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 
     81   // we don't catch the case of #define FOO NULL ... int i = FOO; but that seems a bit narrow anyway
     82   // and avoiding that helps us skip these cases:
     83 #define NULL_COND(cond) ((cond) ? &a : NULL)
     84   bool bl2 = NULL_COND(true); // don't warn on NULL conversion through the conditional operator across a macro boundary
     85   if (NULL_COND(true))
     86     ;
     87   while (NULL_COND(true))
     88     ;
     89   for (; NULL_COND(true); )
     90     ;
     91   do ;
     92   while(NULL_COND(true));
     93 
     94 #define NULL_WRAPPER NULL_COND(false)
     95   if (NULL_WRAPPER)
     96     ;
     97   while (NULL_WRAPPER)
     98     ;
     99   for (; NULL_WRAPPER;)
    100     ;
    101   do
    102     ;
    103   while (NULL_WRAPPER);
    104 
    105   int *ip = NULL;
    106   int (*fp)() = NULL;
    107   struct foo {
    108     int n;
    109     void func();
    110   };
    111   int foo::*datamem = NULL;
    112   int (foo::*funmem)() = NULL;
    113 }
    114 
    115 namespace test4 {
    116   // FIXME: We should warn for non-dependent args (only when the param type is also non-dependent) only once
    117   // not once for the template + once for every instantiation
    118   template<typename T>
    119   void tmpl(char c = NULL, // expected-warning 4 {{implicit conversion of NULL constant to 'char'}}
    120             T a = NULL, // expected-warning {{implicit conversion of NULL constant to 'char'}} \
    121                            expected-warning 2 {{implicit conversion of NULL constant to 'int'}}
    122             T b = 1024) { // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1024 to 0}}
    123   }
    124 
    125   template<typename T>
    126   void tmpl2(T t = NULL) {
    127   }
    128 
    129   void func() {
    130     tmpl<char>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<char>' required here}}
    131     tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}}
    132     // FIXME: We should warn only once for each template instantiation - not once for each call
    133     tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}}
    134     tmpl2<int*>();
    135   }
    136 }
    137 
    138 namespace test5 {
    139   template<int I>
    140   void func() {
    141     bool b = I;
    142   }
    143 
    144   template void func<3>();
    145 }
    146 
    147 namespace test6 {
    148   decltype(nullptr) func() {
    149     return NULL;
    150   }
    151 }
    152 
    153 namespace test7 {
    154   bool fun() {
    155     bool x = nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
    156     if (nullptr) {} // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
    157     return nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
    158   }
    159 }
    160