diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/DefaultFlowFunctionTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/DefaultFlowFunctionTest.cpp index 07870993a9..1b9b1d8900 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/DefaultFlowFunctionTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/DefaultFlowFunctionTest.cpp @@ -12,14 +12,18 @@ #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include "SrcCodeLocationEntry.h" #include "TestConfig.h" #include "gtest/gtest.h" #include using namespace psr; +using namespace psr::unittest; namespace { @@ -67,121 +71,33 @@ class IDEReachableAllocationSitesImpl FilteredLLVMAliasSet PT{&AS}; }; +template std::set -getNormalFlowValueSet(const llvm::Instruction *Instr, IDEAliasImpl &AliasImpl, +getNormalFlowValueSet(const llvm::Instruction *Instr, ImplT &Impl, const llvm::Value *Arg) { - const auto AliasNormalFlowFunc = - AliasImpl.getNormalFlowFunction(Instr, nullptr); - const auto AliasLLVMValueSet = AliasNormalFlowFunc->computeTargets(Arg); - return AliasLLVMValueSet; + return Impl.getNormalFlowFunction(Instr, nullptr)->computeTargets(Arg); } +template std::set -getNormalFlowValueSet(const llvm::Instruction *Instr, - IDENoAliasImpl &NoAliasImpl, const llvm::Value *Arg) { - const auto NoAliasNormalFlowFunc = - NoAliasImpl.getNormalFlowFunction(Instr, nullptr); - const auto NoAliasLLVMValueSet = NoAliasNormalFlowFunc->computeTargets(Arg); - return NoAliasLLVMValueSet; -} - -std::set -getNormalFlowValueSet(const llvm::Instruction *Instr, - IDEReachableAllocationSitesImpl &RASImpl, - const llvm::Value *Arg) { - const auto RASNormalFlowFunc = RASImpl.getNormalFlowFunction(Instr, nullptr); - const auto RASLLVMValueSet = RASNormalFlowFunc->computeTargets(Arg); - return RASLLVMValueSet; -} - -std::set -getCallFlowValueSet(const llvm::Instruction *Instr, IDEAliasImpl &AliasImpl, - const llvm::Value *Arg, const llvm::Function *CalleeFunc) { - const auto AliasCallFlowFunc = - AliasImpl.getCallFlowFunction(Instr, CalleeFunc); - std::set AliasLLVMValueSet = - AliasCallFlowFunc->computeTargets(Arg); - return AliasLLVMValueSet; -} - -std::set -getCallFlowValueSet(const llvm::Instruction *Instr, IDENoAliasImpl &NoAliasImpl, +getCallFlowValueSet(const llvm::Instruction *Instr, ImplT &Impl, const llvm::Value *Arg, const llvm::Function *CalleeFunc) { - const auto NoAliasCallFlowFunc = - NoAliasImpl.getCallFlowFunction(Instr, CalleeFunc); - std::set NoAliasLLVMValueSet = - NoAliasCallFlowFunc->computeTargets(Arg); - return NoAliasLLVMValueSet; + return Impl.getCallFlowFunction(Instr, CalleeFunc)->computeTargets(Arg); } +template std::set -getCallFlowValueSet(const llvm::Instruction *Instr, - IDEReachableAllocationSitesImpl &RASImpl, - const llvm::Value *Arg, const llvm::Function *CalleeFunc) { - const auto RASCallFlowFunc = RASImpl.getCallFlowFunction(Instr, CalleeFunc); - std::set RASLLVMValueSet = - RASCallFlowFunc->computeTargets(Arg); - return RASLLVMValueSet; -} - -std::set -getRetFlowValueSet(const llvm::Instruction *Instr, IDEAliasImpl &AliasImpl, +getRetFlowValueSet(const llvm::Instruction *Instr, ImplT &Impl, const llvm::Value *Arg, const llvm::Instruction *ExitInst) { - const auto AliasRetFlowFunc = - AliasImpl.getRetFlowFunction(Instr, nullptr, ExitInst, nullptr); - std::set AliasLLVMValueSet = - AliasRetFlowFunc->computeTargets(Arg); - return AliasLLVMValueSet; + return Impl.getRetFlowFunction(Instr, nullptr, ExitInst, nullptr) + ->computeTargets(Arg); } +template std::set -getRetFlowValueSet(const llvm::Instruction *Instr, IDENoAliasImpl &NoAliasImpl, - const llvm::Value *Arg, const llvm::Instruction *ExitInst) { - const auto NoAliasRetFlowFunc = - NoAliasImpl.getRetFlowFunction(Instr, nullptr, ExitInst, nullptr); - std::set NoAliasLLVMValueSet = - NoAliasRetFlowFunc->computeTargets(Arg); - return NoAliasLLVMValueSet; -} - -std::set -getRetFlowValueSet(const llvm::Instruction *Instr, - IDEReachableAllocationSitesImpl &RASImpl, - const llvm::Value *Arg, const llvm::Instruction *ExitInst) { - const auto RASRetFlowFunc = - RASImpl.getRetFlowFunction(Instr, nullptr, ExitInst, nullptr); - std::set RASLLVMValueSet = - RASRetFlowFunc->computeTargets(Arg); - return RASLLVMValueSet; -} - -std::set -getCallToRetFlowValueSet(const llvm::Instruction *Instr, - IDEAliasImpl &AliasImpl, const llvm::Value *Arg) { - const auto AliasCallToRetFlowFunc = - AliasImpl.getCallToRetFlowFunction(Instr, nullptr, {}); - const auto AliasLLVMValueSet = AliasCallToRetFlowFunc->computeTargets(Arg); - return AliasLLVMValueSet; -} - -std::set -getCallToRetFlowValueSet(const llvm::Instruction *Instr, - IDENoAliasImpl &NoAliasImpl, const llvm::Value *Arg) { - const auto NoAliasCallToRetFlowFunc = - NoAliasImpl.getCallToRetFlowFunction(Instr, nullptr, {}); - const auto NoAliasLLVMValueSet = - NoAliasCallToRetFlowFunc->computeTargets(Arg); - return NoAliasLLVMValueSet; -} - -std::set -getCallToRetFlowValueSet(const llvm::Instruction *Instr, - IDEReachableAllocationSitesImpl &RASImpl, +getCallToRetFlowValueSet(const llvm::Instruction *Instr, ImplT &Impl, const llvm::Value *Arg) { - const auto RASCallToRetFlowFunc = - RASImpl.getCallToRetFlowFunction(Instr, nullptr, {}); - const auto RASLLVMValueSet = RASCallToRetFlowFunc->computeTargets(Arg); - return RASLLVMValueSet; + return Impl.getCallToRetFlowFunction(Instr, nullptr, {})->computeTargets(Arg); } std::string stringifyValueSet(const std::set &Vals) { @@ -198,348 +114,356 @@ std::string stringifyValueSet(const std::set &Vals) { return Ret; } +struct Impls { + IDEAliasImpl Alias; + IDENoAliasImpl NoAlias; + IDEReachableAllocationSitesImpl RAS; + + Impls(LLVMProjectIRDB *IRDB) : Alias(IRDB), NoAlias(IRDB), RAS(IRDB) {} +}; + +void expectNormalFlow(const std::set &Expected, + const llvm::Instruction *Instr, const llvm::Value *Arg, + Impls &I) { + EXPECT_EQ(Expected, getNormalFlowValueSet(Instr, I.Alias, Arg)); + EXPECT_EQ(Expected, getNormalFlowValueSet(Instr, I.NoAlias, Arg)); + EXPECT_EQ(Expected, getNormalFlowValueSet(Instr, I.RAS, Arg)); +} + +void expectCallFlow(const std::set &Expected, + const llvm::Instruction *Instr, const llvm::Value *Arg, + const llvm::Function *Callee, Impls &I) { + EXPECT_EQ(Expected, getCallFlowValueSet(Instr, I.Alias, Arg, Callee)); + EXPECT_EQ(Expected, getCallFlowValueSet(Instr, I.NoAlias, Arg, Callee)); + EXPECT_EQ(Expected, getCallFlowValueSet(Instr, I.RAS, Arg, Callee)); +} + +void expectRetFlow(const std::set &Expected, + const llvm::Instruction *CallSite, const llvm::Value *Arg, + const llvm::Instruction *ExitInst, Impls &I) { + EXPECT_EQ(Expected, getRetFlowValueSet(CallSite, I.Alias, Arg, ExitInst)); + EXPECT_EQ(Expected, getRetFlowValueSet(CallSite, I.NoAlias, Arg, ExitInst)); + EXPECT_EQ(Expected, getRetFlowValueSet(CallSite, I.RAS, Arg, ExitInst)); +} + +void expectCallToRetFlow(const std::set &Expected, + const llvm::Instruction *Instr, const llvm::Value *Arg, + Impls &I) { + EXPECT_EQ(Expected, getCallToRetFlowValueSet(Instr, I.Alias, Arg)); + EXPECT_EQ(Expected, getCallToRetFlowValueSet(Instr, I.NoAlias, Arg)); + EXPECT_EQ(Expected, getCallToRetFlowValueSet(Instr, I.RAS, Arg)); +} + +using GTMap = std::vector; + TEST(PureFlow, NormalFlow01) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + "pure_flow/normal_flow/normal_flow_01_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); - - const auto *MainFunc = IRDB.getFunction("main"); - // %0 - const auto *PercentZero = MainFunc->getArg(0); - // %1 - const auto *PercentOne = MainFunc->getArg(1); - // %.addr = alloca i32, align 4, !psr.id !216; | ID: 1 - const auto *Instr1 = IRDB.getInstruction(1); - // %.addr1 = alloca ptr, align 8, !psr.id !217; | ID: 2 - const auto *Instr2 = IRDB.getInstruction(2); - //%One = alloca i32, align 4, !psr.id !218; | ID: 3 - const auto *Instr3 = IRDB.getInstruction(3); - // %Two = alloca i32, align 4, !psr.id !219; | ID: 4 - const auto *Instr4 = IRDB.getInstruction(4); - // %OnePtr = alloca ptr, align 8, !psr.id !220; | ID: 5 - const auto *Instr5 = IRDB.getInstruction(5); - // %TwoAddr = alloca ptr, align 8, !psr.id !221; | ID: 6 - const auto *Instr6 = IRDB.getInstruction(6); + Impls I(&IRDB); // store i32 %0, ptr %.addr, align 4 - const auto *Instr8 = IRDB.getInstruction(8); - ASSERT_TRUE(Instr8); - EXPECT_EQ((std::set{PercentZero, Instr1}), - getNormalFlowValueSet(Instr8, AliasImpl, PercentZero)); - EXPECT_EQ((std::set{PercentZero, Instr1}), - getNormalFlowValueSet(Instr8, NoAliasImpl, PercentZero)); - EXPECT_EQ((std::set{PercentZero, Instr1}), - getNormalFlowValueSet(Instr8, RASImpl, PercentZero)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr8, AliasImpl, Instr1)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr8, NoAliasImpl, Instr1)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr8, RASImpl, Instr1)); + const auto *ValueStorePercent0 = + testingLocInIR(LineColFunOp{.Line = 3, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercent0 = + llvm::dyn_cast(ValueStorePercent0); + ASSERT_TRUE(StorePercent0); // store ptr %1, ptr %.addr1, align 8 - const auto *Instr10 = IRDB.getInstruction(10); - ASSERT_TRUE(Instr10); - EXPECT_EQ((std::set{PercentOne, Instr2}), - getNormalFlowValueSet(Instr10, AliasImpl, PercentOne)); - EXPECT_EQ((std::set{PercentOne, Instr2}), - getNormalFlowValueSet(Instr10, NoAliasImpl, PercentOne)); - EXPECT_EQ((std::set{PercentOne, Instr2}), - getNormalFlowValueSet(Instr10, RASImpl, PercentOne)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr10, AliasImpl, Instr2)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr10, NoAliasImpl, Instr2)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr10, RASImpl, Instr2)); + const auto *ValueStorePercent1 = + testingLocInIR(LineColFunOp{.Line = 4, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercent1 = + llvm::dyn_cast(ValueStorePercent1); + ASSERT_TRUE(StorePercent1); // store ptr %One, ptr %OnePtr, align 8, !dbg !225 - const auto *Instr17 = IRDB.getInstruction(17); - ASSERT_TRUE(Instr17); - EXPECT_EQ((std::set{Instr3, Instr5}), - getNormalFlowValueSet(Instr17, AliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr5}), - getNormalFlowValueSet(Instr17, NoAliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr5}), - getNormalFlowValueSet(Instr17, RASImpl, Instr3)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr17, AliasImpl, Instr5)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr17, NoAliasImpl, Instr5)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr17, RASImpl, Instr5)); + const auto *ValueStorePercentOne = + testingLocInIR(LineColFunOp{.Line = 4, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercentOne = + llvm::dyn_cast(ValueStorePercentOne); + ASSERT_TRUE(StorePercentOne); // store ptr %Two, ptr %TwoAddr, align 8, !dbg !228 - const auto *Instr19 = IRDB.getInstruction(19); - ASSERT_TRUE(Instr19); - EXPECT_EQ((std::set{Instr4, Instr6}), - getNormalFlowValueSet(Instr19, AliasImpl, Instr4)); - EXPECT_EQ((std::set{Instr4, Instr6}), - getNormalFlowValueSet(Instr19, NoAliasImpl, Instr4)); - EXPECT_EQ((std::set{Instr4, Instr6}), - getNormalFlowValueSet(Instr19, RASImpl, Instr4)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr19, AliasImpl, Instr6)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr19, NoAliasImpl, Instr6)); - EXPECT_EQ(std::set{}, - getNormalFlowValueSet(Instr19, RASImpl, Instr6)); - - // Other arg - EXPECT_EQ(std::set{Instr19}, - getNormalFlowValueSet(Instr19, AliasImpl, Instr19)); - EXPECT_EQ(std::set{Instr19}, - getNormalFlowValueSet(Instr19, NoAliasImpl, Instr19)); - EXPECT_EQ(std::set{Instr19}, - getNormalFlowValueSet(Instr19, RASImpl, Instr19)); + const auto *ValueStorePercentTwo = + testingLocInIR(LineColFunOp{.Line = 5, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercentTwo = + llvm::dyn_cast(ValueStorePercentTwo); + ASSERT_TRUE(StorePercentTwo); + + expectNormalFlow({StorePercent0}, StorePercent0, StorePercent0, I); + expectNormalFlow({StorePercent1}, StorePercent1, StorePercent1, I); + expectNormalFlow({StorePercentOne}, StorePercentOne, StorePercentOne, I); + expectNormalFlow({StorePercentTwo}, StorePercentTwo, StorePercentTwo, I); } TEST(PureFlow, NormalFlow02) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + "pure_flow/normal_flow/normal_flow_02_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); + Impls I(&IRDB); const auto *MainFunc = IRDB.getFunction("main"); ASSERT_TRUE(MainFunc); - // %0 - const auto *PercentZero = MainFunc->getArg(0); - ASSERT_TRUE(PercentZero); - // %1 - const auto *PercentOne = MainFunc->getArg(1); - ASSERT_TRUE(PercentOne); - // %.addr = alloca i32, align 4, !psr.id !221; | ID: 2 - const auto *Instr2 = IRDB.getInstruction(2); - ASSERT_TRUE(Instr2); - // %.addr1 = alloca ptr, align 8, !psr.id !222; | ID: 3 - const auto *Instr3 = IRDB.getInstruction(3); - ASSERT_TRUE(Instr3); // store i32 %0, ptr %.addr, align 4, !psr.id !227; | ID: 8 - const auto *Instr8 = IRDB.getInstruction(8); - ASSERT_TRUE(Instr8); - EXPECT_EQ((std::set{PercentZero, Instr2}), - getNormalFlowValueSet(Instr8, AliasImpl, PercentZero)); - EXPECT_EQ((std::set{PercentZero, Instr2}), - getNormalFlowValueSet(Instr8, NoAliasImpl, PercentZero)); - EXPECT_EQ((std::set{PercentZero, Instr2}), - getNormalFlowValueSet(Instr8, RASImpl, PercentZero)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr8, AliasImpl, Instr2)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr8, NoAliasImpl, Instr2)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr8, RASImpl, Instr2)); + const auto *ValueStorePercent0 = + testingLocInIR(LineColFunOp{.Line = 5, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercent0 = + llvm::dyn_cast(ValueStorePercent0); + ASSERT_TRUE(StorePercent0); // store ptr %1, ptr %.addr1, align 8, !psr.id !231; | ID: 10 - const auto *Instr10 = IRDB.getInstruction(10); - ASSERT_TRUE(Instr10); - EXPECT_EQ((std::set{PercentOne, Instr3}), - getNormalFlowValueSet(Instr10, AliasImpl, PercentOne)); - EXPECT_EQ((std::set{PercentOne, Instr3}), - getNormalFlowValueSet(Instr10, NoAliasImpl, PercentOne)); - EXPECT_EQ((std::set{PercentOne, Instr3}), - getNormalFlowValueSet(Instr10, RASImpl, PercentOne)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr10, AliasImpl, Instr3)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr10, NoAliasImpl, Instr3)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr10, RASImpl, Instr3)); - - // Other arg - EXPECT_EQ(std::set{Instr10}, - getNormalFlowValueSet(Instr10, AliasImpl, Instr10)); - EXPECT_EQ(std::set{Instr10}, - getNormalFlowValueSet(Instr10, NoAliasImpl, Instr10)); - EXPECT_EQ(std::set{Instr10}, - getNormalFlowValueSet(Instr10, RASImpl, Instr10)); + const auto *ValueStorePercent1 = + testingLocInIR(LineColFunOp{.Line = 5, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercent1 = + llvm::dyn_cast(ValueStorePercent1); + ASSERT_TRUE(StorePercent1); + + expectNormalFlow({StorePercent0}, StorePercent0, StorePercent0, I); + expectNormalFlow({StorePercent0}, StorePercent0, StorePercent0, + I); // duplicate - issue #6 + expectNormalFlow({StorePercent1}, StorePercent1, StorePercent1, I); } TEST(PureFlow, NormalFlow03) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + "pure_flow/normal_flow/normal_flow_03_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); + Impls I(&IRDB); // %One = alloca i32, align 4, !psr.id !222; | ID: 3 - const auto *Instr3 = IRDB.getInstruction(3); - ASSERT_TRUE(Instr3); + const auto *PercentOne = + testingLocInIR(LineColFunOp{.Line = 8, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Alloca}, + IRDB); + // %ForGEP = alloca %struct.StructOne, align 4, !psr.id !227; | ID: 8 - const auto *Instr8 = IRDB.getInstruction(8); - ASSERT_TRUE(Instr8); + const auto *PercentForGEP = + testingLocInIR(LineColFunOp{.Line = 13, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Alloca}, + IRDB); + // %2 = load i32, ptr %One, align 4, !dbg !245, !psr.id !246; | ID: 18 - const auto *Instr18 = IRDB.getInstruction(18); - ASSERT_TRUE(Instr18); - - EXPECT_EQ((std::set{Instr3, Instr18}), - getNormalFlowValueSet(Instr18, AliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr18}), - getNormalFlowValueSet(Instr18, NoAliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr18}), - getNormalFlowValueSet(Instr18, RASImpl, Instr3)); + const auto *ValueLoadPercent2 = + testingLocInIR(LineColFunOp{.Line = 9, + .Col = 18, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); + const auto *LoadPercent2 = + llvm::dyn_cast(ValueLoadPercent2); + ASSERT_TRUE(LoadPercent2); + + expectNormalFlow({PercentOne, LoadPercent2}, LoadPercent2, PercentOne, I); + // %3 = load i32, ptr %One, align 4, !dbg !251, !psr.id !252; | ID: 21 - const auto *Instr21 = IRDB.getInstruction(21); - ASSERT_TRUE(Instr21); - EXPECT_EQ((std::set{Instr3, Instr21}), - getNormalFlowValueSet(Instr21, AliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr21}), - getNormalFlowValueSet(Instr21, NoAliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr21}), - getNormalFlowValueSet(Instr21, RASImpl, Instr3)); + const auto *ValueLoadPercent3 = + testingLocInIR(LineColFunOp{.Line = 9, + .Col = 18, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); + const auto *LoadPercent3 = + llvm::dyn_cast(ValueLoadPercent3); + ASSERT_TRUE(LoadPercent3); + expectNormalFlow({PercentOne, LoadPercent3}, LoadPercent3, PercentOne, I); // %tobool = icmp ne i32 %3, 0, !dbg !251, !psr.id !253; | ID: 22 - const auto *Instr22 = IRDB.getInstruction(22); - ASSERT_TRUE(Instr22); + const auto *ValuePercenttobool = + testingLocInIR(LineColFunOp{.Line = 9, + .Col = 18, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); + const auto *Percenttobool = + llvm::dyn_cast(ValuePercenttobool); + ASSERT_TRUE(Percenttobool); + // %lnot = xor i1 %tobool, true, !dbg !254, !psr.id !255; | ID: 23 - const auto *Instr23 = IRDB.getInstruction(23); - ASSERT_TRUE(Instr23); - EXPECT_EQ((std::set{Instr22, Instr23}), - getNormalFlowValueSet(Instr23, AliasImpl, Instr22)); - EXPECT_EQ((std::set{Instr22, Instr23}), - getNormalFlowValueSet(Instr23, NoAliasImpl, Instr22)); - EXPECT_EQ((std::set{Instr22, Instr23}), - getNormalFlowValueSet(Instr23, RASImpl, Instr22)); + const auto *Percentlnot = + llvm::dyn_cast(ValuePercenttobool); + ASSERT_TRUE(Percentlnot); + + expectNormalFlow({Percenttobool, Percentlnot}, Percentlnot, Percenttobool, I); // %4 = load i32, ptr %One, align 4, !dbg !261, !psr.id !262; | ID: 27 - const auto *Instr27 = IRDB.getInstruction(27); - ASSERT_TRUE(Instr27); - EXPECT_EQ((std::set{Instr3, Instr27}), - getNormalFlowValueSet(Instr27, AliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr27}), - getNormalFlowValueSet(Instr27, NoAliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr27}), - getNormalFlowValueSet(Instr27, RASImpl, Instr3)); + const auto *ValueLoadPercent4 = + testingLocInIR(LineColFunOp{.Line = 9, + .Col = 18, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); + const auto *LoadPercent4 = + llvm::dyn_cast(ValueLoadPercent4); + ASSERT_TRUE(LoadPercent4); + + expectNormalFlow({PercentOne, LoadPercent4}, LoadPercent4, PercentOne, I); // %5 = load i32, ptr %One, align 4, !dbg !263, !psr.id !264; | ID: 28 - const auto *Instr28 = IRDB.getInstruction(28); - ASSERT_TRUE(Instr28); - EXPECT_EQ((std::set{Instr3, Instr28}), - getNormalFlowValueSet(Instr28, AliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr28}), - getNormalFlowValueSet(Instr28, NoAliasImpl, Instr3)); - EXPECT_EQ((std::set{Instr3, Instr28}), - getNormalFlowValueSet(Instr28, RASImpl, Instr3)); + const auto *ValueLoadPercent5 = + testingLocInIR(LineColFunOp{.Line = 9, + .Col = 18, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); + const auto *LoadPercent5 = + llvm::dyn_cast(ValueLoadPercent5); + ASSERT_TRUE(LoadPercent5); + + expectNormalFlow({PercentOne, LoadPercent5}, LoadPercent5, PercentOne, I); // %add = add nsw i32 %4, %5, !dbg !265, !psr.id !266; | ID: 29 - const auto *Instr29 = IRDB.getInstruction(29); - ASSERT_TRUE(Instr29); - EXPECT_EQ((std::set{Instr27, Instr29}), - getNormalFlowValueSet(Instr29, AliasImpl, Instr27)); - EXPECT_EQ((std::set{Instr27, Instr29}), - getNormalFlowValueSet(Instr29, NoAliasImpl, Instr27)); - EXPECT_EQ((std::set{Instr27, Instr29}), - getNormalFlowValueSet(Instr29, RASImpl, Instr27)); - EXPECT_EQ((std::set{Instr28, Instr29}), - getNormalFlowValueSet(Instr29, AliasImpl, Instr28)); - EXPECT_EQ((std::set{Instr28, Instr29}), - getNormalFlowValueSet(Instr29, NoAliasImpl, Instr28)); - EXPECT_EQ((std::set{Instr28, Instr29}), - getNormalFlowValueSet(Instr29, RASImpl, Instr28)); + const auto *ValueAdd = + testingLocInIR(LineColFunOp{.Line = 9, + .Col = 18, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); + const auto *Add = llvm::dyn_cast(ValueAdd); + ASSERT_TRUE(Add); + + expectNormalFlow({LoadPercent4, Add}, Add, LoadPercent4, I); + expectNormalFlow({LoadPercent5, Add}, Add, LoadPercent5, I); // %One2 = getelementptr inbounds %struct.StructOne, ptr %ForGEP, i32 0, i32 // 0, !dbg !282, !psr.id !283; | ID: 37 - const auto *Instr37 = IRDB.getInstruction(37); - ASSERT_TRUE(Instr37); - EXPECT_EQ((std::set{Instr8, Instr37}), - getNormalFlowValueSet(Instr37, AliasImpl, Instr8)); - EXPECT_EQ((std::set{Instr8, Instr37}), - getNormalFlowValueSet(Instr37, NoAliasImpl, Instr8)); - EXPECT_EQ((std::set{Instr8, Instr37}), - getNormalFlowValueSet(Instr37, RASImpl, Instr8)); + const auto *ValuePercentOne2 = + testingLocInIR(LineColFunOp{.Line = 14, + .Col = 20, + .InFunction = "main", + .OpCode = llvm::Instruction::GetElementPtr}, + IRDB); + const auto *PercentOne2 = llvm::dyn_cast(ValuePercentOne2); + ASSERT_TRUE(PercentOne2); + + expectNormalFlow({PercentForGEP, PercentOne2}, PercentOne2, PercentForGEP, I); // %6 = load i32, ptr %One2, align 4, !dbg !282, !psr.id !284; | ID: 38 - const auto *Instr38 = IRDB.getInstruction(38); - ASSERT_TRUE(Instr38); - EXPECT_EQ((std::set{Instr37, Instr38}), - getNormalFlowValueSet(Instr38, AliasImpl, Instr37)); - EXPECT_EQ((std::set{Instr37, Instr38}), - getNormalFlowValueSet(Instr38, NoAliasImpl, Instr37)); - EXPECT_EQ((std::set{Instr37, Instr38}), - getNormalFlowValueSet(Instr38, RASImpl, Instr37)); + const auto *ValuePercent6 = + testingLocInIR(LineColFunOp{.Line = 14, + .Col = 20, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); + const auto *Percent6 = llvm::dyn_cast(ValuePercent6); + ASSERT_TRUE(Percent6); + + expectNormalFlow({PercentOne2, Percent6}, Percent6, PercentOne2, I); } TEST(PureFlow, NormalFlow04) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + "pure_flow/normal_flow/normal_flow_04_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); + Impls I(&IRDB); // %Deref1 = alloca i32, align 4, !psr.id !222; | ID: 7 - const auto *Instr7 = IRDB.getInstruction(7); - ASSERT_TRUE(Instr7); + const auto *PercentDeref1 = + testingLocInIR(LineColFunOp{.Line = 10, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Alloca}, + IRDB); // %Deref2 = alloca i32, align 4, !psr.id !223; | ID: 8 - const auto *Instr8 = IRDB.getInstruction(8); - ASSERT_TRUE(Instr8); + const auto *PercentDeref2 = + testingLocInIR(LineColFunOp{.Line = 11, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Alloca}, + IRDB); // %Deref3 = alloca i32, align 4, !psr.id !224; | ID: 9 - const auto *Instr9 = IRDB.getInstruction(9); - ASSERT_TRUE(Instr9); + const auto *PercentDeref3 = + testingLocInIR(LineColFunOp{.Line = 12, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Alloca}, + IRDB); // %3 = load i32, ptr %2, align 4, !dbg !258, !psr.id !259; | ID: 25 - const auto *Instr25 = IRDB.getInstruction(25); - ASSERT_TRUE(Instr25); + const auto *Percent3 = + testingLocInIR(LineColFunOp{.Line = 10, + .Col = 16, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); // %6 = load i32, ptr %5, align 4, !dbg !268, !psr.id !269; | ID: 30 - const auto *Instr30 = IRDB.getInstruction(30); - ASSERT_TRUE(Instr30); + const auto *Percent6 = + testingLocInIR(LineColFunOp{.Line = 11, + .Col = 16, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); // %10 = load i32, ptr %9, align 4, !dbg !280, !psr.id !281; | ID: 36 - const auto *Instr36 = IRDB.getInstruction(36); - ASSERT_TRUE(Instr36); - + const auto *Percent10 = + testingLocInIR(LineColFunOp{.Line = 12, + .Col = 16, + .InFunction = "main", + .OpCode = llvm::Instruction::Load}, + IRDB); // store i32 %3, ptr %Deref1, align 4, !dbg !254, !psr.id !260; | ID: 26 - const auto *Instr26 = IRDB.getInstruction(26); - ASSERT_TRUE(Instr26); - EXPECT_EQ((std::set{Instr25, Instr7}), - getNormalFlowValueSet(Instr26, AliasImpl, Instr25)); - EXPECT_EQ((std::set{Instr25, Instr7}), - getNormalFlowValueSet(Instr26, NoAliasImpl, Instr25)); - EXPECT_EQ((std::set{Instr25, Instr7}), - getNormalFlowValueSet(Instr26, RASImpl, Instr25)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr26, AliasImpl, Instr7)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr26, NoAliasImpl, Instr7)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr26, RASImpl, Instr7)); + const auto *StorePercent3Value = + testingLocInIR(LineColFunOp{.Line = 10, + .Col = 7, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercent3 = + llvm::dyn_cast(StorePercent3Value); + ASSERT_TRUE(StorePercent3); + + expectNormalFlow({Percent3, PercentDeref1}, StorePercent3, Percent3, I); + expectNormalFlow({}, StorePercent3, PercentDeref1, I); // store i32 %6, ptr %Deref2, align 4, !dbg !262, !psr.id !270; | ID: 31 - const auto *Instr31 = IRDB.getInstruction(31); - ASSERT_TRUE(Instr31); - EXPECT_EQ((std::set{Instr8, Instr30}), - getNormalFlowValueSet(Instr31, AliasImpl, Instr30)); - EXPECT_EQ((std::set{Instr8, Instr30}), - getNormalFlowValueSet(Instr31, NoAliasImpl, Instr30)); - EXPECT_EQ((std::set{Instr8, Instr30}), - getNormalFlowValueSet(Instr31, RASImpl, Instr30)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr31, AliasImpl, Instr8)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr31, NoAliasImpl, Instr8)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr31, RASImpl, Instr8)); + const auto *StorePercent6Value = + testingLocInIR(LineColFunOp{.Line = 11, + .Col = 7, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercent6 = + llvm::dyn_cast(StorePercent6Value); + ASSERT_TRUE(StorePercent6); + + expectNormalFlow({PercentDeref2, Percent6}, StorePercent6, Percent6, I); + expectNormalFlow({}, StorePercent6, PercentDeref2, I); // store i32 %10, ptr %Deref3, align 4, !dbg !272, !psr.id !282; | ID: 37 - const auto *Instr37 = IRDB.getInstruction(37); - ASSERT_TRUE(Instr37); - EXPECT_EQ((std::set{Instr9, Instr36}), - getNormalFlowValueSet(Instr37, AliasImpl, Instr36)); - EXPECT_EQ((std::set{Instr9, Instr36}), - getNormalFlowValueSet(Instr37, NoAliasImpl, Instr36)); - EXPECT_EQ((std::set{Instr9, Instr36}), - getNormalFlowValueSet(Instr37, RASImpl, Instr36)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr37, AliasImpl, Instr9)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr37, NoAliasImpl, Instr9)); - EXPECT_EQ((std::set{}), - getNormalFlowValueSet(Instr37, RASImpl, Instr9)); + const auto *StorePercent10Value = + testingLocInIR(LineColFunOp{.Line = 12, + .Col = 7, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercent10 = + llvm::dyn_cast(StorePercent10Value); + ASSERT_TRUE(StorePercent10); + + expectNormalFlow({PercentDeref3, Percent10}, StorePercent10, Percent10, I); + expectNormalFlow({}, StorePercent10, PercentDeref3, I); } /* @@ -549,144 +473,83 @@ TEST(PureFlow, NormalFlow04) { TEST(PureFlow, CallFlow01) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + "pure_flow/call_flow/call_flow_01_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); + Impls I(&IRDB); // call void @_Z4callii(i32 noundef %2, i32 noundef %3), !dbg !261, !psr.id // !262; | ID: 26 - const auto *Instr26 = IRDB.getInstruction(26); - ASSERT_TRUE(Instr26); - const auto *FuncForInstr26 = IRDB.getFunction("_Z4callii"); - ASSERT_TRUE(FuncForInstr26); - ASSERT_EQ(FuncForInstr26->arg_size(), 2); - const auto *Param0 = FuncForInstr26->getArg(0); - const auto *Param1 = FuncForInstr26->getArg(1); - - if (const auto *CallSite = llvm::dyn_cast(Instr26)) { - EXPECT_EQ(std::set{Param0}, - getCallFlowValueSet(Instr26, AliasImpl, - CallSite->getArgOperand(0), FuncForInstr26)); - EXPECT_EQ(std::set{Param1}, - getCallFlowValueSet(Instr26, AliasImpl, - CallSite->getArgOperand(1), FuncForInstr26)); - EXPECT_EQ(std::set{Param0}, - getCallFlowValueSet(Instr26, NoAliasImpl, - CallSite->getArgOperand(0), FuncForInstr26)); - EXPECT_EQ(std::set{Param1}, - getCallFlowValueSet(Instr26, NoAliasImpl, - CallSite->getArgOperand(1), FuncForInstr26)); - EXPECT_EQ(std::set{Param0}, - getCallFlowValueSet(Instr26, RASImpl, CallSite->getArgOperand(0), - FuncForInstr26)); - EXPECT_EQ(std::set{Param1}, - getCallFlowValueSet(Instr26, RASImpl, CallSite->getArgOperand(1), - FuncForInstr26)); - } else { - FAIL(); - } + const auto *CallValue = + testingLocInIR(LineColFunOp{.Line = 10, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *Call = llvm::dyn_cast(CallValue); + ASSERT_TRUE(Call); + + auto FuncTSL = FuncByName{.FuncName = "_Z4callii"}; + const auto *CallFuncValue = testingLocInIR(FuncTSL, IRDB); + const auto *CallFunc = llvm::dyn_cast(CallFuncValue); + ASSERT_TRUE(CallFunc); + const auto *Param0 = CallFunc->getArg(0); + ASSERT_TRUE(Param0); + const auto *Param1 = CallFunc->getArg(1); + ASSERT_TRUE(Param1); + + const auto *CallSite = llvm::dyn_cast(Call); + ASSERT_TRUE(CallSite); + expectCallFlow({Param0}, Call, CallSite->getArgOperand(0), CallFunc, I); + expectCallFlow({Param1}, Call, CallSite->getArgOperand(1), CallFunc, I); } TEST(PureFlow, CallFlow02) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + "pure_flow/call_flow/call_flow_02_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); - - // %One = alloca i32, align 4, !psr.id !251; | ID: 17 - const auto *Instr17 = IRDB.getInstruction(17); - ASSERT_TRUE(Instr17); - // %Two = alloca i32, align 4, !psr.id !252; | ID: 18 - const auto *Instr18 = IRDB.getInstruction(18); - ASSERT_TRUE(Instr18); - // %Three = alloca i32, align 4, !psr.id !253; | ID: 19 - const auto *Instr19 = IRDB.getInstruction(19); - ASSERT_TRUE(Instr19); - // %PtrToOne = alloca ptr, align 8, !psr.id !254; | ID: 20 - const auto *Instr20 = IRDB.getInstruction(20); - ASSERT_TRUE(Instr20); - // %PtrToTwo = alloca ptr, align 8, !psr.id !255; | ID: 21 - const auto *Instr21 = IRDB.getInstruction(21); - ASSERT_TRUE(Instr21); - // %PtrPtrToTwo = alloca ptr, align 8, !psr.id !256; | ID: 22 - const auto *Instr22 = IRDB.getInstruction(22); - ASSERT_TRUE(Instr22); - // %PtrToThree = alloca ptr, align 8, !psr.id !257; | ID: 23 - const auto *Instr23 = IRDB.getInstruction(23); - ASSERT_TRUE(Instr23); - // %PtrPtrToThree = alloca ptr, align 8, !psr.id !258; | ID: 24 - const auto *Instr24 = IRDB.getInstruction(24); - ASSERT_TRUE(Instr24); - // %PtrPtrPtrToThree = alloca ptr, align 8, !psr.id !259; | ID: 25 - const auto *Instr25 = IRDB.getInstruction(25); - ASSERT_TRUE(Instr25); - // call void @_Z4callPi(ptr noundef %2), !dbg !307, !psr.id !308; | ID: 50 - const auto *Instr50 = IRDB.getInstruction(50); - ASSERT_TRUE(Instr50); - // call void @_Z10secondCallPiPS_PS0_(ptr noundef %3, ptr noundef %4, ptr - // noundef %5), !dbg !315, !psr.id !316; | ID: 54 - const auto *Instr54 = IRDB.getInstruction(54); - ASSERT_TRUE(Instr54); + Impls I(&IRDB); + // call void @_Z4callPi(ptr noundef %2), !dbg !307, !psr.id !308; | ID: 50 + const auto *CallValue = + testingLocInIR(LineColFunOp{.Line = 19, + .Col = 3, + .InFunction = "main", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *CallInstr = llvm::dyn_cast(CallValue); + ASSERT_TRUE(CallInstr); // call function - const auto *CallFunc = IRDB.getFunction("_Z4callPi"); + const auto *CallFuncValue = + testingLocInIR(FuncByName{.FuncName = "_Z4callPi"}, IRDB); + const auto *CallFunc = llvm::dyn_cast(CallFuncValue); ASSERT_TRUE(CallFunc); + // call void @_Z10secondCallPiPS_PS0_(ptr noundef %3, ptr noundef %4, ptr + // noundef %5), !dbg !315, !psr.id !316; | ID: 54 + const auto *SecondCallValue = + testingLocInIR(LineColFunOp{.Line = 20, + .Col = 3, + .InFunction = "main", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *SecondCallInstr = + llvm::dyn_cast(SecondCallValue); + ASSERT_TRUE(SecondCallInstr); // second call function - const auto *SecondCallFunc = IRDB.getFunction("_Z10secondCallPiPS_PS0_"); + const auto *SecondCallFuncValue = + testingLocInIR(FuncByName{.FuncName = "_Z10secondCallPiPS_PS0_"}, IRDB); + const auto *SecondCallFunc = + llvm::dyn_cast(SecondCallFuncValue); ASSERT_TRUE(SecondCallFunc); - const auto *CSCallFunc = llvm::cast(Instr50); - const auto *CSSecondCallFunc = llvm::cast(Instr54); - - EXPECT_EQ((std::set{CallFunc->getArg(0)}), - getCallFlowValueSet(Instr50, AliasImpl, - CSCallFunc->getArgOperand(0), CallFunc)); - EXPECT_EQ((std::set{CallFunc->getArg(0)}), - getCallFlowValueSet(Instr50, NoAliasImpl, - CSCallFunc->getArgOperand(0), CallFunc)); - EXPECT_EQ((std::set{CallFunc->getArg(0)}), - getCallFlowValueSet(Instr50, RASImpl, CSCallFunc->getArgOperand(0), - CallFunc)); - - EXPECT_EQ((std::set{SecondCallFunc->getArg(0)}), - getCallFlowValueSet(Instr54, AliasImpl, - CSSecondCallFunc->getArgOperand(0), - SecondCallFunc)); - EXPECT_EQ((std::set{SecondCallFunc->getArg(0)}), - getCallFlowValueSet(Instr54, NoAliasImpl, - CSSecondCallFunc->getArgOperand(0), - SecondCallFunc)); - EXPECT_EQ((std::set{SecondCallFunc->getArg(0)}), - getCallFlowValueSet(Instr54, RASImpl, - CSSecondCallFunc->getArgOperand(0), - SecondCallFunc)); - EXPECT_EQ((std::set{SecondCallFunc->getArg(1)}), - getCallFlowValueSet(Instr54, AliasImpl, - CSSecondCallFunc->getArgOperand(1), - SecondCallFunc)); - EXPECT_EQ((std::set{SecondCallFunc->getArg(1)}), - getCallFlowValueSet(Instr54, NoAliasImpl, - CSSecondCallFunc->getArgOperand(1), - SecondCallFunc)); - EXPECT_EQ((std::set{SecondCallFunc->getArg(1)}), - getCallFlowValueSet(Instr54, RASImpl, - CSSecondCallFunc->getArgOperand(1), - SecondCallFunc)); - EXPECT_EQ((std::set{SecondCallFunc->getArg(2)}), - getCallFlowValueSet(Instr54, AliasImpl, - CSSecondCallFunc->getArgOperand(2), - SecondCallFunc)); - EXPECT_EQ((std::set{SecondCallFunc->getArg(2)}), - getCallFlowValueSet(Instr54, NoAliasImpl, - CSSecondCallFunc->getArgOperand(2), - SecondCallFunc)); - EXPECT_EQ((std::set{SecondCallFunc->getArg(2)}), - getCallFlowValueSet(Instr54, RASImpl, - CSSecondCallFunc->getArgOperand(2), - SecondCallFunc)); + const auto *CSCallFunc = llvm::cast(CallInstr); + const auto *CSSecondCallFunc = llvm::cast(SecondCallInstr); + + expectCallFlow({CallFunc->getArg(0)}, CallInstr, CSCallFunc->getArgOperand(0), + CallFunc, I); + + expectCallFlow({SecondCallFunc->getArg(0)}, SecondCallInstr, + CSSecondCallFunc->getArgOperand(0), SecondCallFunc, I); + expectCallFlow({SecondCallFunc->getArg(1)}, SecondCallInstr, + CSSecondCallFunc->getArgOperand(1), SecondCallFunc, I); + expectCallFlow({SecondCallFunc->getArg(2)}, SecondCallInstr, + CSSecondCallFunc->getArgOperand(2), SecondCallFunc, I); } /* @@ -696,247 +559,327 @@ TEST(PureFlow, CallFlow02) { TEST(PureFlow, RetFlow01) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + "pure_flow/ret_flow/ret_flow_01_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); + Impls I(&IRDB); // %Two = alloca i32, align 4, !psr.id !251; | ID: 20 - const auto *UnusedValue = IRDB.getValueFromId(20); - + const auto *PercentTwo = + testingLocInIR(LineColFunOp{.Line = 13, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Alloca}, + IRDB); // %call = call noundef i32 @_Z6getTwov(), !dbg !231, !psr.id !232; | ID: 9 - const auto *Instr9 = IRDB.getInstruction(9); - ASSERT_TRUE(Instr9); + const auto *PercentCallGetTwoValue = + testingLocInIR(LineColFunOp{.Line = 6, + .Col = 0, + .InFunction = "_Z4callii", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *PercentCallGetTwo = + llvm::dyn_cast(PercentCallGetTwoValue); + ASSERT_TRUE(PercentCallGetTwo); // ret i32 2, !dbg !212, !psr.id !213; | ID: 0 - const auto *Instr0 = IRDB.getInstruction(0); - ASSERT_TRUE(Instr0); - - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr9, AliasImpl, UnusedValue, Instr0)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr9, NoAliasImpl, UnusedValue, Instr0)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr9, RASImpl, UnusedValue, Instr0)); + const auto *RetValGetTwo = + testingLocInIR(LineColFunOp{.Line = 3, + .Col = 0, + .InFunction = "_Z6getTwov", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetValGetTwoInstr = + llvm::dyn_cast(RetValGetTwo); + ASSERT_TRUE(RetValGetTwoInstr); + + expectRetFlow({}, PercentCallGetTwo, PercentTwo, RetValGetTwoInstr, I); // %call = call noundef i32 @_Z4callii(i32 noundef %2, i32 noundef %3), !dbg // !281, !psr.id !282; | ID: 36 - const auto *Instr36 = IRDB.getInstruction(36); - ASSERT_TRUE(Instr36); + const auto *PercentCallValue = + testingLocInIR(LineColFunOp{.Line = 15, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *PercentCall = llvm::dyn_cast(PercentCallValue); + ASSERT_TRUE(PercentCall); // ret i32 %add, !dbg !240, !psr.id !241; | ID: 14 - const auto *Instr14 = IRDB.getInstruction(14); - ASSERT_TRUE(Instr14); + const auto *RetValCallValue = + testingLocInIR(LineColFunOp{.Line = 7, + .Col = 0, + .InFunction = "_Z4callii", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetValCall = llvm::dyn_cast(RetValCallValue); + ASSERT_TRUE(RetValCall); const auto *FuncZ4callii = IRDB.getFunction("_Z4callii"); + ASSERT_TRUE(FuncZ4callii); + ASSERT_TRUE(FuncZ4callii->getArg(0)); + ASSERT_TRUE(FuncZ4callii->getArg(1)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr36, AliasImpl, FuncZ4callii->getArg(0), Instr14)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr36, AliasImpl, FuncZ4callii->getArg(1), Instr14)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr36, NoAliasImpl, FuncZ4callii->getArg(0), - Instr14)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr36, NoAliasImpl, FuncZ4callii->getArg(1), - Instr14)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr36, RASImpl, FuncZ4callii->getArg(0), Instr14)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr36, RASImpl, FuncZ4callii->getArg(1), Instr14)); + expectRetFlow({}, PercentCall, FuncZ4callii->getArg(0), RetValCall, I); + expectRetFlow({}, PercentCall, FuncZ4callii->getArg(1), RetValCall, I); // negative tests - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr9, AliasImpl, FuncZ4callii->getArg(1), Instr0)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr9, NoAliasImpl, FuncZ4callii->getArg(1), Instr0)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr9, RASImpl, FuncZ4callii->getArg(1), Instr0)); + expectRetFlow({}, PercentCallGetTwo, FuncZ4callii->getArg(1), + RetValGetTwoInstr, I); } TEST(PureFlow, RetFlow02) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + "pure_flow/ret_flow/ret_flow_02_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); + Impls I(&IRDB); // %Two = alloca i32, align 4, !psr.id !268; | ID: 29 - const auto *UnusedValue = IRDB.getValueFromId(29); + const auto *PercentTwo = + testingLocInIR(LineColFunOp{.Line = 22, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Alloca}, + IRDB); // %call = call noundef i32 @_Z6getTwov(), !dbg !240, !psr.id !241; | ID: 14 - const auto *Instr14 = IRDB.getInstruction(14); - ASSERT_TRUE(Instr14); + const auto *PercentCallGetTwoValue = + testingLocInIR(LineColFunOp{.Line = 11, + .Col = 0, + .InFunction = "_Z4callii", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *PercentCallGetTwo = + llvm::dyn_cast(PercentCallGetTwoValue); + ASSERT_TRUE(PercentCallGetTwo); // ret i32 2, !dbg !212, !psr.id !213; | ID: 0 - const auto *Instr0 = IRDB.getInstruction(0); - ASSERT_TRUE(Instr0); - - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr14, AliasImpl, UnusedValue, Instr0)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr14, NoAliasImpl, UnusedValue, Instr0)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr14, RASImpl, UnusedValue, Instr0)); + const auto *RetValGetTwoValue = + testingLocInIR(LineColFunOp{.Line = 3, + .Col = 0, + .InFunction = "_Z6getTwov", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetValGetTwoInstr = + llvm::dyn_cast(RetValGetTwoValue); + ASSERT_TRUE(RetValGetTwoInstr); + + expectRetFlow({}, PercentCallGetTwo, PercentTwo, RetValGetTwoInstr, I); // %call1 = call noundef i32 @_Z8newThreev(), !dbg !247, !psr.id !248; | ID: // 18 - const auto *Instr18 = IRDB.getInstruction(18); - ASSERT_TRUE(Instr18); + const auto *PercentCall1 = + testingLocInIR(LineColFunOp{.Line = 14, + .Col = 0, + .InFunction = "_Z4callii", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *PercentCallInstr1 = + llvm::dyn_cast(PercentCall1); + ASSERT_TRUE(PercentCallInstr1); // ret i32 3, !dbg !220, !psr.id !221; | ID: 4 - const auto *Instr4 = IRDB.getInstruction(4); - ASSERT_TRUE(Instr4); - - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr18, AliasImpl, UnusedValue, Instr4)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr18, NoAliasImpl, UnusedValue, Instr4)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr18, RASImpl, UnusedValue, Instr4)); + const auto *RetValNewThree = + testingLocInIR(LineColFunOp{.Line = 7, + .Col = 0, + .InFunction = "_Z8newThreev", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetValNewThreeInstr = + llvm::dyn_cast(RetValNewThree); + ASSERT_TRUE(RetValNewThreeInstr); + + expectRetFlow({}, PercentCallInstr1, PercentTwo, RetValNewThreeInstr, I); // %call = call noundef i32 @_Z4callii(i32 noundef %2, i32 noundef %3), !dbg // !298, !psr.id !299; | ID: 45 - const auto *Instr45 = IRDB.getInstruction(45); - ASSERT_TRUE(Instr45); + const auto *PercentCallValue = + testingLocInIR(LineColFunOp{.Line = 24, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *PercentCall = llvm::dyn_cast(PercentCallValue); + ASSERT_TRUE(PercentCall); // ret i32 %add, !dbg !257, !psr.id !258; | ID: 23 - const auto *Instr23 = IRDB.getInstruction(23); - ASSERT_TRUE(Instr23); + const auto *RetAddValue = + testingLocInIR(LineColFunOp{.Line = 16, + .Col = 0, + .InFunction = "_Z4callii", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetAdd = llvm::dyn_cast(RetAddValue); + ASSERT_TRUE(RetAdd); const auto *FuncZ4callii = IRDB.getFunction("_Z4callii"); + ASSERT_TRUE(FuncZ4callii); + ASSERT_TRUE(FuncZ4callii->getArg(0)); + ASSERT_TRUE(FuncZ4callii->getArg(1)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr45, AliasImpl, FuncZ4callii->getArg(0), Instr23)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr45, AliasImpl, FuncZ4callii->getArg(1), Instr23)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr45, NoAliasImpl, FuncZ4callii->getArg(0), - Instr23)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr45, NoAliasImpl, FuncZ4callii->getArg(1), - Instr23)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr45, RASImpl, FuncZ4callii->getArg(0), Instr23)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr45, RASImpl, FuncZ4callii->getArg(1), Instr23)); + expectRetFlow({}, PercentCall, FuncZ4callii->getArg(0), RetAdd, I); + expectRetFlow({}, PercentCall, FuncZ4callii->getArg(1), RetAdd, I); // negative tests - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr14, AliasImpl, FuncZ4callii->getArg(1), Instr0)); - EXPECT_EQ(std::set{}, - getRetFlowValueSet(Instr14, NoAliasImpl, FuncZ4callii->getArg(1), - Instr0)); - EXPECT_EQ( - std::set{}, - getRetFlowValueSet(Instr14, RASImpl, FuncZ4callii->getArg(1), Instr0)); + expectRetFlow({}, PercentCallGetTwo, FuncZ4callii->getArg(1), + RetValGetTwoInstr, I); } TEST(PureFlow, RetFlow03) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + "pure_flow/ret_flow/ret_flow_03_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); + Impls I(&IRDB); // %ThreeInCall = alloca i32, align 4, !psr.id !254; | ID: 15 - const auto *Instr15 = IRDB.getValueFromId(15); - ASSERT_TRUE(Instr15); + const auto *PercentThreeInCall = + testingLocInIR(LineColFunOp{.Line = 16, + .Col = 0, + .InFunction = "_Z4callRiPKi", + .OpCode = llvm::Instruction::Alloca}, + IRDB); // %ThreePtrInCall = alloca ptr, align 8, !psr.id !255; | ID: 16 - const auto *Instr16 = IRDB.getValueFromId(16); - ASSERT_TRUE(Instr16); + const auto *PercentThreePtrInCall = + testingLocInIR(LineColFunOp{.Line = 17, + .Col = 0, + .InFunction = "_Z4callRiPKi", + .OpCode = llvm::Instruction::Alloca}, + IRDB); // %0 = load ptr, ptr %ThreePtrInCall, align 8, !dbg !280, !psr.id !281; | ID: // 29 - const auto *Instr29 = IRDB.getValueFromId(29); - ASSERT_TRUE(Instr29); + const auto *ValuePercent0 = + testingLocInIR(LineColFunOp{.Line = 18, + .Col = 40, + .InFunction = "_Z4callRiPKi", + .OpCode = llvm::Instruction::Load}, + IRDB); + const auto *Percent0 = llvm::dyn_cast(ValuePercent0); + ASSERT_TRUE(Percent0); // %call = call noundef ptr @_Z8newThreePKi(ptr noundef %0), !dbg !282, // !psr.id !283; | ID: 30 - const auto *Instr30 = IRDB.getValueFromId(30); - ASSERT_TRUE(Instr30); + const auto *ValuePercentCall = + testingLocInIR(LineColFunOp{.Line = 18, + .Col = 31, + .InFunction = "_Z4callRiPKi", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *PercentCall = llvm::dyn_cast(ValuePercentCall); + ASSERT_TRUE(PercentCall); // ret ptr %1, !dbg !234, !psr.id !235; | ID: 9 - const auto *Instruction9 = IRDB.getInstruction(9); - ASSERT_TRUE(Instruction9); - // %call = call noundef ptr @_Z8newThreePKi(ptr noundef %0), !dbg !282, - // !psr.id !283; | ID: 30 - const auto *Instruction30 = IRDB.getInstruction(30); - ASSERT_TRUE(Instruction30); + const auto *RetValNewThreeValue = + testingLocInIR(LineColFunOp{.Line = 7, + .Col = 0, + .InFunction = "_Z8newThreePKi", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetValNewThreeInstr = + llvm::dyn_cast(RetValNewThreeValue); + ASSERT_TRUE(RetValNewThreeInstr); + const auto *FunctionZ8newThreePKi = IRDB.getFunction("_Z8newThreePKi"); + const auto &Got = + getRetFlowValueSet(PercentCall, I.Alias, FunctionZ8newThreePKi->getArg(0), + RetValNewThreeInstr); + EXPECT_EQ(std::set{Percent0}, + getRetFlowValueSet(PercentCall, I.NoAlias, + FunctionZ8newThreePKi->getArg(0), + RetValNewThreeInstr)); + EXPECT_EQ((std::set{Percent0, PercentThreeInCall, + PercentCall}), + getRetFlowValueSet(PercentCall, I.RAS, + FunctionZ8newThreePKi->getArg(0), + RetValNewThreeInstr)); - const auto &Got = getRetFlowValueSet( - Instruction30, AliasImpl, FunctionZ8newThreePKi->getArg(0), Instruction9); - EXPECT_EQ(std::set{Instr29}, - getRetFlowValueSet(Instruction30, NoAliasImpl, - FunctionZ8newThreePKi->getArg(0), Instruction9)); - EXPECT_EQ((std::set{Instr29, Instr15, Instruction30}), - getRetFlowValueSet(Instruction30, RASImpl, - FunctionZ8newThreePKi->getArg(0), Instruction9)); - - EXPECT_EQ((std::set{Instr15, Instr16, Instr29, Instr30}), - Got) + EXPECT_EQ( + (std::set{PercentThreeInCall, PercentThreePtrInCall, + Percent0, PercentCall}), + Got) << stringifyValueSet(Got); - // ret ptr @GlobalFour, !dbg !240, !psr.id !241; | ID: 10 - const auto *Instruction10 = IRDB.getInstruction(10); - ASSERT_TRUE(Instruction10); // %call3 = call noundef ptr @_Z10getFourPtrv(), !dbg !304, !psr.id !305; | // ID: 42 - const auto *Instruction42 = IRDB.getInstruction(42); - ASSERT_TRUE(Instruction42); + const auto *PercentCall3Value = + testingLocInIR(LineColFunOp{.Line = 20, + .Col = 61, + .InFunction = "_Z4callRiPKi", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *PercentCall3 = + llvm::dyn_cast(PercentCall3Value); + ASSERT_TRUE(PercentCall3); // ret ptr @GlobalFour, !dbg !246, !psr.id !247; | ID: 11 - const auto *Instruction11 = IRDB.getInstruction(11); - ASSERT_TRUE(Instruction11); + const auto *RetValGetFourValue = + testingLocInIR(LineColFunOp{.Line = 10, + .Col = 0, + .InFunction = "_Z10getFourPtrv", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetValGetFourInstr = + llvm::dyn_cast(RetValGetFourValue); + ASSERT_TRUE(RetValGetFourInstr); + + const auto *RetValGlobalFourSecondValue = + testingLocInIR(LineColFunOp{.Line = 12, + .Col = 0, + .InFunction = "_Z11getFourAddrv", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetValGlobalFourSecond = + llvm::dyn_cast(RetValGlobalFourSecondValue); + ASSERT_TRUE(RetValGlobalFourSecond); + // %call5 = call noundef nonnull align 4 dereferenceable(4) ptr // @_Z11getFourAddrv(), !dbg !310, !psr.id !311; | ID: 45 - const auto *Instruction45 = IRDB.getInstruction(45); - ASSERT_TRUE(Instruction45); + const auto *PercentCall5Value = + testingLocInIR(LineColFunOp{.Line = 21, + .Col = 10, + .InFunction = "_Z4callRiPKi", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *PercentCall5 = + llvm::dyn_cast(PercentCall5Value); + ASSERT_TRUE(PercentCall5); // ret i32 %add6, !dbg !315, !psr.id !316; | ID: 48 - const auto *Instruction48 = IRDB.getInstruction(48); - ASSERT_TRUE(Instruction48); + const auto *RetValAdd6Value = + testingLocInIR(LineColFunOp{.Line = 20, + .Col = 0, + .InFunction = "_Z4callRiPKi", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetValAdd6 = llvm::dyn_cast(RetValAdd6Value); + ASSERT_TRUE(RetValAdd6); // %call = call noundef i32 @_Z4callRiPKi(ptr noundef nonnull align 4 // dereferenceable(4) %Zero, ptr noundef %One), !dbg !352, !psr.id !353; | ID: // 68 - const auto *Instruction68 = IRDB.getInstruction(68); - ASSERT_TRUE(Instruction68); + const auto *PercentCallZeroOneValue = + testingLocInIR(LineColFunOp{.Line = 29, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Call}, + IRDB); + const auto *PercentCallZeroOne = + llvm::dyn_cast(PercentCallZeroOneValue); + ASSERT_TRUE(PercentCallZeroOne); const auto *FuncZ4callRiPKi = IRDB.getFunction("_Z4callRiPKi"); // %Zero = alloca i32, align 4, !psr.id !324; | ID: 52 - const auto *Instr52 = IRDB.getInstruction(52); - ASSERT_TRUE(Instr52); + const auto *PercentZeroValue = + testingLocInIR(LineColFunOp{.Line = 25, + .Col = 7, + .InFunction = "main", + .OpCode = llvm::Instruction::Alloca}, + IRDB); + const auto *PercentZero = llvm::dyn_cast(PercentZeroValue); + ASSERT_TRUE(PercentZero); // %One = alloca i32, align 4, !psr.id !325; | ID: 53 - const auto *Instr53 = IRDB.getInstruction(53); - ASSERT_TRUE(Instr53); - - EXPECT_EQ(std::set{Instr52}, - getRetFlowValueSet(Instruction68, AliasImpl, - FuncZ4callRiPKi->getArg(0), Instruction48)); - EXPECT_EQ(std::set{Instr52}, - getRetFlowValueSet(Instruction68, NoAliasImpl, - FuncZ4callRiPKi->getArg(0), Instruction48)); - EXPECT_EQ(std::set{Instr52}, - getRetFlowValueSet(Instruction68, RASImpl, - FuncZ4callRiPKi->getArg(0), Instruction48)); - EXPECT_EQ(std::set{Instr53}, - getRetFlowValueSet(Instruction68, AliasImpl, - FuncZ4callRiPKi->getArg(1), Instruction48)); - EXPECT_EQ(std::set{Instr53}, - getRetFlowValueSet(Instruction68, NoAliasImpl, - FuncZ4callRiPKi->getArg(1), Instruction48)); - EXPECT_EQ(std::set{Instr53}, - getRetFlowValueSet(Instruction68, RASImpl, - FuncZ4callRiPKi->getArg(1), Instruction48)); + const auto *PercentOneValue = + testingLocInIR(LineColFunOp{.Line = 26, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Alloca}, + IRDB); + const auto *PercentOne = llvm::dyn_cast(PercentOneValue); + ASSERT_TRUE(PercentOne); + + expectRetFlow({PercentZero}, PercentCallZeroOne, FuncZ4callRiPKi->getArg(0), + RetValAdd6, I); + expectRetFlow({PercentOne}, PercentCallZeroOne, FuncZ4callRiPKi->getArg(1), + RetValAdd6, I); } /* @@ -947,112 +890,122 @@ TEST(PureFlow, CallToRetFlow01) { LLVMProjectIRDB IRDB( {unittest::PathToLLTestFiles + "pure_flow/call_to_ret_flow/call_to_ret_flow_01_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); + Impls I(&IRDB); // store i32 0, ptr %Zero, align 4, !dbg !252, !psr.id !254; | ID: 22 - const auto *Instr22 = IRDB.getInstruction(22); - ASSERT_TRUE(Instr22); + const auto *StorePercentZeroValue = + testingLocInIR(LineColFunOp{.Line = 6, + .Col = 7, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercentZero = + llvm::dyn_cast(StorePercentZeroValue); + ASSERT_TRUE(StorePercentZero); // store i32 1, ptr %One, align 4, !dbg !256, !psr.id !258; | ID: 24 - const auto *Instr24 = IRDB.getInstruction(24); - ASSERT_TRUE(Instr24); + const auto *StorePercentOneValue = + testingLocInIR(LineColFunOp{.Line = 6, + .Col = 7, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercentOne = + llvm::dyn_cast(StorePercentOneValue); + ASSERT_TRUE(StorePercentOne); // ret i32 0, !dbg !269, !psr.id !270; | ID: 30 - const auto *Instr30 = IRDB.getInstruction(30); - ASSERT_TRUE(Instr30); - - EXPECT_EQ(std::set{Instr22}, - getCallToRetFlowValueSet(Instr30, AliasImpl, Instr22)); - EXPECT_EQ(std::set{Instr22}, - getCallToRetFlowValueSet(Instr30, NoAliasImpl, Instr22)); - EXPECT_EQ(std::set{Instr22}, - getCallToRetFlowValueSet(Instr30, RASImpl, Instr22)); - - EXPECT_EQ(std::set{Instr24}, - getCallToRetFlowValueSet(Instr30, AliasImpl, Instr24)); - EXPECT_EQ(std::set{Instr24}, - getCallToRetFlowValueSet(Instr30, NoAliasImpl, Instr24)); - EXPECT_EQ(std::set{Instr24}, - getCallToRetFlowValueSet(Instr30, RASImpl, Instr24)); - - EXPECT_EQ(std::set{Instr30}, - getCallToRetFlowValueSet(Instr30, AliasImpl, Instr30)); - EXPECT_EQ(std::set{Instr30}, - getCallToRetFlowValueSet(Instr30, NoAliasImpl, Instr30)); - EXPECT_EQ(std::set{Instr30}, - getCallToRetFlowValueSet(Instr30, RASImpl, Instr30)); + const auto *RetMainValue = + testingLocInIR(LineColFunOp{.Line = 11, + .Col = 0, + .InFunction = "main", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetMainInstr = llvm::dyn_cast(RetMainValue); + ASSERT_TRUE(RetMainInstr); + + expectCallToRetFlow({StorePercentZero}, RetMainInstr, StorePercentZero, I); + expectCallToRetFlow({StorePercentOne}, RetMainInstr, StorePercentOne, I); + expectCallToRetFlow({RetMainInstr}, RetMainInstr, RetMainInstr, I); } TEST(PureFlow, CallToRetFlow02) { LLVMProjectIRDB IRDB( {unittest::PathToLLTestFiles + "pure_flow/call_to_ret_flow/call_to_ret_flow_02_cpp_dbg.ll"}); - IDEAliasImpl AliasImpl = IDEAliasImpl(&IRDB); - IDENoAliasImpl NoAliasImpl = IDENoAliasImpl(&IRDB); - IDEReachableAllocationSitesImpl RASImpl = - IDEReachableAllocationSitesImpl(&IRDB); + Impls I(&IRDB); // store i32 3, ptr %Three, align 4, !dbg !223, !psr.id !225; | ID: 5 - const auto *Instr5 = IRDB.getInstruction(5); - ASSERT_TRUE(Instr5); + const auto *StorePercentThreeValue = + testingLocInIR(LineColFunOp{.Line = 6, + .Col = 7, + .InFunction = "_Z4callv", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercentThree = + llvm::dyn_cast(StorePercentThreeValue); + ASSERT_TRUE(StorePercentThree); // store i32 4, ptr %Four, align 4, !dbg !229, !psr.id !231; | ID: 8 - const auto *Instr8 = IRDB.getInstruction(8); - ASSERT_TRUE(Instr8); + const auto *StorePercentFourValue = + testingLocInIR(LineColFunOp{.Line = 8, + .Col = 7, + .InFunction = "_Z4callv", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercentFour = + llvm::dyn_cast(StorePercentFourValue); + ASSERT_TRUE(StorePercentFour); // ret void, !dbg !234, !psr.id !235; | ID: 10 - const auto *Instr10 = IRDB.getInstruction(10); - ASSERT_TRUE(Instr10); - - EXPECT_EQ(std::set{Instr5}, - getCallToRetFlowValueSet(Instr10, AliasImpl, Instr5)); - EXPECT_EQ(std::set{Instr5}, - getCallToRetFlowValueSet(Instr10, NoAliasImpl, Instr5)); - EXPECT_EQ(std::set{Instr5}, - getCallToRetFlowValueSet(Instr10, RASImpl, Instr5)); - - EXPECT_EQ(std::set{Instr8}, - getCallToRetFlowValueSet(Instr10, AliasImpl, Instr8)); - EXPECT_EQ(std::set{Instr8}, - getCallToRetFlowValueSet(Instr10, NoAliasImpl, Instr8)); - EXPECT_EQ(std::set{Instr8}, - getCallToRetFlowValueSet(Instr10, RASImpl, Instr8)); + const auto *RetCallValue = + testingLocInIR(LineColFunOp{.Line = 10, + .Col = 0, + .InFunction = "_Z4callv", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetCall = llvm::dyn_cast(RetCallValue); + ASSERT_TRUE(RetCall); + + expectCallToRetFlow({StorePercentThree}, RetCall, StorePercentThree, I); + expectCallToRetFlow({StorePercentFour}, RetCall, StorePercentFour, I); // store i32 1, ptr %One, align 4, !dbg !255, !psr.id !257; | ID: 22 - const auto *Instr22 = IRDB.getInstruction(22); - ASSERT_TRUE(Instr22); + const auto *StorePercentOneValue = + testingLocInIR(LineColFunOp{.Line = 13, + .Col = 7, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercentOne = + llvm::dyn_cast(StorePercentOneValue); + ASSERT_TRUE(StorePercentOne); // store i32 2, ptr %Two, align 4, !dbg !261, !psr.id !263; | ID: 25 - const auto *Instr25 = IRDB.getInstruction(25); - ASSERT_TRUE(Instr25); + const auto *StorePercentTwoValue = + testingLocInIR(LineColFunOp{.Line = 15, + .Col = 7, + .InFunction = "main", + .OpCode = llvm::Instruction::Store}, + IRDB); + const auto *StorePercentTwo = + llvm::dyn_cast(StorePercentTwoValue); + ASSERT_TRUE(StorePercentTwo); // ret i32 0, !dbg !266, !psr.id !267; | ID: 27 - const auto *Instr27 = IRDB.getInstruction(27); - ASSERT_TRUE(Instr27); - - EXPECT_EQ(std::set{Instr22}, - getCallToRetFlowValueSet(Instr27, AliasImpl, Instr22)); - EXPECT_EQ(std::set{Instr22}, - getCallToRetFlowValueSet(Instr27, NoAliasImpl, Instr22)); - EXPECT_EQ(std::set{Instr22}, - getCallToRetFlowValueSet(Instr27, RASImpl, Instr22)); - - EXPECT_EQ(std::set{Instr25}, - getCallToRetFlowValueSet(Instr27, AliasImpl, Instr25)); - EXPECT_EQ(std::set{Instr25}, - getCallToRetFlowValueSet(Instr27, NoAliasImpl, Instr25)); - EXPECT_EQ(std::set{Instr25}, - getCallToRetFlowValueSet(Instr27, RASImpl, Instr25)); - - EXPECT_EQ(std::set{Instr27}, - getCallToRetFlowValueSet(Instr27, AliasImpl, Instr27)); - EXPECT_EQ(std::set{Instr27}, - getCallToRetFlowValueSet(Instr27, NoAliasImpl, Instr27)); - EXPECT_EQ(std::set{Instr27}, - getCallToRetFlowValueSet(Instr27, RASImpl, Instr27)); + const auto *RetCallOneValue = + testingLocInIR(LineColFunOp{.Line = 4, + .Col = 0, + .InFunction = "_Z7callOnev", + .OpCode = llvm::Instruction::Ret}, + IRDB); + const auto *RetCallOneInstr = + llvm::dyn_cast(RetCallOneValue); + ASSERT_TRUE(RetCallOneInstr); + + expectCallToRetFlow({StorePercentOne}, RetCallOneInstr, StorePercentOne, I); + expectCallToRetFlow({StorePercentTwo}, RetCallOneInstr, StorePercentTwo, I); + expectCallToRetFlow({RetCallOneInstr}, RetCallOneInstr, RetCallOneInstr, I); } }; // namespace diff --git a/unittests/TestUtils/SrcCodeLocationEntry.h b/unittests/TestUtils/SrcCodeLocationEntry.h index 26a993fc6f..61f6b7c37f 100644 --- a/unittests/TestUtils/SrcCodeLocationEntry.h +++ b/unittests/TestUtils/SrcCodeLocationEntry.h @@ -148,6 +148,7 @@ struct RetVal { return std::string("RetVal { InFunction: ") + InFunction.str() + " }"; } }; + struct RetStmt { llvm::StringRef InFunction; @@ -179,11 +180,25 @@ struct OperandOf { } }; +struct FuncByName { + llvm::StringRef FuncName; + + friend bool operator<(FuncByName F1, FuncByName F2) noexcept { + return F1.FuncName < F2.FuncName; + } + friend bool operator==(FuncByName F1, FuncByName F2) noexcept { + return F1.FuncName == F2.FuncName; + } + [[nodiscard]] std::string str() const { + return std::string("FuncByName { FuncName: ") + FuncName.str() + " }"; + } +}; + struct TestingSrcLocation : public std::variant { + ArgInFun, RetVal, RetStmt, OperandOf, FuncByName> { using VarT = std::variant; + ArgInFun, RetVal, RetStmt, OperandOf, FuncByName>; using VarT::variant; template [[nodiscard]] constexpr bool isa() const noexcept { @@ -267,6 +282,12 @@ template <> struct hash { } }; +template <> struct hash { + size_t operator()(psr::unittest::FuncByName Fun) const noexcept { + return llvm::hash_value(Fun.FuncName); + } +}; + template <> struct hash { size_t operator()(const psr::unittest::TestingSrcLocation &Loc) const noexcept { @@ -398,7 +419,13 @@ testingLocInIR(TestingSrcLocation Loc, const LLVMProjectIRDB &IRDB, return Inst->getOperand(Op.OperandIndex); }, - }, + [&](FuncByName F) -> llvm::Value const * { + const auto *Func = GetFunction(F.FuncName); + if (Func) { + return Func; + } + llvm::report_fatal_error("No function named " + F.FuncName); + }}, Loc); if (!Ret) { llvm::report_fatal_error("Cannot convert " + llvm::Twine(Loc.str()) +