Mercurial > hg > CbC > CbC_llvm
diff clang/test/SemaCXX/warn-bool-conversion.cpp @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 2e18cbf3894f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clang/test/SemaCXX/warn-bool-conversion.cpp Thu Feb 13 15:10:13 2020 +0900 @@ -0,0 +1,214 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=expected,expected-cxx11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,expected-cxx11 -std=c++11 %s + +namespace BooleanFalse { +int* j = false; +#if __cplusplus <= 199711L +// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}} +#else +// expected-error@-4 {{cannot initialize a variable of type 'int *' with an rvalue of type 'bool'}} +#endif + +#if __cplusplus <= 199711L +// expected-warning@+6 {{initialization of pointer of type 'int *' to null from a constant boolean expression}} +#else +// expected-error@+4 {{cannot initialize a parameter of type 'int *' with an rvalue of type 'bool'}} +// expected-note@+3 {{passing argument to parameter 'j' here}} +// expected-note@+2 6 {{candidate function not viable: requires 2 arguments, but 1 was provided}} +#endif +void foo(int* i, int *j=(false)) +{ + foo(false); +#if __cplusplus <= 199711L +// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}} +#else +// expected-error@-4 {{no matching function for call to 'foo'}} +#endif + + foo((int*)false); +#if __cplusplus <= 199711L +// no-warning: explicit cast +#else +// expected-error@-4 {{no matching function for call to 'foo'}} +#endif + + foo(0); +#if __cplusplus <= 199711L +// no-warning: not a bool, even though its convertible to bool +#else +// expected-error@-4 {{no matching function for call to 'foo'}} +#endif + + foo(false == true); +#if __cplusplus <= 199711L +// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}} +#else +// expected-error@-4 {{no matching function for call to 'foo'}} +#endif + + foo((42 + 24) < 32); +#if __cplusplus <= 199711L +// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}} +#else +// expected-error@-4 {{no matching function for call to 'foo'}} +#endif + + const bool kFlag = false; + foo(kFlag); +#if __cplusplus <= 199711L +// expected-warning@-2 {{initialization of pointer of type 'int *' to null from a constant boolean expression}} +#else +// expected-error@-4 {{no matching function for call to 'foo'}} +#endif +} + +char f(struct Undefined*); +double f(...); + +// Ensure that when using false in metaprogramming machinery its conversion +// isn't flagged. +template <int N> struct S {}; +S<sizeof(f(false))> s; + +} + +namespace Function { +void f1(); + +struct S { + static void f2(); +}; + +extern void f3() __attribute__((weak_import)); + +struct S2 { + static void f4() __attribute__((weak_import)); +}; + +bool f5(); +bool f6(int); + +void bar() { + bool b; + + b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \ + expected-note {{prefix with the address-of operator to silence this warning}} + if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \ + expected-note {{prefix with the address-of operator to silence this warning}} + b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \ + expected-note {{prefix with the address-of operator to silence this warning}} + if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \ + expected-note {{prefix with the address-of operator to silence this warning}} + b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \ + expected-note {{prefix with the address-of operator to silence this warning}} \ + expected-note {{suffix with parentheses to turn this into a function call}} + b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \ + expected-note {{prefix with the address-of operator to silence this warning}} + + // implicit casts of weakly imported symbols are ok: + b = f3; + if (f3) {} + b = S2::f4; + if (S2::f4) {} +} +} + +namespace Array { + #define GetValue(ptr) ((ptr) ? ptr[0] : 0) + extern int a[] __attribute__((weak)); + int b[] = {8,13,21}; + struct { + int x[10]; + } c; + const char str[] = "text"; + void ignore() { + if (a) {} + if (a) {} + (void)GetValue(b); + } + void test() { + if (b) {} + // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}} + if (b) {} + // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}} + if (c.x) {} + // expected-warning@-1{{address of array 'c.x' will always evaluate to 'true'}} + if (str) {} + // expected-warning@-1{{address of array 'str' will always evaluate to 'true'}} + } +} + +namespace Pointer { + extern int a __attribute__((weak)); + int b; + static int c; + class S { + public: + static int a; + int b; + }; + void ignored() { + if (&a) {} + } + void test() { + S s; + if (&b) {} + // expected-warning@-1{{address of 'b' will always evaluate to 'true'}} + if (&c) {} + // expected-warning@-1{{address of 'c' will always evaluate to 'true'}} + if (&s.a) {} + // expected-warning@-1{{address of 's.a' will always evaluate to 'true'}} + if (&s.b) {} + // expected-warning@-1{{address of 's.b' will always evaluate to 'true'}} + if (&S::a) {} + // expected-warning@-1{{address of 'S::a' will always evaluate to 'true'}} + } +} + +namespace macros { + #define assert(x) if (x) {} + #define zero_on_null(x) ((x) ? *(x) : 0) + + int array[5]; + void fun(); + int x; + + void test() { + assert(array); + assert(array && "expecting null pointer"); + // expected-warning@-1{{address of array 'array' will always evaluate to 'true'}} + + assert(fun); + assert(fun && "expecting null pointer"); + // expected-warning@-1{{address of function 'fun' will always evaluate to 'true'}} + // expected-note@-2 {{prefix with the address-of operator to silence this warning}} + + // TODO: warn on assert(&x) while not warning on zero_on_null(&x) + zero_on_null(&x); + assert(zero_on_null(&x)); + assert(&x); + assert(&x && "expecting null pointer"); + // expected-warning@-1{{address of 'x' will always evaluate to 'true'}} + } +} + +namespace Template { + // FIXME: These cases should not warn. + template<int *p> void f() { if (p) {} } // expected-warning 2{{will always evaluate to 'true'}} expected-cxx11-warning {{implicit conversion of nullptr}} + template<int (*p)[3]> void g() { if (p) {} } // expected-warning 2{{will always evaluate to 'true'}} expected-cxx11-warning {{implicit conversion of nullptr}} + template<int (*p)()> void h() { if (p) {} } + + int a, b[3], c[3][3], d(); + template void f<&a>(); // expected-note {{instantiation of}} + template void f<b>(); // expected-note {{instantiation of}} +#if __cplusplus >= 201103L + template void f<(int*)nullptr>(); // expected-note {{instantiation of}} +#endif + template void g<&b>(); // expected-note {{instantiation of}} + template void g<c>(); // expected-note {{instantiation of}} +#if __cplusplus >= 201103L + template void g<(int(*)[3])nullptr>(); // expected-note {{instantiation of}} +#endif + template void h<d>(); +}