1+ struct Base {
2+ void f ();
3+ virtual void virtual_f ();
4+ };
5+
6+ struct Derived : Base {
7+ void f ();
8+ void virtual_f ();
9+ };
10+
11+ void test_simple () {
12+ Base b;
13+ b.f (); // $ target=2
14+ b.virtual_f (); // $ target=3
15+
16+ Derived d;
17+ d.f (); // $ target=7
18+ d.virtual_f (); // $ target=8
19+
20+ Base* b_ptr = &d;
21+ b_ptr->f (); // $ target=2
22+ b_ptr->virtual_f (); // $ target=8 SPURIOUS: target=3
23+
24+ Base& b_ref = d;
25+ b_ref.f (); // $ target=2
26+ b_ref.virtual_f (); // $ target=8 SPURIOUS: target=3
27+
28+ Base* b_null = nullptr ;
29+ b_null->f (); // $ target=2
30+ b_null->virtual_f (); // $ target=3
31+
32+ Base* base_is_derived = new Derived ();
33+ base_is_derived->f (); // $ target=2
34+ base_is_derived->virtual_f (); // $ target=8 SPURIOUS: target=3
35+
36+ Base* base_is_base = new Base ();
37+ base_is_base->f (); // $ target=2
38+ base_is_base->virtual_f (); // $ target=3
39+
40+ Derived* derived_is_derived = new Derived ();
41+ derived_is_derived->f (); // $ target=7
42+ derived_is_derived->virtual_f (); // $ target=8
43+
44+ Base& b_ref2 = b;
45+ b_ref2 = d;
46+ b_ref2.f (); // $ target=2
47+ b_ref2.virtual_f (); // $ target=3
48+ }
49+
50+ struct S {
51+ Base* b1;
52+ Base* b2;
53+ };
54+
55+ void test_fields () {
56+ S s;
57+
58+ s.b1 = new Base ();
59+ s.b2 = new Derived ();
60+
61+ s.b1 ->virtual_f (); // $ target=3
62+ s.b2 ->virtual_f (); // $ SPURIOUS: target=3 MISSING: target=8
63+
64+ s.b1 = new Derived ();
65+ s.b2 = new Base ();
66+ s.b1 ->virtual_f (); // $ MISSING: target=8 SPURIOUS: target=3 // type-tracking has no 'clearsContent' feature and C/C++ doesn't have field-based SSA
67+ s.b2 ->virtual_f (); // $ target=3 // type-tracking has no 'clearsContent' feature and C/C++ doesn't have field-based SSA
68+ }
69+
70+ Base* getDerived () {
71+ return new Derived ();
72+ }
73+
74+ void test_getDerived () {
75+ Base* b = getDerived ();
76+ b->virtual_f (); // $ target=8 SPURIOUS: target=3
77+
78+ Derived d = *(Derived*)getDerived ();
79+ d.virtual_f (); // $ target=8
80+ }
81+
82+ void write_to_arg (Base* b) {
83+ *b = Derived ();
84+ }
85+
86+ void write_to_arg_2 (Base** b) {
87+ Derived* d = new Derived ();
88+ *b = d;
89+ }
90+
91+ void test_write_to_arg () {
92+ {
93+ Base b;
94+ write_to_arg (&b);
95+ b.virtual_f (); // $ SPURIOUS: target=3 MISSING: target=8 // missing flow through the copy-constructor in write_to_arg
96+ }
97+
98+ {
99+ Base* b;
100+ write_to_arg_2 (&b);
101+ b->virtual_f (); // $ target=8 SPURIOUS: target=3
102+ }
103+ }
104+
105+ Base* global_derived;
106+
107+ void set_global_to_derived () {
108+ global_derived = new Derived ();
109+ }
110+
111+ void read_global () {
112+ global_derived->virtual_f (); // $ target=8 SPURIOUS: target=3
113+ }
114+
115+ Base* global_base_or_derived;
116+
117+ void set_global_base_or_derived_1 () {
118+ global_base_or_derived = new Base ();
119+ }
120+
121+ void set_global_base_or_derived_2 () {
122+ global_base_or_derived = new Derived ();
123+ }
124+
125+ void read_global_base_or_derived () {
126+ global_base_or_derived->virtual_f (); // $ target=3 target=8
127+ }
0 commit comments