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 Weber void 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 Keane struct A { operator int*() { return nullptr; } };
func()42818cf5bcSErich Keane void func() { if (nullptr == A()) {} }
func2()43818cf5bcSErich Keane void func2() { if ((nullptr) == A()) {} }
44818cf5bcSErich Keane }
45*809df34eSRoman Lebedev 
TmplFunc0(T var)46*809df34eSRoman Lebedev template <typename T> void TmplFunc0(T var) {}
Func0Test()47*809df34eSRoman Lebedev void 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 Lebedev template <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 Lebedev void 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 Lebedev void 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 Lebedev void 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