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