// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++11 // RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -DSYSTEM_WARNINGS -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 #include #define MACRO (0) #define MCRO(x) (x) struct S {}; int (S::*mp0) = nullptr; void (*fp0)() = nullptr; void* p0 = nullptr; int (S::*mp1) = 0; // expected-warning{{zero as null pointer constant}} void (*fp1)() = 0; // expected-warning{{zero as null pointer constant}} void* p1 = 0; // expected-warning{{zero as null pointer constant}} // NULL is an integer constant expression, so warn on it too: void* p2 = __null; // expected-warning{{zero as null pointer constant}} void (*fp2)() = __null; // expected-warning{{zero as null pointer constant}} int (S::*mp2) = __null; // expected-warning{{zero as null pointer constant}} void f0(void* v = MACRO); // expected-warning{{zero as null pointer constant}} void f1(void* v = NULL); // expected-warning{{zero as null pointer constant}} void f2(void* v = MCRO(0)); // expected-warning{{zero as null pointer constant}} void f3(void* v = MCRO(NULL)); // expected-warning{{zero as null pointer constant}} void f4(void* v = 0); // expected-warning{{zero as null pointer constant}} void f5(void* v); void g() { f1(0); // expected-warning{{zero as null pointer constant}} } // Warn on these too. Matches gcc and arguably makes sense. void* pp = (decltype(nullptr))0; // expected-warning{{zero as null pointer constant}} void* pp2 = static_cast(0); // expected-warning{{zero as null pointer constant}} // Shouldn't warn. namespace pr34362 { struct A { operator int*() { return nullptr; } }; void func() { if (nullptr == A()) {} } void func2() { if ((nullptr) == A()) {} } } template void TmplFunc0(T var) {} void Func0Test() { TmplFunc0(0); TmplFunc0(0); // expected-warning {{zero as null pointer constant}} TmplFunc0(0); // expected-warning {{zero as null pointer constant}} } // FIXME: this one probably should not warn. template void TmplFunc1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} void FuncTest() { TmplFunc1(0); TmplFunc1(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1' required here}} TmplFunc1(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1' required here}} } template class TemplateClass0 { public: explicit TemplateClass0(T var) {} }; void TemplateClass0Test() { TemplateClass0 a(0); TemplateClass0 b(0); // expected-warning {{zero as null pointer constant}} TemplateClass0 c(0); // expected-warning {{zero as null pointer constant}} } template class TemplateClass1 { public: // FIXME: this one should *NOT* warn. explicit TemplateClass1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} }; void IgnoreSubstTemplateType1() { TemplateClass1 a(1); TemplateClass1 b(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1' required here}} TemplateClass1 c(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1' required here}} } #ifndef SYSTEM_WARNINGS // Do not warn on *any* other macros from system headers, even if they // expand to/their expansion contains NULL. void* sys_init = SYSTEM_MACRO; void* sys_init2 = OTHER_SYSTEM_MACRO; #else void* sys_init = SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}} void* sys_init2 = OTHER_SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}} #endif