• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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
3 
4 #include <stddef.h>
5 
6 typedef   signed char  int8_t;
7 typedef   signed short int16_t;
8 typedef   signed int   int32_t;
9 typedef   signed long  int64_t;
10 
11 typedef unsigned char  uint8_t;
12 typedef unsigned short uint16_t;
13 typedef unsigned int   uint32_t;
14 typedef unsigned long  uint64_t;
15 
16 // <rdar://problem/7909130>
17 namespace test0 {
test1_positive(char * I,char * E)18   int32_t test1_positive(char *I, char *E) {
19     return (E - I); // expected-warning {{implicit conversion loses integer precision}}
20   }
21 
test1_negative(char * I,char * E)22   int32_t test1_negative(char *I, char *E) {
23     return static_cast<int32_t>(E - I);
24   }
25 
test2_positive(uint64_t x)26   uint32_t test2_positive(uint64_t x) {
27     return x; // expected-warning {{implicit conversion loses integer precision}}
28   }
29 
test2_negative(uint64_t x)30   uint32_t test2_negative(uint64_t x) {
31     return (uint32_t) x;
32   }
33 }
34 
35 namespace test1 {
test1(int x,unsigned y)36   uint64_t test1(int x, unsigned y) {
37     return sizeof(x == y);
38   }
39 
test2(int x,unsigned y)40   uint64_t test2(int x, unsigned y) {
41     return __alignof(x == y);
42   }
43 
44   void * const foo();
test2(void * p)45   bool test2(void *p) {
46     return p == foo();
47   }
48 }
49 
50 namespace test2 {
51   struct A {
52     unsigned int x : 2;
Atest2::A53     A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to 2}}
54   };
55 }
56 
57 // This file tests -Wnull-conversion, a subcategory of -Wconversion
58 // which is on by default.
59 
test3()60 void test3() {
61   int a = NULL; // expected-warning {{implicit conversion of NULL constant to 'int'}}
62   int b;
63   b = NULL; // expected-warning {{implicit conversion of NULL constant to 'int'}}
64   long l = NULL; // FIXME: this should also warn, but currently does not if sizeof(NULL)==sizeof(inttype)
65   int c = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
66   int d;
67   d = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
68   bool bl = NULL; // expected-warning {{implicit conversion of NULL constant to 'bool'}}
69   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'}}
72   double dbl = NULL; // expected-warning {{implicit conversion of NULL constant to 'double'}}
73 
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:
77   // CHECK: note: expanded from macro 'FINIT'
78 #define FINIT int a3 = NULL;
79   FINIT // expected-warning {{implicit conversion of NULL constant to 'int'}}
80   // 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.
82 
83   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;
91 }
92 
93 namespace test4 {
94   // 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
96   template<typename T>
tmpl(char c=NULL,T a=NULL,T b=1024)97   void tmpl(char c = NULL, // expected-warning 3 {{implicit conversion of NULL constant to 'char'}}
98             T a = NULL, // expected-warning {{implicit conversion of NULL constant to 'char'}} \
99                            expected-warning {{implicit conversion of NULL constant to 'int'}}
100             T b = 1024) { // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1024 to 0}}
101   }
102 
103   template<typename T>
tmpl2(T t=NULL)104   void tmpl2(T t = NULL) {
105   }
106 
func()107   void func() {
108     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}}
110     tmpl<int>();
111     tmpl2<int*>();
112   }
113 }
114 
115 namespace test5 {
116   template<int I>
func()117   void func() {
118     bool b = I;
119   }
120 
121   template void func<3>();
122 }
123 
124 namespace test6 {
func()125   decltype(nullptr) func() {
126     return NULL;
127   }
128 }
129 
130 namespace test7 {
fun()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 }
137 
138 namespace 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
macro()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>
template_and_macro()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>
template_and_macro2()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 
run()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 }
200 
201 // Don't warn on a nullptr to bool conversion when the nullptr is the return
202 // type of a function.
203 namespace test9 {
204   typedef decltype(nullptr) nullptr_t;
205   nullptr_t EXIT();
206 
test()207   bool test() {
208     return EXIT();
209   }
210 }
211 
212 // Test NULL macro inside a macro has same warnings nullptr inside a macro.
213 namespace 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 
run(int x)224   void run(int x) {
225     if (test1(x)) {}
226     if (test2(x)) {}
227     assert(test1(x));
228     assert(test2(x));
229   }
230 }
231 
232 namespace 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)
241 int dostuff ();
242 
test(const char * content_type)243 void test(const char * content_type) {
244   assert11(run1());
245   assert11(run2());
246 }
247 
248 }
249 
250 namespace test12 {
251 
252 #define x return NULL;
253 
run()254 bool run() {
255   x  // expected-warning{{}}
256 }
257 
258 }
259 
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.
264 namespace 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 
function1(const char * str)271 void function1(const char* str) {
272   CHECK13(check_str_nullptr_13(str));
273   CHECK13(check_str_null_13(str));
274 }
275 
276 bool some_bool_function(bool);
function2()277 void 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;
function3(const char * str)286 void 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 
293 void run(int* ptr);
294 #define conditional_run_13(ptr) \
295     if (ptr) run(ptr);
function4()296 void function4() {
297   conditional_run_13(nullptr);
298   conditional_run_13(NULL);
299 }
300 }
301