Home | History | Annotate | Download | only in SemaCXX
      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