lebedev.ri updated this revision to Diff 120285.
lebedev.ri added a comment.

- Rebased
- Handle `-Wsystem-headers` properly, as per irc disscussion.

It was suggested that `findMacroSpelling()` might be slow, and 
`isNullPointerConstant()` should be used, but i'm not sure any of the 
`NullPointerConstantKind`'s can replace direct check for `NULL` specifically...


Repository:
  rL LLVM

https://reviews.llvm.org/D38954

Files:
  docs/ReleaseNotes.rst
  lib/Sema/Sema.cpp
  test/SemaCXX/Inputs/warn-zero-nullptr.h
  test/SemaCXX/warn-zero-nullptr.cpp

Index: test/SemaCXX/warn-zero-nullptr.cpp
===================================================================
--- test/SemaCXX/warn-zero-nullptr.cpp
+++ test/SemaCXX/warn-zero-nullptr.cpp
@@ -1,4 +1,10 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++11
+// 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 <warn-zero-nullptr.h>
+
+#define MACRO (0)
+#define MCRO(x) (x)
 
 struct S {};
 
@@ -15,13 +21,65 @@
 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 = 0); // expected-warning{{zero as null pointer constant}}
-void f1(void* v);
+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<decltype(nullptr)>(0); // expected-warning{{zero as null pointer constant}}
+
+template <typename T> void TmplFunc0(T var) {}
+void Func0Test() {
+  TmplFunc0<int>(0);
+  TmplFunc0<int*>(0); // expected-warning {{zero as null pointer constant}}
+  TmplFunc0<void*>(0); // expected-warning {{zero as null pointer constant}}
+}
+
+// FIXME: this one should *NOT* warn.
+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}}
+void FuncTest() {
+  TmplFunc1<int>(0);
+  TmplFunc1<int*>(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<int *>' required here}}
+  TmplFunc1<void*>(0);  // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<void *>' required here}}
+}
+
+template<typename T>
+class TemplateClass0 {
+ public:
+  explicit TemplateClass0(T var) {}
+};
+void TemplateClass0Test() {
+  TemplateClass0<int> a(0);
+  TemplateClass0<int*> b(0); // expected-warning {{zero as null pointer constant}}
+  TemplateClass0<void*> c(0); // expected-warning {{zero as null pointer constant}}
+}
+
+template<typename T>
+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<int> a(1);
+  TemplateClass1<int*> b(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<int *>' required here}}
+  TemplateClass1<void*> c(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<void *>' 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
Index: test/SemaCXX/Inputs/warn-zero-nullptr.h
===================================================================
--- /dev/null
+++ test/SemaCXX/Inputs/warn-zero-nullptr.h
@@ -0,0 +1,3 @@
+#define NULL (0)
+#define SYSTEM_MACRO (0)
+#define OTHER_SYSTEM_MACRO (NULL)
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -440,6 +440,15 @@
     return;
   if (E->getType()->isNullPtrType())
     return;
+
+  // If it is a macro from system header, and if the macro name is not "NULL",
+  // do not warn.
+  SourceLocation MaybeMacroLoc = E->getLocStart();
+  if (Diags.getSuppressSystemWarnings() &&
+      SourceMgr.isInSystemMacro(MaybeMacroLoc) &&
+      !findMacroSpelling(MaybeMacroLoc, "NULL"))
+    return;
+
   // nullptr only exists from C++11 on, so don't warn on its absence earlier.
   if (!getLangOpts().CPlusPlus11)
     return;
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -91,6 +91,9 @@
   offset is nonzero. It also now warns about arithmetic on a null pointer
   treated as a cast from integer to pointer (GNU extension).
 
+- ``-Wzero-as-null-pointer-constant`` was adjusted not to warn on null pointer
+  constants that originate from system macros, except ``NULL`` macro.
+
 Non-comprehensive list of changes in this release
 -------------------------------------------------
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to