Skip to content

Commit 9726428

Browse files
C++: More SSA test cases
1 parent eed0894 commit 9726428

File tree

3 files changed

+432
-1
lines changed

3 files changed

+432
-1
lines changed

cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,3 +510,202 @@ ssa.cpp:
510510
# 122| v3_11(void) = ReturnVoid :
511511
# 122| v3_12(void) = UnmodeledUse : mu*
512512
# 122| v3_13(void) = ExitFunction :
513+
514+
# 134| void MergeMustExactlyWithMustTotallyOverlap(bool, Point, int)
515+
# 134| Block 0
516+
# 134| v0_0(void) = EnterFunction :
517+
# 134| m0_1(unknown) = AliasedDefinition :
518+
# 134| mu0_2(unknown) = UnmodeledDefinition :
519+
# 134| r0_3(glval<bool>) = VariableAddress[c] :
520+
# 134| m0_4(bool) = InitializeParameter[c] : &:r0_3
521+
# 134| r0_5(glval<Point>) = VariableAddress[p] :
522+
# 134| m0_6(Point) = InitializeParameter[p] : &:r0_5
523+
# 134| r0_7(glval<int>) = VariableAddress[x1] :
524+
# 134| m0_8(int) = InitializeParameter[x1] : &:r0_7
525+
# 135| r0_9(glval<Point>) = VariableAddress[a] :
526+
# 135| m0_10(Point) = Uninitialized[a] : &:r0_9
527+
# 135| r0_11(glval<int>) = FieldAddress[x] : r0_9
528+
# 135| r0_12(int) = Constant[0] :
529+
# 135| m0_13(int) = Store : &:r0_11, r0_12
530+
# 135| m0_14(Point) = Chi : total:m0_10, partial:m0_13
531+
# 135| r0_15(glval<int>) = FieldAddress[y] : r0_9
532+
# 135| r0_16(int) = Constant[0] :
533+
# 135| m0_17(int) = Store : &:r0_15, r0_16
534+
# 135| m0_18(Point) = Chi : total:m0_14, partial:m0_17
535+
# 136| r0_19(glval<bool>) = VariableAddress[c] :
536+
# 136| r0_20(bool) = Load : &:r0_19, m0_4
537+
# 136| v0_21(void) = ConditionalBranch : r0_20
538+
#-----| False -> Block 2
539+
#-----| True -> Block 1
540+
541+
# 137| Block 1
542+
# 137| r1_0(glval<int>) = VariableAddress[x1] :
543+
# 137| r1_1(int) = Load : &:r1_0, m0_8
544+
# 137| r1_2(glval<Point>) = VariableAddress[a] :
545+
# 137| r1_3(glval<int>) = FieldAddress[x] : r1_2
546+
# 137| m1_4(int) = Store : &:r1_3, r1_1
547+
# 137| m1_5(Point) = Chi : total:m0_18, partial:m1_4
548+
#-----| Goto -> Block 3
549+
550+
# 140| Block 2
551+
# 140| r2_0(glval<Point>) = VariableAddress[p] :
552+
# 140| r2_1(Point) = Load : &:r2_0, m0_6
553+
# 140| r2_2(glval<Point>) = VariableAddress[a] :
554+
# 140| m2_3(Point) = Store : &:r2_2, r2_1
555+
#-----| Goto -> Block 3
556+
557+
# 142| Block 3
558+
# 142| m3_0(Point) = Phi : from 1:m1_5, from 2:m2_3
559+
# 142| r3_1(glval<int>) = VariableAddress[x] :
560+
# 142| r3_2(glval<Point>) = VariableAddress[a] :
561+
# 142| r3_3(glval<int>) = FieldAddress[x] : r3_2
562+
# 142| r3_4(int) = Load : &:r3_3, m3_0
563+
# 142| m3_5(int) = Store : &:r3_1, r3_4
564+
# 143| v3_6(void) = NoOp :
565+
# 134| v3_7(void) = ReturnVoid :
566+
# 134| v3_8(void) = UnmodeledUse : mu*
567+
# 134| v3_9(void) = ExitFunction :
568+
569+
# 145| void MergeMustExactlyWithMayPartiallyOverlap(bool, Point, int)
570+
# 145| Block 0
571+
# 145| v0_0(void) = EnterFunction :
572+
# 145| m0_1(unknown) = AliasedDefinition :
573+
# 145| mu0_2(unknown) = UnmodeledDefinition :
574+
# 145| r0_3(glval<bool>) = VariableAddress[c] :
575+
# 145| m0_4(bool) = InitializeParameter[c] : &:r0_3
576+
# 145| r0_5(glval<Point>) = VariableAddress[p] :
577+
# 145| m0_6(Point) = InitializeParameter[p] : &:r0_5
578+
# 145| r0_7(glval<int>) = VariableAddress[x1] :
579+
# 145| m0_8(int) = InitializeParameter[x1] : &:r0_7
580+
# 146| r0_9(glval<Point>) = VariableAddress[a] :
581+
# 146| m0_10(Point) = Uninitialized[a] : &:r0_9
582+
# 146| r0_11(glval<int>) = FieldAddress[x] : r0_9
583+
# 146| r0_12(int) = Constant[0] :
584+
# 146| m0_13(int) = Store : &:r0_11, r0_12
585+
# 146| m0_14(Point) = Chi : total:m0_10, partial:m0_13
586+
# 146| r0_15(glval<int>) = FieldAddress[y] : r0_9
587+
# 146| r0_16(int) = Constant[0] :
588+
# 146| m0_17(int) = Store : &:r0_15, r0_16
589+
# 146| m0_18(Point) = Chi : total:m0_14, partial:m0_17
590+
# 147| r0_19(glval<bool>) = VariableAddress[c] :
591+
# 147| r0_20(bool) = Load : &:r0_19, m0_4
592+
# 147| v0_21(void) = ConditionalBranch : r0_20
593+
#-----| False -> Block 2
594+
#-----| True -> Block 1
595+
596+
# 148| Block 1
597+
# 148| r1_0(glval<int>) = VariableAddress[x1] :
598+
# 148| r1_1(int) = Load : &:r1_0, m0_8
599+
# 148| r1_2(glval<Point>) = VariableAddress[a] :
600+
# 148| r1_3(glval<int>) = FieldAddress[x] : r1_2
601+
# 148| m1_4(int) = Store : &:r1_3, r1_1
602+
# 148| m1_5(Point) = Chi : total:m0_18, partial:m1_4
603+
#-----| Goto -> Block 3
604+
605+
# 151| Block 2
606+
# 151| r2_0(glval<Point>) = VariableAddress[p] :
607+
# 151| r2_1(Point) = Load : &:r2_0, m0_6
608+
# 151| r2_2(glval<Point>) = VariableAddress[a] :
609+
# 151| m2_3(Point) = Store : &:r2_2, r2_1
610+
#-----| Goto -> Block 3
611+
612+
# 153| Block 3
613+
# 153| m3_0(Point) = Phi : from 1:m1_5, from 2:m2_3
614+
# 153| r3_1(glval<Point>) = VariableAddress[b] :
615+
# 153| r3_2(glval<Point>) = VariableAddress[a] :
616+
# 153| r3_3(Point) = Load : &:r3_2, m3_0
617+
# 153| m3_4(Point) = Store : &:r3_1, r3_3
618+
# 154| v3_5(void) = NoOp :
619+
# 145| v3_6(void) = ReturnVoid :
620+
# 145| v3_7(void) = UnmodeledUse : mu*
621+
# 145| v3_8(void) = ExitFunction :
622+
623+
# 156| void MergeMustTotallyOverlapWithMayPartiallyOverlap(bool, Rect, int)
624+
# 156| Block 0
625+
# 156| v0_0(void) = EnterFunction :
626+
# 156| m0_1(unknown) = AliasedDefinition :
627+
# 156| mu0_2(unknown) = UnmodeledDefinition :
628+
# 156| r0_3(glval<bool>) = VariableAddress[c] :
629+
# 156| m0_4(bool) = InitializeParameter[c] : &:r0_3
630+
# 156| r0_5(glval<Rect>) = VariableAddress[r] :
631+
# 156| m0_6(Rect) = InitializeParameter[r] : &:r0_5
632+
# 156| r0_7(glval<int>) = VariableAddress[x1] :
633+
# 156| m0_8(int) = InitializeParameter[x1] : &:r0_7
634+
# 157| r0_9(glval<Rect>) = VariableAddress[a] :
635+
# 157| m0_10(Rect) = Uninitialized[a] : &:r0_9
636+
# 157| r0_11(glval<Point>) = FieldAddress[topLeft] : r0_9
637+
# 157| r0_12(Point) = Constant[0] :
638+
# 157| m0_13(Point) = Store : &:r0_11, r0_12
639+
# 157| m0_14(Rect) = Chi : total:m0_10, partial:m0_13
640+
# 157| r0_15(glval<Point>) = FieldAddress[bottomRight] : r0_9
641+
# 157| r0_16(Point) = Constant[0] :
642+
# 157| m0_17(Point) = Store : &:r0_15, r0_16
643+
# 157| m0_18(Rect) = Chi : total:m0_14, partial:m0_17
644+
# 158| r0_19(glval<bool>) = VariableAddress[c] :
645+
# 158| r0_20(bool) = Load : &:r0_19, m0_4
646+
# 158| v0_21(void) = ConditionalBranch : r0_20
647+
#-----| False -> Block 2
648+
#-----| True -> Block 1
649+
650+
# 159| Block 1
651+
# 159| r1_0(glval<int>) = VariableAddress[x1] :
652+
# 159| r1_1(int) = Load : &:r1_0, m0_8
653+
# 159| r1_2(glval<Rect>) = VariableAddress[a] :
654+
# 159| r1_3(glval<Point>) = FieldAddress[topLeft] : r1_2
655+
# 159| r1_4(glval<int>) = FieldAddress[x] : r1_3
656+
# 159| m1_5(int) = Store : &:r1_4, r1_1
657+
# 159| m1_6(Rect) = Chi : total:m0_18, partial:m1_5
658+
#-----| Goto -> Block 3
659+
660+
# 162| Block 2
661+
# 162| r2_0(glval<Rect>) = VariableAddress[r] :
662+
# 162| r2_1(Rect) = Load : &:r2_0, m0_6
663+
# 162| r2_2(glval<Rect>) = VariableAddress[a] :
664+
# 162| m2_3(Rect) = Store : &:r2_2, r2_1
665+
#-----| Goto -> Block 3
666+
667+
# 164| Block 3
668+
# 164| m3_0(Rect) = Phi : from 1:m1_6, from 2:m2_3
669+
# 164| r3_1(glval<Point>) = VariableAddress[b] :
670+
# 164| r3_2(glval<Rect>) = VariableAddress[a] :
671+
# 164| r3_3(glval<Point>) = FieldAddress[topLeft] : r3_2
672+
# 164| r3_4(Point) = Load : &:r3_3, m3_0
673+
# 164| m3_5(Point) = Store : &:r3_1, r3_4
674+
# 165| v3_6(void) = NoOp :
675+
# 156| v3_7(void) = ReturnVoid :
676+
# 156| v3_8(void) = UnmodeledUse : mu*
677+
# 156| v3_9(void) = ExitFunction :
678+
679+
# 171| void WrapperStruct(Wrapper)
680+
# 171| Block 0
681+
# 171| v0_0(void) = EnterFunction :
682+
# 171| m0_1(unknown) = AliasedDefinition :
683+
# 171| mu0_2(unknown) = UnmodeledDefinition :
684+
# 171| r0_3(glval<Wrapper>) = VariableAddress[w] :
685+
# 171| m0_4(Wrapper) = InitializeParameter[w] : &:r0_3
686+
# 172| r0_5(glval<Wrapper>) = VariableAddress[x] :
687+
# 172| r0_6(glval<Wrapper>) = VariableAddress[w] :
688+
# 172| r0_7(Wrapper) = Load : &:r0_6, m0_4
689+
# 172| m0_8(Wrapper) = Store : &:r0_5, r0_7
690+
# 173| r0_9(glval<int>) = VariableAddress[a] :
691+
# 173| r0_10(glval<Wrapper>) = VariableAddress[w] :
692+
# 173| r0_11(glval<int>) = FieldAddress[f] : r0_10
693+
# 173| r0_12(int) = Load : &:r0_11, m0_4
694+
# 173| m0_13(int) = Store : &:r0_9, r0_12
695+
# 174| r0_14(int) = Constant[5] :
696+
# 174| r0_15(glval<Wrapper>) = VariableAddress[w] :
697+
# 174| r0_16(glval<int>) = FieldAddress[f] : r0_15
698+
# 174| m0_17(int) = Store : &:r0_16, r0_14
699+
# 175| r0_18(glval<Wrapper>) = VariableAddress[w] :
700+
# 175| r0_19(glval<int>) = FieldAddress[f] : r0_18
701+
# 175| r0_20(int) = Load : &:r0_19, m0_17
702+
# 175| r0_21(glval<int>) = VariableAddress[a] :
703+
# 175| m0_22(int) = Store : &:r0_21, r0_20
704+
# 176| r0_23(glval<Wrapper>) = VariableAddress[w] :
705+
# 176| r0_24(Wrapper) = Load : &:r0_23, m0_17
706+
# 176| r0_25(glval<Wrapper>) = VariableAddress[x] :
707+
# 176| m0_26(Wrapper) = Store : &:r0_25, r0_24
708+
# 177| v0_27(void) = NoOp :
709+
# 171| v0_28(void) = ReturnVoid :
710+
# 171| v0_29(void) = UnmodeledUse : mu*
711+
# 171| v0_30(void) = ExitFunction :

