237 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify=expected,expected-cxx11 %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s3// RUN: %clang_cc1 -fsyntax-only -verify=expected,expected-cxx11 -std=c++11 %s4 5namespace BooleanFalse {6int* j = false;7#if __cplusplus <= 199711L8// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}9#else10// expected-error@-4 {{cannot initialize a variable of type 'int *' with an rvalue of type 'bool'}}11#endif12 13#if __cplusplus <= 199711L14// expected-warning@+5 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}15#else16// expected-error@+3 {{cannot initialize a parameter of type 'int *' with an rvalue of type 'bool'}}17// expected-note@+2 {{passing argument to parameter 'j' here}}18#endif19void bar(int *j = false);20 21#if __cplusplus > 199711L22// expected-note@+2 4{{candidate function not viable: no known conversion}}23#endif24void foo(int *i)25{26 foo(false);27#if __cplusplus <= 199711L28// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}29#else30// expected-error@-4 {{no matching function for call to 'foo'}}31#endif32 33 foo((int*)false); // OK: explicit cast34 foo(0); // OK: not a bool, even though it's convertible to bool35 36 foo(false == true);37#if __cplusplus <= 199711L38// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}39#else40// expected-error@-4 {{no matching function for call to 'foo'}}41#endif42 43 foo((42 + 24) < 32);44#if __cplusplus <= 199711L45// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}46#else47// expected-error@-4 {{no matching function for call to 'foo'}}48#endif49 50 const bool kFlag = false;51 foo(kFlag);52#if __cplusplus <= 199711L53// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}}54#else55// expected-error@-4 {{no matching function for call to 'foo'}}56#endif57}58 59char f(struct Undefined*);60double f(...);61 62// Ensure that when using false in metaprogramming machinery its conversion63// isn't flagged.64template <int N> struct S {};65S<sizeof(f(false))> s;66 67}68 69namespace Function {70void f1();71 72struct S {73 static void f2();74};75 76extern void f3() __attribute__((weak_import));77 78struct S2 {79 static void f4() __attribute__((weak_import));80};81 82bool f5();83bool f6(int);84#if __cplusplus >= 201103L85auto f7 = []{};86auto f8 = [](){};87 88void foo() {89 bool b;90 b = f7; // expected-warning {{address of lambda function pointer conversion operator will always evaluate to 'true'}}91 b = f8; // expected-warning {{address of lambda function pointer conversion operator will always evaluate to 'true'}}92 bool is_true = [](){ return true; };93 // expected-warning@-1{{address of lambda function pointer conversion operator will always evaluate to 'true'}}94}95 96template <typename... Ts>97static bool IsFalse(const Ts&...) { return false; }98template <typename T>99static bool IsFalse(const T& p) {100 bool b;101 b = f7; // expected-warning {{address of lambda function pointer conversion operator will always evaluate to 'true'}}102 // Intentionally not warned on because p could be a lambda type in one103 // instantiation, but a pointer type in another.104 return p ? false : true;105}106 107bool use_instantiation() {108 return IsFalse([]() { return 0; });109}110#endif111 112void bar() {113 bool b;114 115 b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \116 expected-note {{prefix with the address-of operator to silence this warning}}117 if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \118 expected-note {{prefix with the address-of operator to silence this warning}}119 b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \120 expected-note {{prefix with the address-of operator to silence this warning}}121 if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \122 expected-note {{prefix with the address-of operator to silence this warning}}123 b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \124 expected-note {{prefix with the address-of operator to silence this warning}} \125 expected-note {{suffix with parentheses to turn this into a function call}}126 b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \127 expected-note {{prefix with the address-of operator to silence this warning}}128 129 // implicit casts of weakly imported symbols are ok:130 b = f3;131 if (f3) {}132 b = S2::f4;133 if (S2::f4) {}134}135}136 137namespace Array {138 #define GetValue(ptr) ((ptr) ? ptr[0] : 0)139 extern int a[] __attribute__((weak));140 int b[] = {8,13,21};141 struct {142 int x[10];143 } c;144 const char str[] = "text";145 void ignore() {146 if (a) {}147 if (a) {}148 (void)GetValue(b);149 }150 void test() {151 if (b) {}152 // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}153 if (b) {}154 // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}155 if (c.x) {}156 // expected-warning@-1{{address of array 'c.x' will always evaluate to 'true'}}157 if (str) {}158 // expected-warning@-1{{address of array 'str' will always evaluate to 'true'}}159 }160}161 162namespace Pointer {163 extern int a __attribute__((weak));164 int b;165 static int c;166 class S {167 public:168 static int a;169 int b;170 };171 void ignored() {172 if (&a) {}173 }174 void test() {175 S s;176 if (&b) {}177 // expected-warning@-1{{address of 'b' will always evaluate to 'true'}}178 if (&c) {}179 // expected-warning@-1{{address of 'c' will always evaluate to 'true'}}180 if (&s.a) {}181 // expected-warning@-1{{address of 's.a' will always evaluate to 'true'}}182 if (&s.b) {}183 // expected-warning@-1{{address of 's.b' will always evaluate to 'true'}}184 if (&S::a) {}185 // expected-warning@-1{{address of 'S::a' will always evaluate to 'true'}}186 }187}188 189namespace macros {190 #define assert(x) if (x) {}191 #define zero_on_null(x) ((x) ? *(x) : 0)192 193 int array[5];194 void fun();195 int x;196 197 void test() {198 assert(array);199 assert(array && "expecting null pointer");200 // expected-warning@-1{{address of array 'array' will always evaluate to 'true'}}201 202 assert(fun);203 assert(fun && "expecting null pointer");204 // expected-warning@-1{{address of function 'fun' will always evaluate to 'true'}}205 // expected-note@-2 {{prefix with the address-of operator to silence this warning}}206 207 // TODO: warn on assert(&x) while not warning on zero_on_null(&x)208 zero_on_null(&x);209 assert(zero_on_null(&x));210 assert(&x);211 assert(&x && "expecting null pointer");212 // expected-warning@-1{{address of 'x' will always evaluate to 'true'}}213 }214}215 216#if __cplusplus < 201703L217namespace Template {218 // FIXME: These cases should not warn.219 template<int *p> void f() { if (p) {} } // expected-warning 2{{will always evaluate to 'true'}} expected-cxx11-warning {{implicit conversion of nullptr}}220 template<int (*p)[3]> void g() { if (p) {} } // expected-warning 2{{will always evaluate to 'true'}} expected-cxx11-warning {{implicit conversion of nullptr}}221 template<int (*p)()> void h() { if (p) {} }222 223 int a, b[3], c[3][3], d();224 template void f<&a>(); // expected-note {{instantiation of}}225 template void f<b>(); // expected-note {{instantiation of}}226#if __cplusplus >= 201103L227 template void f<(int*)nullptr>(); // expected-note {{instantiation of}}228#endif229 template void g<&b>(); // expected-note {{instantiation of}}230 template void g<c>(); // expected-note {{instantiation of}}231#if __cplusplus >= 201103L232 template void g<(int(*)[3])nullptr>(); // expected-note {{instantiation of}}233#endif234 template void h<d>();235}236#endif // __cplusplus < 201703L237