• 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   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>
tmpl(char c=NULL,T a=NULL,T b=1024)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>
tmpl2(T t=NULL)114   void tmpl2(T t = NULL) {
115   }
116 
func()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>
func()128   void func() {
129     bool b = I;
130   }
131 
132   template void func<3>();
133 }
134 
135 namespace test6 {
func()136   decltype(nullptr) func() {
137     return NULL;
138   }
139 }
140