1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3namespace BooleanFalse {
4int* j = false; // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
5
6void foo(int* i, int *j=(false)) // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
7{
8  foo(false); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
9  foo((int*)false); // no-warning: explicit cast
10  foo(0); // no-warning: not a bool, even though its convertible to bool
11
12  foo(false == true); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
13  foo((42 + 24) < 32); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
14
15  const bool kFlag = false;
16  foo(kFlag); // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
17}
18
19char f(struct Undefined*);
20double f(...);
21
22// Ensure that when using false in metaprogramming machinery its conversion
23// isn't flagged.
24template <int N> struct S {};
25S<sizeof(f(false))> s;
26
27}
28
29namespace Function {
30void f1();
31
32struct S {
33  static void f2();
34};
35
36extern void f3() __attribute__((weak_import));
37
38struct S2 {
39  static void f4() __attribute__((weak_import));
40};
41
42bool f5();
43bool f6(int);
44
45void bar() {
46  bool b;
47
48  b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
49             expected-note {{prefix with the address-of operator to silence this warning}}
50  if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
51                expected-note {{prefix with the address-of operator to silence this warning}}
52  b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
53                expected-note {{prefix with the address-of operator to silence this warning}}
54  if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
55                   expected-note {{prefix with the address-of operator to silence this warning}}
56  b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
57             expected-note {{prefix with the address-of operator to silence this warning}} \
58             expected-note {{suffix with parentheses to turn this into a function call}}
59  b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
60             expected-note {{prefix with the address-of operator to silence this warning}}
61
62  // implicit casts of weakly imported symbols are ok:
63  b = f3;
64  if (f3) {}
65  b = S2::f4;
66  if (S2::f4) {}
67}
68}
69
70namespace Array {
71  #define GetValue(ptr)  ((ptr) ? ptr[0] : 0)
72  extern int a[] __attribute__((weak));
73  int b[] = {8,13,21};
74  struct {
75    int x[10];
76  } c;
77  const char str[] = "text";
78  void ignore() {
79    if (a) {}
80    if (a) {}
81    (void)GetValue(b);
82  }
83  void test() {
84    if (b) {}
85    // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
86    if (b) {}
87    // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
88    if (c.x) {}
89    // expected-warning@-1{{address of array 'c.x' will always evaluate to 'true'}}
90    if (str) {}
91    // expected-warning@-1{{address of array 'str' will always evaluate to 'true'}}
92  }
93}
94
95namespace Pointer {
96  extern int a __attribute__((weak));
97  int b;
98  static int c;
99  class S {
100  public:
101    static int a;
102    int b;
103  };
104  void ignored() {
105    if (&a) {}
106  }
107  void test() {
108    S s;
109    if (&b) {}
110    // expected-warning@-1{{address of 'b' will always evaluate to 'true'}}
111    if (&c) {}
112    // expected-warning@-1{{address of 'c' will always evaluate to 'true'}}
113    if (&s.a) {}
114    // expected-warning@-1{{address of 's.a' will always evaluate to 'true'}}
115    if (&s.b) {}
116    // expected-warning@-1{{address of 's.b' will always evaluate to 'true'}}
117    if (&S::a) {}
118    // expected-warning@-1{{address of 'S::a' will always evaluate to 'true'}}
119  }
120}
121
122namespace macros {
123  #define assert(x) if (x) {}
124  #define zero_on_null(x) ((x) ? *(x) : 0)
125
126  int array[5];
127  void fun();
128  int x;
129
130  void test() {
131    assert(array);
132    assert(array && "expecting null pointer");
133    // expected-warning@-1{{address of array 'array' will always evaluate to 'true'}}
134
135    assert(fun);
136    assert(fun && "expecting null pointer");
137    // expected-warning@-1{{address of function 'fun' will always evaluate to 'true'}}
138    // expected-note@-2 {{prefix with the address-of operator to silence this warning}}
139
140    // TODO: warn on assert(&x) while not warning on zero_on_null(&x)
141    zero_on_null(&x);
142    assert(zero_on_null(&x));
143    assert(&x);
144    assert(&x && "expecting null pointer");
145    // expected-warning@-1{{address of 'x' will always evaluate to 'true'}}
146  }
147}
148