blob: e7819fff78ccfc9ff8fe2952d6388f1623b9cdd7 [file] [log] [blame]
Kristof Umann7d6d9eb2018-10-31 14:54:27 +00001// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
2//
3// RUN: %clang_analyze_cc1 -analyzer-checker=core %s \
4// RUN: -analyzer-output=plist -o %t.plist \
5// RUN: -analyzer-config expand-macros=true
6//
7// Check the actual plist output.
8// RUN: cat %t.plist | %diff_plist \
9// RUN: %S/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
10//
11// Check the macro expansions from the plist output here, to make the test more
12// understandable.
13// RUN: FileCheck --input-file=%t.plist %s
14
15void print(const void*);
16
17//===----------------------------------------------------------------------===//
18// Tests for non-function-like macro expansions.
19//===----------------------------------------------------------------------===//
20
21#define SET_PTR_VAR_TO_NULL \
22 ptr = 0
23
24void nonFunctionLikeMacroTest() {
25 int *ptr;
26 SET_PTR_VAR_TO_NULL;
27 *ptr = 5; // expected-warning{{Dereference of null pointer}}
28}
29
Kristof Umann38002572018-11-05 02:14:36 +000030// CHECK: <key>name</key><string>SET_PTR_VAR_TO_NULL</string>
31// CHECK-NEXT: <key>expansion</key><string>ptr = 0</string>
Kristof Umann7d6d9eb2018-10-31 14:54:27 +000032
33#define NULL 0
34#define SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO \
35 ptr = NULL
36
37void nonFunctionLikeNestedMacroTest() {
38 int *ptr;
39 SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO;
40 *ptr = 5; // expected-warning{{Dereference of null pointer}}
41}
42
Kristof Umann38002572018-11-05 02:14:36 +000043// CHECK: <key>name</key><string>SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO</string>
44// CHECK-NEXT: <key>expansion</key><string>ptr =0</string>
45
46//===----------------------------------------------------------------------===//
47// Tests for function-like macro expansions.
48//===----------------------------------------------------------------------===//
49
50void setToNull(int **vptr) {
51 *vptr = nullptr;
52}
53
54#define TO_NULL(x) \
55 setToNull(x)
56
57void functionLikeMacroTest() {
58 int *ptr;
59 TO_NULL(&ptr);
60 *ptr = 5; // expected-warning{{Dereference of null pointer}}
61}
62
63// TODO: Expand arguments.
64// CHECK: <key>name</key><string>TO_NULL</string>
65// CHECK: <key>expansion</key><string>setToNull(x)</string>
66
67#define DOES_NOTHING(x) \
68 { \
69 int b; \
70 b = 5; \
71 } \
72 print(x)
73
74#define DEREF(x) \
75 DOES_NOTHING(x); \
76 *x
77
78void functionLikeNestedMacroTest() {
79 int *a;
80 TO_NULL(&a);
81 DEREF(a) = 5; // expected-warning{{Dereference of null pointer}}
82}
83
84// TODO: Expand arguments.
85// CHECK: <key>name</key><string>TO_NULL</string>
86// CHECK-NEXT: <key>expansion</key><string>setToNull(x)</string>
87
88// TODO: Expand arguments.
89// CHECK: <key>name</key><string>DEREF</string>
90// CHECK-NEXT: <key>expansion</key><string>{ int b; b = 5; } print(x); *x</string>
91
92//===----------------------------------------------------------------------===//
93// Tests for undefining and/or redifining macros.
94//===----------------------------------------------------------------------===//
95
96#define WILL_UNDEF_SET_NULL_TO_PTR(ptr) \
97 ptr = nullptr;
98
99void undefinedMacroByTheEndOfParsingTest() {
100 int *ptr;
101 WILL_UNDEF_SET_NULL_TO_PTR(ptr);
102 *ptr = 5; // expected-warning{{Dereference of null pointer}}
103}
104
105#undef WILL_UNDEF_SET_NULL_TO_PTR
106
107// TODO: Expand arguments.
108// CHECK: <key>name</key><string>WILL_UNDEF_SET_NULL_TO_PTR</string>
109// CHECK-NEXT: <key>expansion</key><string>ptr = nullptr;</string>
110
111#define WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr) \
112 /* Nothing */
113#undef WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL
114#define WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr) \
115 ptr = nullptr;
116
117void macroRedefinedMultipleTimesTest() {
118 int *ptr;
119 WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr)
120 *ptr = 5; // expected-warning{{Dereference of null pointer}}
121}
122
123#undef WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL
124#define WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr) \
125 print("This string shouldn't be in the plist file at all. Or anywhere, " \
126 "but here.");
127
128// TODO: Expand arguments.
129// CHECK: <key>name</key><string>WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL</string>
130// CHECK-NEXT: <key>expansion</key><string>ptr = nullptr;</string>
131
132#define WILL_UNDEF_SET_NULL_TO_PTR_2(ptr) \
133 ptr = nullptr;
134
135#define PASS_PTR_TO_MACRO_THAT_WILL_BE_UNDEFD(ptr) \
136 WILL_UNDEF_SET_NULL_TO_PTR_2(ptr)
137
138void undefinedMacroInsideAnotherMacroTest() {
139 int *ptr;
140 PASS_PTR_TO_MACRO_THAT_WILL_BE_UNDEFD(ptr);
141 *ptr = 5; // expected-warning{{Dereference of null pointer}}
142}
143
144// TODO: Expand arguments.
145// CHECK: <key>name</key><string>PASS_PTR_TO_MACRO_THAT_WILL_BE_UNDEFD</string>
146// CHECK-NEXT: <key>expansion</key><string>ptr = nullptr;</string>
147
148#undef WILL_UNDEF_SET_NULL_TO_PTR_2