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   int *ip = NULL;
     94   int (*fp)() = NULL;
     95   struct foo {
     96     int n;
     97     void func();
     98   };
     99   int foo::*datamem = NULL;
    100   int (foo::*funmem)() = NULL;
    101 }
    102 
    103 namespace test4 {
    104   // FIXME: We should warn for non-dependent args (only when the param type is also non-dependent) only once
    105   // not once for the template + once for every instantiation
    106   template<typename T>
    107   void tmpl(char c = NULL, // expected-warning 4 {{implicit conversion of NULL constant to 'char'}}
    108             T a = NULL, // expected-warning {{implicit conversion of NULL constant to 'char'}} \
    109                            expected-warning 2 {{implicit conversion of NULL constant to 'int'}}
    110             T b = 1024) { // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1024 to 0}}
    111   }
    112 
    113   template<typename T>
    114   void tmpl2(T t = NULL) {
    115   }
    116 
    117   void func() {
    118     tmpl<char>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<char>' required here}}
    119     tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}}
    120     // FIXME: We should warn only once for each template instantiation - not once for each call
    121     tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}}
    122     tmpl2<int*>();
    123   }
    124 }
    125 
    126 namespace test5 {
    127   template<int I>
    128   void func() {
    129     bool b = I;
    130   }
    131 
    132   template void func<3>();
    133 }
    134 
    135 namespace test6 {
    136   decltype(nullptr) func() {
    137     return NULL;
    138   }
    139 }
    140