]> granicus.if.org Git - clang/commitdiff
PR10837: Warn if a null pointer constant is formed by a zero integer constant
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 21 Nov 2013 01:53:02 +0000 (01:53 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 21 Nov 2013 01:53:02 +0000 (01:53 +0000)
expression that is not a zero literal, in C. This is a different, and more
targeted, approach than that in r194540.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195303 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/Sema/warn-null.c [new file with mode: 0644]
test/SemaTemplate/dependent-expr.cpp

index 26c81ef552ca50316f92d8200b21dc082f7d486b..55f9d6f8a08b8259cdf12ba0149b048f676761bc 100644 (file)
@@ -6565,12 +6565,14 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS,
 
   // C99 6.5.16.1p1: the left operand is a pointer and the right is
   // a null pointer constant.
-  if ((LHSType->isPointerType() ||
-       LHSType->isObjCObjectPointerType() ||
-       LHSType->isBlockPointerType())
-      && RHS.get()->isNullPointerConstant(Context,
-                                          Expr::NPC_ValueDependentIsNull)) {
-    RHS = ImpCastExprToType(RHS.take(), LHSType, CK_NullToPointer);
+  if ((LHSType->isPointerType() || LHSType->isObjCObjectPointerType() ||
+       LHSType->isBlockPointerType()) &&
+      RHS.get()->isNullPointerConstant(Context,
+                                       Expr::NPC_ValueDependentIsNull)) {
+    CastKind Kind;
+    CXXCastPath Path;
+    CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false);
+    RHS = ImpCastExprToType(RHS.take(), LHSType, Kind, VK_RValue, &Path);
     return Compatible;
   }
 
diff --git a/test/Sema/warn-null.c b/test/Sema/warn-null.c
new file mode 100644 (file)
index 0000000..28fb6a5
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -verify
+
+// PR10837: Warn if a non-pointer-typed expression is folded to a null pointer
+int *p = 0;
+int *q = '\0'; // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+int *r = (1 - 1); // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+void f() {
+  p = 0;
+  q = '\0'; // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+  r = 1 - 1; // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+}
index 01ac42ed42132f5ab23efbfbb68b7b47f37eee26..2c26ec53a0ae1e1ee4d0349a767ee169edffe02f 100644 (file)
@@ -79,3 +79,17 @@ template<typename T> struct CastDependentIntToPointer {
     return ((void*)(((unsigned long)(x)|0x1ul)));
   }
 };
+
+// Regression test for crasher in r194540.
+namespace PR10837 {
+  typedef void t(int);
+  template<typename> struct A {
+    void f();
+    static t g;
+  };
+  t *p;
+  template<typename T> void A<T>::f() {
+    p = g;
+  }
+  template struct A<int>;
+}