[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / SemaCXX / conversion.cpp
blob67bfdf5532b5dc939f5b235d6d792c9522921212
1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -std=c++11 -verify %s
2 // RUN: not %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -std=c++11 %s 2>&1 | FileCheck %s
4 #include <stddef.h>
6 typedef signed char int8_t;
7 typedef signed short int16_t;
8 typedef signed int int32_t;
9 typedef signed long int64_t;
11 typedef unsigned char uint8_t;
12 typedef unsigned short uint16_t;
13 typedef unsigned int uint32_t;
14 typedef unsigned long uint64_t;
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}}
22 int32_t test1_negative(char *I, char *E) {
23 return static_cast<int32_t>(E - I);
26 uint32_t test2_positive(uint64_t x) {
27 return x; // expected-warning {{implicit conversion loses integer precision}}
30 uint32_t test2_negative(uint64_t x) {
31 return (uint32_t) x;
35 namespace test1 {
36 uint64_t test1(int x, unsigned y) {
37 return sizeof(x == y);
40 uint64_t test2(int x, unsigned y) {
41 return __alignof(x == y);
44 void * const foo();
45 bool test2(void *p) {
46 return p == foo();
50 namespace test2 {
51 struct A {
52 unsigned int x : 2;
53 A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bit-field changes value from 10 to 2}}
57 // This file tests -Wnull-conversion, a subcategory of -Wconversion
58 // which is on by default.
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'}}
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.
83 int *ip = NULL;
84 int (*fp)() = NULL;
85 struct foo {
86 int n;
87 void func();
89 int foo::*datamem = NULL;
90 int (foo::*funmem)() = NULL;
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}}
103 template<typename T>
104 void tmpl2(T t = NULL) {
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*>();
115 namespace test5 {
116 template<int I>
117 void func() {
118 bool b = I;
121 template void func<3>();
124 namespace test6 {
125 decltype(nullptr) func() {
126 return NULL;
130 namespace test7 {
131 bool fun() {
132 bool x = nullptr; // expected-error {{cannot initialize}}
133 if (nullptr) {} // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
134 return nullptr; // expected-error {{cannot initialize}}
138 namespace test8 {
139 #define NULL_COND(cond) ((cond) ? &num : NULL)
140 #define NULL_WRAPPER NULL_COND(false)
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));
152 if (NULL_WRAPPER) {}
153 while (NULL_WRAPPER) {}
154 for (;NULL_WRAPPER;) {}
155 do {} while (NULL_WRAPPER);
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));
170 if (NULL_WRAPPER) {}
171 while (NULL_WRAPPER) {}
172 for (;NULL_WRAPPER;) {}
173 do {} while (NULL_WRAPPER);
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));
187 if (NULL_WRAPPER) {}
188 while (NULL_WRAPPER) {}
189 for (;NULL_WRAPPER;) {}
190 do {} while (NULL_WRAPPER);
193 void run() {
194 template_and_macro<int>();
195 template_and_macro<double>();
196 template_and_macro2<int>();
197 template_and_macro2<double>();
201 namespace test9 {
202 typedef decltype(nullptr) nullptr_t;
203 nullptr_t EXIT();
205 bool test() {
206 return EXIT(); // expected-error {{cannot initialize}}
210 // Test NULL macro inside a macro has same warnings nullptr inside a macro.
211 namespace test10 {
212 #define test1(cond) \
213 ((cond) ? nullptr : NULL)
214 #define test2(cond) \
215 ((cond) ? NULL : nullptr)
217 #define assert(cond) \
218 ((cond) ? foo() : bar())
219 void foo();
220 void bar();
222 void run(int x) {
223 if (test1(x)) {}
224 if (test2(x)) {}
225 assert(test1(x));
226 assert(test2(x));
230 namespace test11 {
232 #define assert11(expr) ((expr) ? 0 : 0)
234 // The whitespace in macro run1 are important to trigger the macro being split
235 // over multiple SLocEntry's.
236 #define run1() (dostuff() ? \
237 NULL : NULL)
238 #define run2() (dostuff() ? NULL : NULL)
239 int dostuff ();
241 void test(const char * content_type) {
242 assert11(run1());
243 assert11(run2());
248 namespace test12 {
250 #define x return NULL;
252 bool run() {
253 x // expected-warning{{}}
258 // More tests with macros. Specficially, test function-like macros that either
259 // have a pointer return type or take pointer arguments. Basically, if the
260 // macro was changed into a function and Clang doesn't warn, then it shouldn't
261 // warn for the macro either.
262 namespace test13 {
263 #define check_str_nullptr_13(str) ((str) ? str : nullptr)
264 #define check_str_null_13(str) ((str) ? str : NULL)
265 #define test13(condition) if (condition) return;
266 #define identity13(arg) arg
267 #define CHECK13(condition) test13(identity13(!(condition)))
269 void function1(const char* str) {
270 CHECK13(check_str_nullptr_13(str));
271 CHECK13(check_str_null_13(str));
274 bool some_bool_function(bool); // expected-note {{no known conversion}}
275 void function2() {
276 CHECK13(some_bool_function(nullptr)); // expected-error {{no matching function}}
277 CHECK13(some_bool_function(NULL)); // expected-warning {{implicit conversion of NULL constant to 'bool'}}
280 #define run_check_nullptr_13(str) \
281 if (check_str_nullptr_13(str)) return;
282 #define run_check_null_13(str) \
283 if (check_str_null_13(str)) return;
284 void function3(const char* str) {
285 run_check_nullptr_13(str)
286 run_check_null_13(str)
287 if (check_str_nullptr_13(str)) return;
288 if (check_str_null_13(str)) return;
291 void run(int* ptr);
292 #define conditional_run_13(ptr) \
293 if (ptr) run(ptr);
294 void function4() {
295 conditional_run_13(nullptr);
296 conditional_run_13(NULL);