Clang Project

clang_source_code/test/SemaCXX/warn-bool-conversion.cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s
2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
4
5namespace BooleanFalse {
6int* j = false;
7#if __cplusplus <= 199711L
8// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
9#else
10// expected-error@-4 {{cannot initialize a variable of type 'int *' with an rvalue of type 'bool'}}
11#endif
12
13#if __cplusplus <= 199711L
14// expected-warning@+6 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
15#else
16// expected-error@+4 {{cannot initialize a parameter of type 'int *' with an rvalue of type 'bool'}}
17// expected-note@+3 {{passing argument to parameter 'j' here}}
18// expected-note@+2 6 {{candidate function not viable: requires 2 arguments, but 1 was provided}}
19#endif
20void foo(int* i, int *j=(false))
21{
22  foo(false);
23#if __cplusplus <= 199711L
24// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
25#else
26// expected-error@-4 {{no matching function for call to 'foo'}}
27#endif
28
29  foo((int*)false);
30#if __cplusplus <= 199711L
31// no-warning: explicit cast
32#else
33// expected-error@-4 {{no matching function for call to 'foo'}}
34#endif
35
36  foo(0);
37#if __cplusplus <= 199711L
38// no-warning: not a bool, even though its convertible to bool
39#else
40// expected-error@-4 {{no matching function for call to 'foo'}}
41#endif
42
43  foo(false == true);
44#if __cplusplus <= 199711L
45// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
46#else
47// expected-error@-4 {{no matching function for call to 'foo'}}
48#endif
49
50  foo((42 + 24) < 32);
51#if __cplusplus <= 199711L
52// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
53#else
54// expected-error@-4 {{no matching function for call to 'foo'}}
55#endif
56
57  const bool kFlag = false;
58  foo(kFlag);
59#if __cplusplus <= 199711L
60// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}
61#else
62// expected-error@-4 {{no matching function for call to 'foo'}}
63#endif
64}
65
66char f(struct Undefined*);
67double f(...);
68
69// Ensure that when using false in metaprogramming machinery its conversion
70// isn't flagged.
71template <int N> struct S {};
72S<sizeof(f(false))> s;
73
74}
75
76namespace Function {
77void f1();
78
79struct S {
80  static void f2();
81};
82
83extern void f3() __attribute__((weak_import));
84
85struct S2 {
86  static void f4() __attribute__((weak_import));
87};
88
89bool f5();
90bool f6(int);
91
92void bar() {
93  bool b;
94
95  b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
96             expected-note {{prefix with the address-of operator to silence this warning}}
97  if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
98                expected-note {{prefix with the address-of operator to silence this warning}}
99  b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
100                expected-note {{prefix with the address-of operator to silence this warning}}
101  if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
102                   expected-note {{prefix with the address-of operator to silence this warning}}
103  b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
104             expected-note {{prefix with the address-of operator to silence this warning}} \
105             expected-note {{suffix with parentheses to turn this into a function call}}
106  b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
107             expected-note {{prefix with the address-of operator to silence this warning}}
108
109  // implicit casts of weakly imported symbols are ok:
110  b = f3;
111  if (f3) {}
112  b = S2::f4;
113  if (S2::f4) {}
114}
115}
116
117namespace Array {
118  #define GetValue(ptr)  ((ptr) ? ptr[0] : 0)
119  extern int a[] __attribute__((weak));
120  int b[] = {8,13,21};
121  struct {
122    int x[10];
123  } c;
124  const char str[] = "text";
125  void ignore() {
126    if (a) {}
127    if (a) {}
128    (void)GetValue(b);
129  }
130  void test() {
131    if (b) {}
132    // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
133    if (b) {}
134    // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
135    if (c.x) {}
136    // expected-warning@-1{{address of array 'c.x' will always evaluate to 'true'}}
137    if (str) {}
138    // expected-warning@-1{{address of array 'str' will always evaluate to 'true'}}
139  }
140}
141
142namespace Pointer {
143  extern int a __attribute__((weak));
144  int b;
145  static int c;
146  class S {
147  public:
148    static int a;
149    int b;
150  };
151  void ignored() {
152    if (&a) {}
153  }
154  void test() {
155    S s;
156    if (&b) {}
157    // expected-warning@-1{{address of 'b' will always evaluate to 'true'}}
158    if (&c) {}
159    // expected-warning@-1{{address of 'c' will always evaluate to 'true'}}
160    if (&s.a) {}
161    // expected-warning@-1{{address of 's.a' will always evaluate to 'true'}}
162    if (&s.b) {}
163    // expected-warning@-1{{address of 's.b' will always evaluate to 'true'}}
164    if (&S::a) {}
165    // expected-warning@-1{{address of 'S::a' will always evaluate to 'true'}}
166  }
167}
168
169namespace macros {
170  #define assert(x) if (x) {}
171  #define zero_on_null(x) ((x) ? *(x) : 0)
172
173  int array[5];
174  void fun();
175  int x;
176
177  void test() {
178    assert(array);
179    assert(array && "expecting null pointer");
180    // expected-warning@-1{{address of array 'array' will always evaluate to 'true'}}
181
182    assert(fun);
183    assert(fun && "expecting null pointer");
184    // expected-warning@-1{{address of function 'fun' will always evaluate to 'true'}}
185    // expected-note@-2 {{prefix with the address-of operator to silence this warning}}
186
187    // TODO: warn on assert(&x) while not warning on zero_on_null(&x)
188    zero_on_null(&x);
189    assert(zero_on_null(&x));
190    assert(&x);
191    assert(&x && "expecting null pointer");
192    // expected-warning@-1{{address of 'x' will always evaluate to 'true'}}
193  }
194}
195