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