diff --git a/Assignment-2/Test2.cpp b/Assignment-2/Test2.cpp index e782c5e..2cbf70d 100644 --- a/Assignment-2/Test2.cpp +++ b/Assignment-2/Test2.cpp @@ -87,10 +87,42 @@ void Test2() SVFIR::releaseSVFIR(); delete gt; } + +void Test3() +{ + // Your current workingspace dir}/Assignment-2/testCase/ + std::vector moduleNameVec = {"./Assignment-2/testcase/bc/test3.ll"}; + + SVFModule *svfModule = LLVMModuleSet::getLLVMModuleSet()->buildSVFModule(moduleNameVec); + + /// Build Program Assignment Graph (SVFIR) + SVFIRBuilder builder(svfModule); + SVFIR *pag = builder.build(); + ICFG *icfg = pag->getICFG(); + // If you want to test your own case, plase change the dump name + icfg->dump("./Assignment-2/testcase/dot/test3.ll.icfg"); + ICFGTraversal *gt = new ICFGTraversal(pag); + for (const CallICFGNode *src : gt->identifySources()) + { + for (const CallICFGNode *snk : gt->identifySinks()) + { + gt->reachability(src, snk); + } + } + + std::set expected = {"START->10->11->12->13->4->5->6->7->14->15->4->5->6->7->16->17->18->END"}; + assert(expected == gt->getPaths() && "test3 failed!"); + std::cout << "test2 passed!" << "\n"; + LLVMModuleSet::releaseLLVMModuleSet(); + SVFIR::releaseSVFIR(); + delete gt; +} + void Test() { Test1(); Test2(); + Test3(); } int main() diff --git a/Assignment-2/testcase/bc/test3.ll b/Assignment-2/testcase/bc/test3.ll new file mode 100644 index 0000000..83b7d51 --- /dev/null +++ b/Assignment-2/testcase/bc/test3.ll @@ -0,0 +1,47 @@ +; ModuleID = 'test3.ll' +source_filename = "Assignment-2/testcase/src/test3.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @bar(i32 noundef %s) #0 { +entry: + ret i32 %s +} + +; Function Attrs: noinline nounwind uwtable +define dso_local void @foo(ptr noundef %p) #0 { +entry: + store i32 1, ptr %p, align 4 + ret void +} + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 { +entry: + %a = alloca i32, align 4 + %call = call i32 (...) @source() + store i32 %call, ptr %a, align 4 + call void @foo(ptr noundef %a) + call void @foo(ptr noundef %a) + %0 = load i32, ptr %a, align 4 + call void @sink(i32 noundef %0) + ret i32 0 +} + +declare i32 @source(...) #1 + +declare void @sink(i32 noundef) #1 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 16.0.4 (https://github.com/llvm/llvm-project ae42196bc493ffe877a7e3dff8be32035dea4d07)"} diff --git a/Assignment-2/testcase/dot/test1.ll.icfg.dot b/Assignment-2/testcase/dot/test1.ll.icfg.dot index 8812ec0..a5adc43 100644 --- a/Assignment-2/testcase/dot/test1.ll.icfg.dot +++ b/Assignment-2/testcase/dot/test1.ll.icfg.dot @@ -1,52 +1,52 @@ digraph "ICFG" { label="ICFG"; - Node0x1ad97f0 [shape=record,color=purple,label="{GlobalICFGNode0\nCopyStmt: [Var1 \<-- Var0] \n ptr null \{ constant data \}\nAddrStmt: [Var32 \<-- Var3] \n i32 0 \{ constant data \}\nAddrStmt: [Var19 \<-- Var3] \n i32 1 \{ constant data \}\nAddrStmt: [Var4 \<-- Var5] \nFunction: source \nAddrStmt: [Var9 \<-- Var10] \nFunction: sink \nAddrStmt: [Var14 \<-- Var15] \nFunction: main }"]; - Node0x1ad97f0 -> Node0x1a52f60[style=solid]; - Node0x1a623c0 [shape=record,color=yellow,label="{FunEntryICFGNode1 \{fun: source\}}"]; - Node0x1a623c0 -> Node0x1a65c80[style=solid]; - Node0x1a65c80 [shape=record,color=red,label="{CallICFGNode2 \{fun: source\}|{0x1ad91a0}}"]; - Node0x1a65c80:s0 -> Node0x1a58b10[style=solid,color=red]; - Node0x1a60360 [shape=record,color=blue,label="{RetICFGNode3 \{fun: source\}}"]; - Node0x1a60360 -> Node0x1acb6c0[style=solid]; - Node0x1a58b10 [shape=record,color=yellow,label="{FunEntryICFGNode4 \{fun: sink\}}"]; - Node0x1a58b10 -> Node0x1aeae20[style=solid]; - Node0x1ad9d60 [shape=record,color=green,label="{FunExitICFGNode5 \{fun: sink\}|{0x1ad91a0}}"]; - Node0x1ad9d60:s0 -> Node0x1a60360[style=solid,color=blue]; - Node0x1acb6c0 [shape=record,color=black,label="{IntraICFGNode6 \{fun: source\}\n ret void }"]; - Node0x1acb6c0 -> Node0x1aa1d20[style=solid]; - Node0x1aa1d20 [shape=record,color=green,label="{FunExitICFGNode7 \{fun: source\}|{0x1aeb5d0}}"]; - Node0x1aa1d20:s0 -> Node0x1a7a650[style=solid,color=blue]; - Node0x1aeae20 [shape=record,color=black,label="{IntraICFGNode8 \{fun: sink\}\n ret void }"]; - Node0x1aeae20 -> Node0x1ad9d60[style=solid]; - Node0x1a52f60 [shape=record,color=yellow,label="{FunEntryICFGNode9 \{fun: main\}}"]; - Node0x1a52f60 -> Node0x1a9d210[style=solid]; - Node0x1a9d210 [shape=record,color=black,label="{IntraICFGNode10 \{fun: main\}\nAddrStmt: [Var17 \<-- Var18] \n %a = alloca i32, align 4 }"]; - Node0x1a9d210 -> Node0x1a70370[style=solid]; - Node0x1a70370 [shape=record,color=black,label="{IntraICFGNode11 \{fun: main\}\nStoreStmt: [Var17 \<-- Var19] \n store i32 1, ptr %a, align 4 }"]; - Node0x1a70370 -> Node0x1a56230[style=solid]; - Node0x1a56230 [shape=record,color=black,label="{IntraICFGNode12 \{fun: main\}\nBranchStmt: [ Unconditional branch]\nSuccessor 0 ICFGNode13 \n br label %while.cond }"]; - Node0x1a56230 -> Node0x1a73420[style=solid]; - Node0x1a73420 [shape=record,color=black,label="{IntraICFGNode13 \{fun: main\}\nLoadStmt: [Var23 \<-- Var17] \n %0 = load i32, ptr %a, align 4 }"]; - Node0x1a73420 -> Node0x1ad4db0[style=solid]; - Node0x1ad4db0 [shape=record,color=black,label="{IntraICFGNode14 \{fun: main\}\nCmpStmt: [Var24 \<-- (Var23 predicate41 Var19)] \n %cmp = icmp sle i32 %0, 1 }"]; - Node0x1ad4db0 -> Node0x1ae28a0[style=solid]; - Node0x1ae28a0 [shape=record,color=black,label="{IntraICFGNode15 \{fun: main\}\nBranchStmt: [Condition Var24]\nSuccessor 0 ICFGNode16 Successor 1 ICFGNode18 \n br i1 %cmp, label %while.body, label %while.end }"]; - Node0x1ae28a0 -> Node0x1a992d0[style=solid]; - Node0x1ae28a0 -> Node0x1ad4010[style=solid]; - Node0x1a992d0 [shape=record,color=red,label="{CallICFGNode16 \{fun: main\}\nCallPE: [Var7 \<-- Var17] \n call void @source(ptr noundef %a) |{0x1aeb5d0}}"]; - Node0x1a992d0:s0 -> Node0x1a623c0[style=solid,color=red]; - Node0x1a7a650 [shape=record,color=blue,label="{RetICFGNode17 \{fun: main\}}"]; - Node0x1a7a650 -> Node0x1ae4680[style=solid]; - Node0x1ad4010 [shape=record,color=black,label="{IntraICFGNode18 \{fun: main\}\n ret i32 0 }"]; - Node0x1ad4010 -> Node0x1a85d20[style=solid]; - Node0x1ae4680 [shape=record,color=black,label="{IntraICFGNode19 \{fun: main\}\nLoadStmt: [Var27 \<-- Var17] \n %1 = load i32, ptr %a, align 4 }"]; - Node0x1ae4680 -> Node0x1a85620[style=solid]; - Node0x1a85d20 [shape=record,color=green,label="{FunExitICFGNode20 \{fun: main\}\nPhiStmt: [Var16 \<-- ([Var32, ICFGNode18],)] \n ret i32 0 }"]; - Node0x1a85620 [shape=record,color=black,label="{IntraICFGNode21 \{fun: main\}\nBinaryOPStmt: [Var28 \<-- (Var27 opcode13 Var19)] \n %inc = add nsw i32 %1, 1 }"]; - Node0x1a85620 -> Node0x1ae2040[style=solid]; - Node0x1ae2040 [shape=record,color=black,label="{IntraICFGNode22 \{fun: main\}\nStoreStmt: [Var17 \<-- Var28] \n store i32 %inc, ptr %a, align 4 }"]; - Node0x1ae2040 -> Node0x1a6a460[style=solid]; - Node0x1a6a460 [shape=record,color=black,label="{IntraICFGNode23 \{fun: main\}\nBranchStmt: [ Unconditional branch]\nSuccessor 0 ICFGNode13 \n br label %while.cond, !llvm.loop !6 }"]; - Node0x1a6a460 -> Node0x1a73420[style=solid]; + Node0x557d0caf48b0 [shape=record,color=purple,label="{GlobalICFGNode0\nCopyStmt: [Var1 \<-- Var0] \n ptr null \{ constant data \}\nAddrStmt: [Var32 \<-- Var3] \n i32 0 \{ constant data \}\nAddrStmt: [Var19 \<-- Var3] \n i32 1 \{ constant data \}\nAddrStmt: [Var4 \<-- Var5] \nFunction: source \nAddrStmt: [Var9 \<-- Var10] \nFunction: sink \nAddrStmt: [Var14 \<-- Var15] \nFunction: main }"]; + Node0x557d0caf48b0 -> Node0x557d0cad53d0[style=solid]; + Node0x557d0cae4520 [shape=record,color=yellow,label="{FunEntryICFGNode1 \{fun: source\}}"]; + Node0x557d0cae4520 -> Node0x557d0cae7de0[style=solid]; + Node0x557d0cae7de0 [shape=record,color=red,label="{CallICFGNode2 \{fun: source\}\n call void @sink() |{0x557d0cae7de0}}"]; + Node0x557d0cae7de0:s0 -> Node0x557d0cadab90[style=solid,color=red]; + Node0x557d0cae24c0 [shape=record,color=blue,label="{RetICFGNode3 \{fun: source\}\n call void @sink() }"]; + Node0x557d0cae24c0 -> Node0x557d0cb5be60[style=solid]; + Node0x557d0cadab90 [shape=record,color=yellow,label="{FunEntryICFGNode4 \{fun: sink\}}"]; + Node0x557d0cadab90 -> Node0x557d0cb4d7c0[style=solid]; + Node0x557d0cb5bab0 [shape=record,color=green,label="{FunExitICFGNode5 \{fun: sink\}|{0x557d0cae7de0}}"]; + Node0x557d0cb5bab0:s0 -> Node0x557d0cae24c0[style=solid,color=blue]; + Node0x557d0cb5be60 [shape=record,color=black,label="{IntraICFGNode6 \{fun: source\}\n ret void }"]; + Node0x557d0cb5be60 -> Node0x557d0cb23ea0[style=solid]; + Node0x557d0cb23ea0 [shape=record,color=green,label="{FunExitICFGNode7 \{fun: source\}|{0x557d0cb24d30}}"]; + Node0x557d0cb23ea0:s0 -> Node0x557d0cae80c0[style=solid,color=blue]; + Node0x557d0cb4d7c0 [shape=record,color=black,label="{IntraICFGNode8 \{fun: sink\}\n ret void }"]; + Node0x557d0cb4d7c0 -> Node0x557d0cb5bab0[style=solid]; + Node0x557d0cad53d0 [shape=record,color=yellow,label="{FunEntryICFGNode9 \{fun: main\}}"]; + Node0x557d0cad53d0 -> Node0x557d0cb6d9e0[style=solid]; + Node0x557d0cb6d9e0 [shape=record,color=black,label="{IntraICFGNode10 \{fun: main\}\nAddrStmt: [Var17 \<-- Var18] \n %a = alloca i32, align 4 }"]; + Node0x557d0cb6d9e0 -> Node0x557d0cb6d6d0[style=solid]; + Node0x557d0cb6d6d0 [shape=record,color=black,label="{IntraICFGNode11 \{fun: main\}\nStoreStmt: [Var17 \<-- Var19] \n store i32 1, ptr %a, align 4 }"]; + Node0x557d0cb6d6d0 -> Node0x557d0cb5b2a0[style=solid]; + Node0x557d0cb5b2a0 [shape=record,color=black,label="{IntraICFGNode12 \{fun: main\}\nBranchStmt: [ Unconditional branch]\nSuccessor 0 ICFGNode13 \n br label %while.cond }"]; + Node0x557d0cb5b2a0 -> Node0x557d0cb3d4a0[style=solid]; + Node0x557d0cb3d4a0 [shape=record,color=black,label="{IntraICFGNode13 \{fun: main\}\nLoadStmt: [Var23 \<-- Var17] \n %0 = load i32, ptr %a, align 4 }"]; + Node0x557d0cb3d4a0 -> Node0x557d0caff780[style=solid]; + Node0x557d0caff780 [shape=record,color=black,label="{IntraICFGNode14 \{fun: main\}\nCmpStmt: [Var24 \<-- (Var23 predicate41 Var19)] \n %cmp = icmp sle i32 %0, 1 }"]; + Node0x557d0caff780 -> Node0x557d0cafa290[style=solid]; + Node0x557d0cafa290 [shape=record,color=black,label="{IntraICFGNode15 \{fun: main\}\nBranchStmt: [Condition Var24]\nSuccessor 0 ICFGNode16 Successor 1 ICFGNode18 \n br i1 %cmp, label %while.body, label %while.end }"]; + Node0x557d0cafa290 -> Node0x557d0cb24d30[style=solid]; + Node0x557d0cafa290 -> Node0x557d0cb44070[style=solid]; + Node0x557d0cb24d30 [shape=record,color=red,label="{CallICFGNode16 \{fun: main\}\nCallPE: [Var7 \<-- Var17] \n call void @source(ptr noundef %a) |{0x557d0cb24d30}}"]; + Node0x557d0cb24d30:s0 -> Node0x557d0cae4520[style=solid,color=red]; + Node0x557d0cae80c0 [shape=record,color=blue,label="{RetICFGNode17 \{fun: main\}\n call void @source(ptr noundef %a) }"]; + Node0x557d0cae80c0 -> Node0x557d0cb69c80[style=solid]; + Node0x557d0cb44070 [shape=record,color=black,label="{IntraICFGNode18 \{fun: main\}\n ret i32 0 }"]; + Node0x557d0cb44070 -> Node0x557d0cb013e0[style=solid]; + Node0x557d0cb69c80 [shape=record,color=black,label="{IntraICFGNode19 \{fun: main\}\nLoadStmt: [Var27 \<-- Var17] \n %1 = load i32, ptr %a, align 4 }"]; + Node0x557d0cb69c80 -> Node0x557d0cb24bb0[style=solid]; + Node0x557d0cb013e0 [shape=record,color=green,label="{FunExitICFGNode20 \{fun: main\}\nPhiStmt: [Var16 \<-- ([Var32, ICFGNode18],)] \n ret i32 0 }"]; + Node0x557d0cb24bb0 [shape=record,color=black,label="{IntraICFGNode21 \{fun: main\}\nBinaryOPStmt: [Var28 \<-- (Var27 opcode13 Var19)] \n %inc = add nsw i32 %1, 1 }"]; + Node0x557d0cb24bb0 -> Node0x557d0cb711f0[style=solid]; + Node0x557d0cb711f0 [shape=record,color=black,label="{IntraICFGNode22 \{fun: main\}\nStoreStmt: [Var17 \<-- Var28] \n store i32 %inc, ptr %a, align 4 }"]; + Node0x557d0cb711f0 -> Node0x557d0cb6d390[style=solid]; + Node0x557d0cb6d390 [shape=record,color=black,label="{IntraICFGNode23 \{fun: main\}\nBranchStmt: [ Unconditional branch]\nSuccessor 0 ICFGNode13 \n br label %while.cond, !llvm.loop !6 }"]; + Node0x557d0cb6d390 -> Node0x557d0cb3d4a0[style=solid]; } diff --git a/Assignment-2/testcase/dot/test2.ll.icfg.dot b/Assignment-2/testcase/dot/test2.ll.icfg.dot index 7551608..71ae240 100644 --- a/Assignment-2/testcase/dot/test2.ll.icfg.dot +++ b/Assignment-2/testcase/dot/test2.ll.icfg.dot @@ -1,47 +1,47 @@ digraph "ICFG" { label="ICFG"; - Node0x1a6bf20 [shape=record,color=purple,label="{GlobalICFGNode0\nCopyStmt: [Var1 \<-- Var0] \n ptr null \{ constant data \}\nAddrStmt: [Var16 \<-- Var3] \n i32 0 \{ constant data \}\nAddrStmt: [Var4 \<-- Var5] \nFunction: bar \nAddrStmt: [Var9 \<-- Var10] \nFunction: main \nAddrStmt: [Var13 \<-- Var14] \nFunction: source \nAddrStmt: [Var20 \<-- Var21] \nFunction: sink }"]; - Node0x1a6bf20 -> Node0x1a623c0[style=solid]; - Node0x1a60360 [shape=record,color=yellow,label="{FunEntryICFGNode1 \{fun: bar\}}"]; - Node0x1a60360 -> Node0x1ad9d60[style=solid]; - Node0x1ad9d60 [shape=record,color=black,label="{IntraICFGNode2 \{fun: bar\}\n ret i32 %s }"]; - Node0x1ad9d60 -> Node0x1a803d0[style=solid]; - Node0x1a803d0 [shape=record,color=green,label="{FunExitICFGNode3 \{fun: bar\}\nPhiStmt: [Var6 \<-- ([Var7, ICFGNode2],)] \n ret i32 %s |{0x1a80770|0x1a801c0}}"]; - Node0x1a803d0:s0 -> Node0x1a6bfe0[style=solid,color=blue]; - Node0x1a803d0:s1 -> Node0x1a760f0[style=solid,color=blue]; - Node0x1a623c0 [shape=record,color=yellow,label="{FunEntryICFGNode4 \{fun: main\}}"]; - Node0x1a623c0 -> Node0x1ab0880[style=solid]; - Node0x1ab0880 [shape=record,color=red,label="{CallICFGNode5 \{fun: main\}}"]; - Node0x1ab0880 -> Node0x1a8ace0[style=solid]; - Node0x1a8ace0 [shape=record,color=blue,label="{RetICFGNode6 \{fun: main\}}"]; - Node0x1a8ace0 -> Node0x1a56230[style=solid]; - Node0x1a56230 [shape=record,color=black,label="{IntraICFGNode7 \{fun: main\}\nCmpStmt: [Var15 \<-- (Var12 predicate38 Var16)] \n %cmp = icmp sgt i32 %call, 0 }"]; - Node0x1a56230 -> Node0x1a687a0[style=solid]; - Node0x1a687a0 [shape=record,color=black,label="{IntraICFGNode8 \{fun: main\}\nBranchStmt: [Condition Var15]\nSuccessor 0 ICFGNode9 Successor 1 ICFGNode11 \n br i1 %cmp, label %if.then, label %if.else }"]; - Node0x1a687a0 -> Node0x1ad8f40[style=solid]; - Node0x1a687a0 -> Node0x1ab9340[style=solid]; - Node0x1ad8f40 [shape=record,color=red,label="{CallICFGNode9 \{fun: main\}\nCallPE: [Var7 \<-- Var12] \n %call1 = call i32 @bar(i32 noundef %call) |{0x1a80770}}"]; - Node0x1ad8f40:s0 -> Node0x1a60360[style=solid,color=red]; - Node0x1a6bfe0 [shape=record,color=blue,label="{RetICFGNode10 \{fun: main\}\nRetPE: [Var18 \<-- Var6] \n %call1 = call i32 @bar(i32 noundef %call) }"]; - Node0x1a6bfe0 -> Node0x1ac4690[style=solid]; - Node0x1ab9340 [shape=record,color=red,label="{CallICFGNode11 \{fun: main\}\nCallPE: [Var7 \<-- Var12] \n %call2 = call i32 @bar(i32 noundef %call) |{0x1a801c0}}"]; - Node0x1ab9340:s0 -> Node0x1a60360[style=solid,color=red]; - Node0x1a760f0 [shape=record,color=blue,label="{RetICFGNode12 \{fun: main\}\nRetPE: [Var24 \<-- Var6] \n %call2 = call i32 @bar(i32 noundef %call) }"]; - Node0x1a760f0 -> Node0x1aa24b0[style=solid]; - Node0x1ac4690 [shape=record,color=red,label="{CallICFGNode13 \{fun: main\}}"]; - Node0x1ac4690 -> Node0x1a6c270[style=solid]; - Node0x1a6c270 [shape=record,color=blue,label="{RetICFGNode14 \{fun: main\}}"]; - Node0x1a6c270 -> Node0x1ad09e0[style=solid]; - Node0x1aa24b0 [shape=record,color=red,label="{CallICFGNode15 \{fun: main\}}"]; - Node0x1aa24b0 -> Node0x1ae9910[style=solid]; - Node0x1ae9910 [shape=record,color=blue,label="{RetICFGNode16 \{fun: main\}}"]; - Node0x1ae9910 -> Node0x1a620c0[style=solid]; - Node0x1ad09e0 [shape=record,color=black,label="{IntraICFGNode17 \{fun: main\}\nBranchStmt: [ Unconditional branch]\nSuccessor 0 ICFGNode19 \n br label %if.end }"]; - Node0x1ad09e0 -> Node0x1a6a4d0[style=solid]; - Node0x1a620c0 [shape=record,color=black,label="{IntraICFGNode18 \{fun: main\}\nBranchStmt: [ Unconditional branch]\nSuccessor 0 ICFGNode19 \n br label %if.end }"]; - Node0x1a620c0 -> Node0x1a6a4d0[style=solid]; - Node0x1a6a4d0 [shape=record,color=black,label="{IntraICFGNode19 \{fun: main\}\n ret i32 0 }"]; - Node0x1a6a4d0 -> Node0x1a6c380[style=solid]; - Node0x1a6c380 [shape=record,color=green,label="{FunExitICFGNode20 \{fun: main\}\nPhiStmt: [Var11 \<-- ([Var16, ICFGNode19],)] \n ret i32 0 }"]; + Node0x557d0cb41a00 [shape=record,color=purple,label="{GlobalICFGNode0\nCopyStmt: [Var1 \<-- Var0] \n ptr null \{ constant data \}\nAddrStmt: [Var16 \<-- Var3] \n i32 0 \{ constant data \}\nAddrStmt: [Var4 \<-- Var5] \nFunction: bar \nAddrStmt: [Var9 \<-- Var10] \nFunction: main \nAddrStmt: [Var13 \<-- Var14] \nFunction: source \nAddrStmt: [Var20 \<-- Var21] \nFunction: sink }"]; + Node0x557d0cb41a00 -> Node0x557d0cae4520[style=solid]; + Node0x557d0cae24c0 [shape=record,color=yellow,label="{FunEntryICFGNode1 \{fun: bar\}}"]; + Node0x557d0cae24c0 -> Node0x557d0caf5e30[style=solid]; + Node0x557d0caf5e30 [shape=record,color=black,label="{IntraICFGNode2 \{fun: bar\}\n ret i32 %s }"]; + Node0x557d0caf5e30 -> Node0x557d0cb01730[style=solid]; + Node0x557d0cb01730 [shape=record,color=green,label="{FunExitICFGNode3 \{fun: bar\}\nPhiStmt: [Var6 \<-- ([Var7, ICFGNode2],)] \n ret i32 %s |{0x557d0cb2da50|0x557d0cb24d30}}"]; + Node0x557d0cb01730:s0 -> Node0x557d0cb37ef0[style=solid,color=blue]; + Node0x557d0cb01730:s1 -> Node0x557d0caea7d0[style=solid,color=blue]; + Node0x557d0cae4520 [shape=record,color=yellow,label="{FunEntryICFGNode4 \{fun: main\}}"]; + Node0x557d0cae4520 -> Node0x557d0cafa1a0[style=solid]; + Node0x557d0cafa1a0 [shape=record,color=red,label="{CallICFGNode5 \{fun: main\}\n %call = call i32 (...) @source() }"]; + Node0x557d0cafa1a0 -> Node0x557d0cb03760[style=solid]; + Node0x557d0cb03760 [shape=record,color=blue,label="{RetICFGNode6 \{fun: main\}\n %call = call i32 (...) @source() }"]; + Node0x557d0cb03760 -> Node0x557d0caeb050[style=solid]; + Node0x557d0caeb050 [shape=record,color=black,label="{IntraICFGNode7 \{fun: main\}\nCmpStmt: [Var15 \<-- (Var12 predicate38 Var16)] \n %cmp = icmp sgt i32 %call, 0 }"]; + Node0x557d0caeb050 -> Node0x557d0caeac00[style=solid]; + Node0x557d0caeac00 [shape=record,color=black,label="{IntraICFGNode8 \{fun: main\}\nBranchStmt: [Condition Var15]\nSuccessor 0 ICFGNode9 Successor 1 ICFGNode11 \n br i1 %cmp, label %if.then, label %if.else }"]; + Node0x557d0caeac00 -> Node0x557d0cb2da50[style=solid]; + Node0x557d0caeac00 -> Node0x557d0cb24d30[style=solid]; + Node0x557d0cb2da50 [shape=record,color=red,label="{CallICFGNode9 \{fun: main\}\nCallPE: [Var7 \<-- Var12] \n %call1 = call i32 @bar(i32 noundef %call) |{0x557d0cb2da50}}"]; + Node0x557d0cb2da50:s0 -> Node0x557d0cae24c0[style=solid,color=red]; + Node0x557d0cb37ef0 [shape=record,color=blue,label="{RetICFGNode10 \{fun: main\}\nRetPE: [Var18 \<-- Var6] \n %call1 = call i32 @bar(i32 noundef %call) }"]; + Node0x557d0cb37ef0 -> Node0x557d0cae7de0[style=solid]; + Node0x557d0cb24d30 [shape=record,color=red,label="{CallICFGNode11 \{fun: main\}\nCallPE: [Var7 \<-- Var12] \n %call2 = call i32 @bar(i32 noundef %call) |{0x557d0cb24d30}}"]; + Node0x557d0cb24d30:s0 -> Node0x557d0cae24c0[style=solid,color=red]; + Node0x557d0caea7d0 [shape=record,color=blue,label="{RetICFGNode12 \{fun: main\}\nRetPE: [Var24 \<-- Var6] \n %call2 = call i32 @bar(i32 noundef %call) }"]; + Node0x557d0caea7d0 -> Node0x557d0cb46ea0[style=solid]; + Node0x557d0cae7de0 [shape=record,color=red,label="{CallICFGNode13 \{fun: main\}\n call void @sink(i32 noundef %call1) }"]; + Node0x557d0cae7de0 -> Node0x557d0cae9ae0[style=solid]; + Node0x557d0cae9ae0 [shape=record,color=blue,label="{RetICFGNode14 \{fun: main\}\n call void @sink(i32 noundef %call1) }"]; + Node0x557d0cae9ae0 -> Node0x557d0cb5be60[style=solid]; + Node0x557d0cb46ea0 [shape=record,color=red,label="{CallICFGNode15 \{fun: main\}\n call void @sink(i32 noundef %call2) }"]; + Node0x557d0cb46ea0 -> Node0x557d0cb50e60[style=solid]; + Node0x557d0cb50e60 [shape=record,color=blue,label="{RetICFGNode16 \{fun: main\}\n call void @sink(i32 noundef %call2) }"]; + Node0x557d0cb50e60 -> Node0x557d0cb5bab0[style=solid]; + Node0x557d0cb5be60 [shape=record,color=black,label="{IntraICFGNode17 \{fun: main\}\nBranchStmt: [ Unconditional branch]\nSuccessor 0 ICFGNode19 \n br label %if.end }"]; + Node0x557d0cb5be60 -> Node0x557d0cb0d230[style=solid]; + Node0x557d0cb5bab0 [shape=record,color=black,label="{IntraICFGNode18 \{fun: main\}\nBranchStmt: [ Unconditional branch]\nSuccessor 0 ICFGNode19 \n br label %if.end }"]; + Node0x557d0cb5bab0 -> Node0x557d0cb0d230[style=solid]; + Node0x557d0cb0d230 [shape=record,color=black,label="{IntraICFGNode19 \{fun: main\}\n ret i32 0 }"]; + Node0x557d0cb0d230 -> Node0x557d0cb3ac20[style=solid]; + Node0x557d0cb3ac20 [shape=record,color=green,label="{FunExitICFGNode20 \{fun: main\}\nPhiStmt: [Var11 \<-- ([Var16, ICFGNode19],)] \n ret i32 0 }"]; } diff --git a/Assignment-2/testcase/dot/test3.ll.icfg.dot b/Assignment-2/testcase/dot/test3.ll.icfg.dot new file mode 100644 index 0000000..aadcc68 --- /dev/null +++ b/Assignment-2/testcase/dot/test3.ll.icfg.dot @@ -0,0 +1,47 @@ +digraph "ICFG" { + label="ICFG"; + + Node0x557d0cae6390 [shape=record,color=purple,label="{GlobalICFGNode0\nCopyStmt: [Var1 \<-- Var0] \n ptr null \{ constant data \}\nAddrStmt: [Var14 \<-- Var3] \n i32 1 \{ constant data \}\nAddrStmt: [Var32 \<-- Var3] \n i32 0 \{ constant data \}\nAddrStmt: [Var4 \<-- Var5] \nFunction: bar \nAddrStmt: [Var9 \<-- Var10] \nFunction: foo \nAddrStmt: [Var16 \<-- Var17] \nFunction: main \nAddrStmt: [Var22 \<-- Var23] \nFunction: source \nAddrStmt: [Var29 \<-- Var30] \nFunction: sink }"]; + Node0x557d0cae6390 -> Node0x557d0cb5bb80[style=solid]; + Node0x557d0cb51550 [shape=record,color=yellow,label="{FunEntryICFGNode1 \{fun: bar\}}"]; + Node0x557d0cb51550 -> Node0x557d0caeab30[style=solid]; + Node0x557d0caeab30 [shape=record,color=black,label="{IntraICFGNode2 \{fun: bar\}\n ret i32 %s }"]; + Node0x557d0caeab30 -> Node0x557d0cb5be60[style=solid]; + Node0x557d0cb5be60 [shape=record,color=green,label="{FunExitICFGNode3 \{fun: bar\}\nPhiStmt: [Var6 \<-- ([Var7, ICFGNode2],)] \n ret i32 %s }"]; + Node0x557d0cb35aa0 [shape=record,color=yellow,label="{FunEntryICFGNode4 \{fun: foo\}}"]; + Node0x557d0cb35aa0 -> Node0x557d0cb5bab0[style=solid]; + Node0x557d0cb5bab0 [shape=record,color=black,label="{IntraICFGNode5 \{fun: foo\}\nStoreStmt: [Var12 \<-- Var14] \n store i32 1, ptr %p, align 4 }"]; + Node0x557d0cb5bab0 -> Node0x557d0cb3e150[style=solid]; + Node0x557d0cb3e150 [shape=record,color=black,label="{IntraICFGNode6 \{fun: foo\}\n ret void }"]; + Node0x557d0cb3e150 -> Node0x557d0cb01730[style=solid]; + Node0x557d0cb01730 [shape=record,color=green,label="{FunExitICFGNode7 \{fun: foo\}|{0x557d0cb2da50|0x557d0cb58370}}"]; + Node0x557d0cb01730:s0 -> Node0x557d0cafa370[style=solid,color=blue]; + Node0x557d0cb01730:s1 -> Node0x557d0cb723b0[style=solid,color=blue]; + Node0x557d0cb5bb80 [shape=record,color=yellow,label="{FunEntryICFGNode8 \{fun: main\}}"]; + Node0x557d0cb5bb80 -> Node0x557d0caf5e30[style=solid]; + Node0x557d0caf5e30 [shape=record,color=black,label="{IntraICFGNode9 \{fun: main\}\nAddrStmt: [Var19 \<-- Var20] \n %a = alloca i32, align 4 }"]; + Node0x557d0caf5e30 -> Node0x557d0cb24d30[style=solid]; + Node0x557d0cb24d30 [shape=record,color=red,label="{CallICFGNode10 \{fun: main\}\n %call = call i32 (...) @source() }"]; + Node0x557d0cb24d30 -> Node0x557d0cb26480[style=solid]; + Node0x557d0cb26480 [shape=record,color=blue,label="{RetICFGNode11 \{fun: main\}\n %call = call i32 (...) @source() }"]; + Node0x557d0cb26480 -> Node0x557d0cb496b0[style=solid]; + Node0x557d0cb496b0 [shape=record,color=black,label="{IntraICFGNode12 \{fun: main\}\nStoreStmt: [Var19 \<-- Var21] \n store i32 %call, ptr %a, align 4 }"]; + Node0x557d0cb496b0 -> Node0x557d0cb2da50[style=solid]; + Node0x557d0cb2da50 [shape=record,color=red,label="{CallICFGNode13 \{fun: main\}\nCallPE: [Var12 \<-- Var19] \n call void @foo(ptr noundef %a) |{0x557d0cb2da50}}"]; + Node0x557d0cb2da50:s0 -> Node0x557d0cb35aa0[style=solid,color=red]; + Node0x557d0cafa370 [shape=record,color=blue,label="{RetICFGNode14 \{fun: main\}\n call void @foo(ptr noundef %a) }"]; + Node0x557d0cafa370 -> Node0x557d0cb58370[style=solid]; + Node0x557d0cb58370 [shape=record,color=red,label="{CallICFGNode15 \{fun: main\}\nCallPE: [Var12 \<-- Var19] \n call void @foo(ptr noundef %a) |{0x557d0cb58370}}"]; + Node0x557d0cb58370:s0 -> Node0x557d0cb35aa0[style=solid,color=red]; + Node0x557d0cb723b0 [shape=record,color=blue,label="{RetICFGNode16 \{fun: main\}\n call void @foo(ptr noundef %a) }"]; + Node0x557d0cb723b0 -> Node0x557d0cb54ae0[style=solid]; + Node0x557d0cb54ae0 [shape=record,color=black,label="{IntraICFGNode17 \{fun: main\}\nLoadStmt: [Var27 \<-- Var19] \n %0 = load i32, ptr %a, align 4 }"]; + Node0x557d0cb54ae0 -> Node0x557d0caec5d0[style=solid]; + Node0x557d0caec5d0 [shape=record,color=red,label="{CallICFGNode18 \{fun: main\}\n call void @sink(i32 noundef %0) }"]; + Node0x557d0caec5d0 -> Node0x557d0caf6920[style=solid]; + Node0x557d0caf6920 [shape=record,color=blue,label="{RetICFGNode19 \{fun: main\}\n call void @sink(i32 noundef %0) }"]; + Node0x557d0caf6920 -> Node0x557d0cb73ac0[style=solid]; + Node0x557d0cb73ac0 [shape=record,color=black,label="{IntraICFGNode20 \{fun: main\}\n ret i32 0 }"]; + Node0x557d0cb73ac0 -> Node0x557d0cb51320[style=solid]; + Node0x557d0cb51320 [shape=record,color=green,label="{FunExitICFGNode21 \{fun: main\}\nPhiStmt: [Var18 \<-- ([Var32, ICFGNode20],)] \n ret i32 0 }"]; +} diff --git a/Assignment-2/testcase/src/test3.c b/Assignment-2/testcase/src/test3.c new file mode 100644 index 0000000..7c94a83 --- /dev/null +++ b/Assignment-2/testcase/src/test3.c @@ -0,0 +1,16 @@ +#include +extern int source(); +extern void sink(int s); +int bar(int s){ + return s; +} +void foo(int* p) { + *p = 1; +} + +int main() { + int a = source(); + foo(&a); + foo(&a); + sink(a); +} \ No newline at end of file