• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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