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 {
test1_positive(char * I,char * E)18 int32_t test1_positive(char *I, char *E) {
19 return (E - I); // expected-warning {{implicit conversion loses integer precision}}
20 }
21
test1_negative(char * I,char * E)22 int32_t test1_negative(char *I, char *E) {
23 return static_cast<int32_t>(E - I);
24 }
25
test2_positive(uint64_t x)26 uint32_t test2_positive(uint64_t x) {
27 return x; // expected-warning {{implicit conversion loses integer precision}}
28 }
29
test2_negative(uint64_t x)30 uint32_t test2_negative(uint64_t x) {
31 return (uint32_t) x;
32 }
33 }
34
35 namespace test1 {
test1(int x,unsigned y)36 uint64_t test1(int x, unsigned y) {
37 return sizeof(x == y);
38 }
39
test2(int x,unsigned y)40 uint64_t test2(int x, unsigned y) {
41 return __alignof(x == y);
42 }
43
44 void * const foo();
test2(void * p)45 bool test2(void *p) {
46 return p == foo();
47 }
48 }
49
50 namespace test2 {
51 struct A {
52 unsigned int x : 2;
Atest2::A53 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
test3()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>
tmpl(char c=NULL,T a=NULL,T b=1024)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>
tmpl2(T t=NULL)126 void tmpl2(T t = NULL) {
127 }
128
func()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>
func()140 void func() {
141 bool b = I;
142 }
143
144 template void func<3>();
145 }
146
147 namespace test6 {
func()148 decltype(nullptr) func() {
149 return NULL;
150 }
151 }
152
153 namespace test7 {
fun()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