xref: /llvm-project/clang/test/Analysis/cxx2b-deducing-this.cpp (revision d4687fe7d1639ea5d16190c89a54de1f2c6e2a9a)
1 // RUN: %clang_analyze_cc1 -std=c++2b -verify %s \
2 // RUN:   -analyzer-checker=core,debug.ExprInspection
3 
4 template <typename T> void clang_analyzer_dump(T);
5 
6 struct S {
7   int num;
8   S *orig;
9 
aS10   void a(this auto Self) {
11     clang_analyzer_dump(&Self);     // expected-warning {{&Self}}
12     clang_analyzer_dump(Self.orig); // expected-warning {{&s}}
13     clang_analyzer_dump(Self.num);       // expected-warning {{5 S32b}}
14     clang_analyzer_dump(Self.orig->num); // expected-warning {{5 S32b}}
15 
16     Self.num = 1;
17     clang_analyzer_dump(Self.num);       // expected-warning {{1 S32b}}
18     clang_analyzer_dump(Self.orig->num); // expected-warning {{5 S32b}}
19   }
20 
bS21   void b(this auto& Self) {
22     clang_analyzer_dump(&Self);     // expected-warning {{&s}}
23     clang_analyzer_dump(Self.orig); // expected-warning {{&s}}
24     clang_analyzer_dump(Self.num);       // expected-warning {{5 S32b}}
25     clang_analyzer_dump(Self.orig->num); // expected-warning {{5 S32b}}
26 
27     Self.num = 2;
28     clang_analyzer_dump(Self.num);       // expected-warning {{2 S32b}}
29     clang_analyzer_dump(Self.orig->num); // expected-warning {{2 S32b}}
30   }
31 
cS32   void c(this S Self) {
33     clang_analyzer_dump(&Self);     // expected-warning {{&Self}}
34     clang_analyzer_dump(Self.orig); // expected-warning {{&s}}
35     clang_analyzer_dump(Self.num);       // expected-warning {{2 S32b}}
36     clang_analyzer_dump(Self.orig->num); // expected-warning {{2 S32b}}
37 
38     Self.num = 3;
39     clang_analyzer_dump(Self.num);       // expected-warning {{3 S32b}}
40     clang_analyzer_dump(Self.orig->num); // expected-warning {{2 S32b}}
41   }
42 
cS43   void c(this S Self, int I) {
44     clang_analyzer_dump(I); // expected-warning {{11 S32b}}
45     clang_analyzer_dump(&Self);     // expected-warning {{&Self}}
46     clang_analyzer_dump(Self.orig); // expected-warning {{&s}}
47     clang_analyzer_dump(Self.num);       // expected-warning {{2 S32b}}
48     clang_analyzer_dump(Self.orig->num); // expected-warning {{2 S32b}}
49 
50     Self.num = 4;
51     clang_analyzer_dump(Self.num);       // expected-warning {{4 S32b}}
52     clang_analyzer_dump(Self.orig->num); // expected-warning {{2 S32b}}
53   }
54 };
55 
top()56 void top() {
57   S s = {/*num=*/5, /*orig=*/&s};
58   s.a();
59   s.b(); // This call changes 's.num' to 2.
60   s.c();
61   s.c(11);
62 }
63 
64 
65 struct S2 {
operator ==S266   bool operator==(this auto, S2) {
67     return true;
68   }
69 };
use_deducing_this()70 void use_deducing_this() {
71   int result = S2{} == S2{}; // no-crash
72   clang_analyzer_dump(result); // expected-warning {{1 S32b}}
73 }
74