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 { 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 35 namespace 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 } 49 50 namespace test2 { 51 struct A { 52 unsigned int x : 2; 53 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 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> 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> 104 void tmpl2(T t = NULL) { 105 } 106 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> 117 void func() { 118 bool b = I; 119 } 120 121 template void func<3>(); 122 } 123 124 namespace test6 { 125 decltype(nullptr) func() { 126 return NULL; 127 } 128 } 129 130 namespace 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 } 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 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 } 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 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 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 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 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 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); 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; 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); 296 void function4() { 297 conditional_run_13(nullptr); 298 conditional_run_13(NULL); 299 } 300 } 301