1*809df34eSRoman Lebedev // RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++11 2*809df34eSRoman Lebedev // RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -DSYSTEM_WARNINGS -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11 3*809df34eSRoman Lebedev 4*809df34eSRoman Lebedev #include <warn-zero-nullptr.h> 5*809df34eSRoman Lebedev 6*809df34eSRoman Lebedev #define MACRO (0) 7*809df34eSRoman Lebedev #define MCRO(x) (x) 8d7ba86b6SNico Weber 9d7ba86b6SNico Weber struct S {}; 10d7ba86b6SNico Weber 11d7ba86b6SNico Weber int (S::*mp0) = nullptr; 12d7ba86b6SNico Weber void (*fp0)() = nullptr; 13d7ba86b6SNico Weber void* p0 = nullptr; 14d7ba86b6SNico Weber 15d7ba86b6SNico Weber int (S::*mp1) = 0; // expected-warning{{zero as null pointer constant}} 16d7ba86b6SNico Weber void (*fp1)() = 0; // expected-warning{{zero as null pointer constant}} 17d7ba86b6SNico Weber void* p1 = 0; // expected-warning{{zero as null pointer constant}} 18d7ba86b6SNico Weber 19d7ba86b6SNico Weber // NULL is an integer constant expression, so warn on it too: 20d7ba86b6SNico Weber void* p2 = __null; // expected-warning{{zero as null pointer constant}} 21d7ba86b6SNico Weber void (*fp2)() = __null; // expected-warning{{zero as null pointer constant}} 22d7ba86b6SNico Weber int (S::*mp2) = __null; // expected-warning{{zero as null pointer constant}} 23d7ba86b6SNico Weber 24*809df34eSRoman Lebedev void f0(void* v = MACRO); // expected-warning{{zero as null pointer constant}} 25*809df34eSRoman Lebedev void f1(void* v = NULL); // expected-warning{{zero as null pointer constant}} 26*809df34eSRoman Lebedev void f2(void* v = MCRO(0)); // expected-warning{{zero as null pointer constant}} 27*809df34eSRoman Lebedev void f3(void* v = MCRO(NULL)); // expected-warning{{zero as null pointer constant}} 28*809df34eSRoman Lebedev void f4(void* v = 0); // expected-warning{{zero as null pointer constant}} 29*809df34eSRoman Lebedev void f5(void* v); 30d7ba86b6SNico Weber g()31d7ba86b6SNico Webervoid g() { 32d7ba86b6SNico Weber f1(0); // expected-warning{{zero as null pointer constant}} 33d7ba86b6SNico Weber } 34d7ba86b6SNico Weber 35d7ba86b6SNico Weber // Warn on these too. Matches gcc and arguably makes sense. 36d7ba86b6SNico Weber void* pp = (decltype(nullptr))0; // expected-warning{{zero as null pointer constant}} 37d7ba86b6SNico Weber void* pp2 = static_cast<decltype(nullptr)>(0); // expected-warning{{zero as null pointer constant}} 38818cf5bcSErich Keane 39818cf5bcSErich Keane // Shouldn't warn. 40818cf5bcSErich Keane namespace pr34362 { operator int*pr34362::A41818cf5bcSErich Keanestruct A { operator int*() { return nullptr; } }; func()42818cf5bcSErich Keanevoid func() { if (nullptr == A()) {} } func2()43818cf5bcSErich Keanevoid func2() { if ((nullptr) == A()) {} } 44818cf5bcSErich Keane } 45*809df34eSRoman Lebedev TmplFunc0(T var)46*809df34eSRoman Lebedevtemplate <typename T> void TmplFunc0(T var) {} Func0Test()47*809df34eSRoman Lebedevvoid Func0Test() { 48*809df34eSRoman Lebedev TmplFunc0<int>(0); 49*809df34eSRoman Lebedev TmplFunc0<int*>(0); // expected-warning {{zero as null pointer constant}} 50*809df34eSRoman Lebedev TmplFunc0<void*>(0); // expected-warning {{zero as null pointer constant}} 51*809df34eSRoman Lebedev } 52*809df34eSRoman Lebedev 53*809df34eSRoman Lebedev // FIXME: this one probably should not warn. TmplFunc1(int a,T default_value=0)54*809df34eSRoman Lebedevtemplate <typename T> void TmplFunc1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} FuncTest()55*809df34eSRoman Lebedevvoid FuncTest() { 56*809df34eSRoman Lebedev TmplFunc1<int>(0); 57*809df34eSRoman Lebedev TmplFunc1<int*>(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<int *>' required here}} 58*809df34eSRoman Lebedev TmplFunc1<void*>(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<void *>' required here}} 59*809df34eSRoman Lebedev } 60*809df34eSRoman Lebedev 61*809df34eSRoman Lebedev template<typename T> 62*809df34eSRoman Lebedev class TemplateClass0 { 63*809df34eSRoman Lebedev public: TemplateClass0(T var)64*809df34eSRoman Lebedev explicit TemplateClass0(T var) {} 65*809df34eSRoman Lebedev }; TemplateClass0Test()66*809df34eSRoman Lebedevvoid TemplateClass0Test() { 67*809df34eSRoman Lebedev TemplateClass0<int> a(0); 68*809df34eSRoman Lebedev TemplateClass0<int*> b(0); // expected-warning {{zero as null pointer constant}} 69*809df34eSRoman Lebedev TemplateClass0<void*> c(0); // expected-warning {{zero as null pointer constant}} 70*809df34eSRoman Lebedev } 71*809df34eSRoman Lebedev 72*809df34eSRoman Lebedev template<typename T> 73*809df34eSRoman Lebedev class TemplateClass1 { 74*809df34eSRoman Lebedev public: 75*809df34eSRoman Lebedev // FIXME: this one should *NOT* warn. TemplateClass1(int a,T default_value=0)76*809df34eSRoman Lebedev explicit TemplateClass1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}} 77*809df34eSRoman Lebedev }; IgnoreSubstTemplateType1()78*809df34eSRoman Lebedevvoid IgnoreSubstTemplateType1() { 79*809df34eSRoman Lebedev TemplateClass1<int> a(1); 80*809df34eSRoman Lebedev TemplateClass1<int*> b(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<int *>' required here}} 81*809df34eSRoman Lebedev TemplateClass1<void*> c(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<void *>' required here}} 82*809df34eSRoman Lebedev } 83*809df34eSRoman Lebedev 84*809df34eSRoman Lebedev #ifndef SYSTEM_WARNINGS 85*809df34eSRoman Lebedev // Do not warn on *any* other macros from system headers, even if they 86*809df34eSRoman Lebedev // expand to/their expansion contains NULL. 87*809df34eSRoman Lebedev void* sys_init = SYSTEM_MACRO; 88*809df34eSRoman Lebedev void* sys_init2 = OTHER_SYSTEM_MACRO; 89*809df34eSRoman Lebedev #else 90*809df34eSRoman Lebedev void* sys_init = SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}} 91*809df34eSRoman Lebedev void* sys_init2 = OTHER_SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}} 92*809df34eSRoman Lebedev #endif 93