blob: dcd64fa2ec8aeaa0ce986864b098ffdd9691b0d8 [file] [log] [blame]
David Blaikiebcd4b552013-02-16 00:56:22 +00001// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -std=c++11 -verify %s
2// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -std=c++11 %s 2>&1 | FileCheck %s
John McCalla15eb732010-07-13 06:26:23 +00003
Richard Trieubeaf3452011-05-29 19:59:02 +00004#include <stddef.h>
5
John McCalla15eb732010-07-13 06:26:23 +00006typedef signed char int8_t;
7typedef signed short int16_t;
8typedef signed int int32_t;
9typedef signed long int64_t;
10
11typedef unsigned char uint8_t;
12typedef unsigned short uint16_t;
13typedef unsigned int uint32_t;
14typedef unsigned long uint64_t;
15
16// <rdar://problem/7909130>
17namespace test0 {
18 int32_t test1_positive(char *I, char *E) {
19 return (E - I); // expected-warning {{implicit conversion loses integer precision}}
20 }
21
22 int32_t test1_negative(char *I, char *E) {
23 return static_cast<int32_t>(E - I);
24 }
25
26 uint32_t test2_positive(uint64_t x) {
27 return x; // expected-warning {{implicit conversion loses integer precision}}
28 }
29
30 uint32_t test2_negative(uint64_t x) {
31 return (uint32_t) x;
32 }
33}
34
35namespace test1 {
36 uint64_t test1(int x, unsigned y) {
37 return sizeof(x == y);
38 }
39
40 uint64_t test2(int x, unsigned y) {
41 return __alignof(x == y);
42 }
43
44 void * const foo();
45 bool test2(void *p) {
46 return p == foo();
47 }
48}
John McCall1f425642010-11-11 03:21:53 +000049
50namespace test2 {
51 struct A {
52 unsigned int x : 2;
Chandler Carruthcbe1eba2016-12-20 02:43:58 +000053 A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bit-field changes value from 10 to 2}}
John McCall1f425642010-11-11 03:21:53 +000054 };
55}
Richard Trieubeaf3452011-05-29 19:59:02 +000056
David Blaikieebcbe4b2012-03-15 04:50:32 +000057// This file tests -Wnull-conversion, a subcategory of -Wconversion
58// which is on by default.
59
Richard Trieubeaf3452011-05-29 19:59:02 +000060void test3() {
David Blaikiee7fd5802012-03-15 20:48:26 +000061 int a = NULL; // expected-warning {{implicit conversion of NULL constant to 'int'}}
Richard Trieubeaf3452011-05-29 19:59:02 +000062 int b;
David Blaikiee7fd5802012-03-15 20:48:26 +000063 b = NULL; // expected-warning {{implicit conversion of NULL constant to 'int'}}
David Blaikieebcbe4b2012-03-15 04:50:32 +000064 long l = NULL; // FIXME: this should also warn, but currently does not if sizeof(NULL)==sizeof(inttype)
David Blaikiee7fd5802012-03-15 20:48:26 +000065 int c = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
Richard Trieubeaf3452011-05-29 19:59:02 +000066 int d;
David Blaikiee7fd5802012-03-15 20:48:26 +000067 d = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
David Blaikie7555b6a2012-05-15 16:56:36 +000068 bool bl = NULL; // expected-warning {{implicit conversion of NULL constant to 'bool'}}
David Blaikiee7fd5802012-03-15 20:48:26 +000069 char ch = NULL; // expected-warning {{implicit conversion of NULL constant to 'char'}}
70 unsigned char uch = NULL; // expected-warning {{implicit conversion of NULL constant to 'unsigned char'}}
71 short sh = NULL; // expected-warning {{implicit conversion of NULL constant to 'short'}}
David Blaikie9366d2b2012-06-19 21:19:06 +000072 double dbl = NULL; // expected-warning {{implicit conversion of NULL constant to 'double'}}
David Blaikieae12b182012-03-16 20:30:12 +000073
74 // Use FileCheck to ensure we don't get any unnecessary macro-expansion notes
75 // (that don't appear as 'real' notes & can't be seen/tested by -verify)
76 // CHECK-NOT: note:
David Blaikieae12b182012-03-16 20:30:12 +000077 // CHECK: note: expanded from macro 'FINIT'
78#define FINIT int a3 = NULL;
79 FINIT // expected-warning {{implicit conversion of NULL constant to 'int'}}
Richard Trieu43b4c822016-01-06 21:11:18 +000080 // we don't catch the case of #define FOO NULL ... int i = FOO; but that
81 // seems a bit narrow anyway and avoiding that helps us skip other cases.
Richard Trieu5b993502014-10-15 03:42:06 +000082
David Blaikie8cf439f2012-06-21 18:51:10 +000083 int *ip = NULL;
84 int (*fp)() = NULL;
85 struct foo {
86 int n;
87 void func();
88 };
89 int foo::*datamem = NULL;
90 int (foo::*funmem)() = NULL;
Richard Trieubeaf3452011-05-29 19:59:02 +000091}
David Blaikief68e8092012-04-30 18:21:31 +000092
93namespace test4 {
David Blaikie7afed5e2012-05-01 06:05:57 +000094 // FIXME: We should warn for non-dependent args (only when the param type is also non-dependent) only once
95 // not once for the template + once for every instantiation
David Blaikief68e8092012-04-30 18:21:31 +000096 template<typename T>
John McCall32791cc2016-01-06 22:34:54 +000097 void tmpl(char c = NULL, // expected-warning 3 {{implicit conversion of NULL constant to 'char'}}
David Blaikief68e8092012-04-30 18:21:31 +000098 T a = NULL, // expected-warning {{implicit conversion of NULL constant to 'char'}} \
John McCall32791cc2016-01-06 22:34:54 +000099 expected-warning {{implicit conversion of NULL constant to 'int'}}
David Blaikief68e8092012-04-30 18:21:31 +0000100 T b = 1024) { // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1024 to 0}}
101 }
102
103 template<typename T>
104 void tmpl2(T t = NULL) {
105 }
106
107 void func() {
David Blaikie7afed5e2012-05-01 06:05:57 +0000108 tmpl<char>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<char>' required here}}
109 tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}}
John McCall32791cc2016-01-06 22:34:54 +0000110 tmpl<int>();
David Blaikief68e8092012-04-30 18:21:31 +0000111 tmpl2<int*>();
112 }
113}
David Blaikie7555b6a2012-05-15 16:56:36 +0000114
115namespace test5 {
116 template<int I>
117 void func() {
118 bool b = I;
119 }
120
121 template void func<3>();
122}
David Blaikiebcd4b552013-02-16 00:56:22 +0000123
124namespace test6 {
125 decltype(nullptr) func() {
126 return NULL;
127 }
128}
Richard Trieu5b993502014-10-15 03:42:06 +0000129
130namespace test7 {
131 bool fun() {
132 bool x = nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
133 if (nullptr) {} // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
134 return nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
135 }
136}
Richard Trieu43b4c822016-01-06 21:11:18 +0000137
138namespace test8 {
139 #define NULL_COND(cond) ((cond) ? &num : NULL)
140 #define NULL_WRAPPER NULL_COND(false)
141
142 // don't warn on NULL conversion through the conditional operator across a
143 // macro boundary
144 void macro() {
145 int num;
146 bool b = NULL_COND(true);
147 if (NULL_COND(true)) {}
148 while (NULL_COND(true)) {}
149 for (;NULL_COND(true);) {}
150 do {} while (NULL_COND(true));
151
152 if (NULL_WRAPPER) {}
153 while (NULL_WRAPPER) {}
154 for (;NULL_WRAPPER;) {}
155 do {} while (NULL_WRAPPER);
156 }
157
158 // Identical to the previous function except with a template argument.
159 // This ensures that template instantiation does not introduce any new
160 // warnings.
161 template <typename X>
162 void template_and_macro() {
163 int num;
164 bool b = NULL_COND(true);
165 if (NULL_COND(true)) {}
166 while (NULL_COND(true)) {}
167 for (;NULL_COND(true);) {}
168 do {} while (NULL_COND(true));
169
170 if (NULL_WRAPPER) {}
171 while (NULL_WRAPPER) {}
172 for (;NULL_WRAPPER;) {}
173 do {} while (NULL_WRAPPER);
174 }
175
176 // Identical to the previous function except the template argument affects
177 // the conditional statement.
178 template <typename X>
179 void template_and_macro2() {
180 X num;
181 bool b = NULL_COND(true);
182 if (NULL_COND(true)) {}
183 while (NULL_COND(true)) {}
184 for (;NULL_COND(true);) {}
185 do {} while (NULL_COND(true));
186
187 if (NULL_WRAPPER) {}
188 while (NULL_WRAPPER) {}
189 for (;NULL_WRAPPER;) {}
190 do {} while (NULL_WRAPPER);
191 }
192
193 void run() {
194 template_and_macro<int>();
195 template_and_macro<double>();
196 template_and_macro2<int>();
197 template_and_macro2<double>();
198 }
199}
Richard Trieu09d6b802016-01-08 23:35:06 +0000200
201// Don't warn on a nullptr to bool conversion when the nullptr is the return
202// type of a function.
203namespace test9 {
204 typedef decltype(nullptr) nullptr_t;
205 nullptr_t EXIT();
206
207 bool test() {
208 return EXIT();
209 }
210}
Richard Trieufc014f22016-01-09 01:10:17 +0000211
212// Test NULL macro inside a macro has same warnings nullptr inside a macro.
213namespace test10 {
214#define test1(cond) \
215 ((cond) ? nullptr : NULL)
216#define test2(cond) \
217 ((cond) ? NULL : nullptr)
218
219#define assert(cond) \
220 ((cond) ? foo() : bar())
221 void foo();
222 void bar();
223
224 void run(int x) {
225 if (test1(x)) {}
226 if (test2(x)) {}
227 assert(test1(x));
228 assert(test2(x));
229 }
230}
Richard Trieu3a5c9582016-01-26 02:51:55 +0000231
232namespace test11 {
233
234#define assert11(expr) ((expr) ? 0 : 0)
235
236// The whitespace in macro run1 are important to trigger the macro being split
237// over multiple SLocEntry's.
238#define run1() (dostuff() ? \
239 NULL : NULL)
240#define run2() (dostuff() ? NULL : NULL)
241int dostuff ();
242
243void test(const char * content_type) {
244 assert11(run1());
245 assert11(run2());
246}
247
248}
249
250namespace test12 {
251
252#define x return NULL;
253
254bool run() {
255 x // expected-warning{{}}
256}
257
258}
Richard Trieu0a5e1662016-02-13 00:58:53 +0000259
260// More tests with macros. Specficially, test function-like macros that either
261// have a pointer return type or take pointer arguments. Basically, if the
262// macro was changed into a function and Clang doesn't warn, then it shouldn't
263// warn for the macro either.
264namespace test13 {
265#define check_str_nullptr_13(str) ((str) ? str : nullptr)
266#define check_str_null_13(str) ((str) ? str : NULL)
267#define test13(condition) if (condition) return;
268#define identity13(arg) arg
269#define CHECK13(condition) test13(identity13(!(condition)))
270
271void function1(const char* str) {
272 CHECK13(check_str_nullptr_13(str));
273 CHECK13(check_str_null_13(str));
274}
275
276bool some_bool_function(bool);
277void function2() {
278 CHECK13(some_bool_function(nullptr)); // expected-warning{{implicit conversion of nullptr constant to 'bool'}}
279 CHECK13(some_bool_function(NULL)); // expected-warning{{implicit conversion of NULL constant to 'bool'}}
280}
281
282#define run_check_nullptr_13(str) \
283 if (check_str_nullptr_13(str)) return;
284#define run_check_null_13(str) \
285 if (check_str_null_13(str)) return;
286void function3(const char* str) {
287 run_check_nullptr_13(str)
288 run_check_null_13(str)
289 if (check_str_nullptr_13(str)) return;
290 if (check_str_null_13(str)) return;
291}
292
293void run(int* ptr);
294#define conditional_run_13(ptr) \
295 if (ptr) run(ptr);
296void function4() {
297 conditional_run_13(nullptr);
298 conditional_run_13(NULL);
299}
300}