cpp/ql/test/library-tests/ir/ssa/ssa.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,51 @@ void MergeMustExactlyOverlap(bool c, int x1, int x2) {
127127
else {
128128
a.x = x2;
129129
}
130-
int x = a.x;
130+
int x = a.x; // Both reaching defs must exactly overlap.
131131
Point b = a;
132132
}
133+
134+
void MergeMustExactlyWithMustTotallyOverlap(bool c, Point p, int x1) {
135+
Point a = {};
136+
if (c) {
137+
a.x = x1;
138+
}
139+
else {
140+
a = p;
141+
}
142+
int x = a.x; // Only one reaching def must exactly overlap, but we should still get a Phi for it.
143+
}
144+
145+
void MergeMustExactlyWithMayPartiallyOverlap(bool c, Point p, int x1) {
146+
Point a = {};
147+
if (c) {
148+
a.x = x1;
149+
}
150+
else {
151+
a = p;
152+
}
153+
Point b = a; // Only one reaching def must exactly overlap, but we should still get a Phi for it.
154+
}
155+
156+
void MergeMustTotallyOverlapWithMayPartiallyOverlap(bool c, Rect r, int x1) {
157+
Rect a = {};
158+
if (c) {
159+
a.topLeft.x = x1;
160+
}
161+
else {
162+
a = r;
163+
}
164+
Point b = a.topLeft; // Neither reaching def must exactly overlap, so we'll just get a Phi of the virtual variable.
165+
}
166+
167+
struct Wrapper {
168+
int f;
169+
};
170+
171+
void WrapperStruct(Wrapper w) {
172+
Wrapper x = w; // MustExactlyOverlap
173+
int a = w.f; // MustTotallyOverlap, because the types don't match
174+
w.f = 5;
175+
a = w.f; // MustExactlyOverlap
176+
x = w; // MustTotallyOverlap
177+
}

0 commit comments

Comments
 (0)