diff options
Diffstat (limited to 'test/SemaCXX/conversion.cpp')
-rw-r--r-- | test/SemaCXX/conversion.cpp | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp index a64b187..ac235cc 100644 --- a/test/SemaCXX/conversion.cpp +++ b/test/SemaCXX/conversion.cpp @@ -65,19 +65,69 @@ void test3() { int c = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}} int d; d = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}} - bool bl = NULL; // FIXME: this should warn but we currently suppress a bunch of conversion-to-bool warnings including this one + bool bl = NULL; // expected-warning {{implicit conversion of NULL constant to 'bool'}} char ch = NULL; // expected-warning {{implicit conversion of NULL constant to 'char'}} unsigned char uch = NULL; // expected-warning {{implicit conversion of NULL constant to 'unsigned char'}} short sh = NULL; // expected-warning {{implicit conversion of NULL constant to 'short'}} + double dbl = NULL; // expected-warning {{implicit conversion of NULL constant to 'double'}} // Use FileCheck to ensure we don't get any unnecessary macro-expansion notes // (that don't appear as 'real' notes & can't be seen/tested by -verify) // CHECK-NOT: note: - // CHECK: note: expanded from macro 'FNULL' -#define FNULL NULL - int a2 = FNULL; // expected-warning {{implicit conversion of NULL constant to 'int'}} - // CHECK-NOT: note: // CHECK: note: expanded from macro 'FINIT' #define FINIT int a3 = NULL; FINIT // expected-warning {{implicit conversion of NULL constant to 'int'}} + + // we don't catch the case of #define FOO NULL ... int i = FOO; but that seems a bit narrow anyway + // and avoiding that helps us skip these cases: +#define NULL_COND(cond) ((cond) ? &a : NULL) + bool bl2 = NULL_COND(true); // don't warn on NULL conversion through the conditional operator across a macro boundary + if (NULL_COND(true)) + ; + while (NULL_COND(true)) + ; + for (; NULL_COND(true); ) + ; + do ; + while(NULL_COND(true)); + int *ip = NULL; + int (*fp)() = NULL; + struct foo { + int n; + void func(); + }; + int foo::*datamem = NULL; + int (foo::*funmem)() = NULL; +} + +namespace test4 { + // FIXME: We should warn for non-dependent args (only when the param type is also non-dependent) only once + // not once for the template + once for every instantiation + template<typename T> + void tmpl(char c = NULL, // expected-warning 4 {{implicit conversion of NULL constant to 'char'}} + T a = NULL, // expected-warning {{implicit conversion of NULL constant to 'char'}} \ + expected-warning 2 {{implicit conversion of NULL constant to 'int'}} + T b = 1024) { // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1024 to 0}} + } + + template<typename T> + void tmpl2(T t = NULL) { + } + + void func() { + tmpl<char>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<char>' required here}} + tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}} + // FIXME: We should warn only once for each template instantiation - not once for each call + tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}} + tmpl2<int*>(); + } +} + +namespace test5 { + template<int I> + void func() { + bool b = I; + } + + template void func<3>(); } |