r183883 - Implement core issue 903: only integer literals with value 0 and prvalues of

Richard Smith richard-llvm at metafoo.co.uk
Wed Jun 12 19:46:15 PDT 2013


Author: rsmith
Date: Wed Jun 12 21:46:14 2013
New Revision: 183883

URL: http://llvm.org/viewvc/llvm-project?rev=183883&view=rev
Log:
Implement core issue 903: only integer literals with value 0 and prvalues of
type std::nullptr_t are null pointer constants from C++11 onwards.

Modified:
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
    cfe/trunk/test/SemaCXX/lambda-expressions.cpp

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=183883&r1=183882&r2=183883&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Wed Jun 12 21:46:14 2013
@@ -3024,7 +3024,7 @@ bool Expr::hasNonTrivialCall(ASTContext
 Expr::NullPointerConstantKind
 Expr::isNullPointerConstant(ASTContext &Ctx,
                             NullPointerConstantValueDependence NPC) const {
-  if (isValueDependent()) {
+  if (isValueDependent() && !Ctx.getLangOpts().CPlusPlus11) {
     switch (NPC) {
     case NPC_NeverValueDependent:
       llvm_unreachable("Unexpected value dependent expression!");
@@ -3085,7 +3085,8 @@ Expr::isNullPointerConstant(ASTContext &
     return NPCK_CXX11_nullptr;
 
   if (const RecordType *UT = getType()->getAsUnionType())
-    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>())
+    if (!Ctx.getLangOpts().CPlusPlus11 &&
+        UT && UT->getDecl()->hasAttr<TransparentUnionAttr>())
       if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(this)){
         const Expr *InitExpr = CLE->getInitializer();
         if (const InitListExpr *ILE = dyn_cast<InitListExpr>(InitExpr))
@@ -3096,14 +3097,14 @@ Expr::isNullPointerConstant(ASTContext &
       (Ctx.getLangOpts().CPlusPlus && getType()->isEnumeralType()))
     return NPCK_NotNull;
 
-  // If we have an integer constant expression, we need to *evaluate* it and
-  // test for the value 0. Don't use the C++11 constant expression semantics
-  // for this, for now; once the dust settles on core issue 903, we might only
-  // allow a literal 0 here in C++11 mode.
   if (Ctx.getLangOpts().CPlusPlus11) {
-    if (!isCXX98IntegralConstantExpr(Ctx))
-      return NPCK_NotNull;
+    // C++11 [conv.ptr]p1: A null pointer constant is an integer literal with
+    // value zero or a prvalue of type std::nullptr_t.
+    const IntegerLiteral *Lit = dyn_cast<IntegerLiteral>(this);
+    return (Lit && !Lit->getValue()) ? NPCK_ZeroLiteral : NPCK_NotNull;
   } else {
+    // If we have an integer constant expression, we need to *evaluate* it and
+    // test for the value 0.
     if (!isIntegerConstantExpr(Ctx))
       return NPCK_NotNull;
   }

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=183883&r1=183882&r2=183883&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Wed Jun 12 21:46:14 2013
@@ -769,15 +769,22 @@ static_assert(&ok2 == pok2, "");
 static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");
 static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
 
-constexpr Base *nullB = 42 - 6 * 7; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *const'}}
+// Core issue 903: we do not perform constant evaluation when checking for a
+// null pointer in C++11. Just check for an integer literal with value 0.
+constexpr Base *nullB = 42 - 6 * 7; // expected-error {{cannot initialize a variable of type 'Class::Base *const' with an rvalue of type 'int'}}
+constexpr Base *nullB1 = 0;
 static_assert((Bottom*)nullB == 0, "");
 static_assert((Derived*)nullB == 0, "");
 static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");
-Base * nullB2 = '\0'; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *'}}
-Base * nullB3 = (0);
-// We suppress the warning in unevaluated contexts to workaround some gtest
-// behavior. Once this becomes an error this isn't a problem anymore.
-static_assert(nullB == (1 - 1), "");
+Base *nullB2 = '\0'; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'char'}}
+Base *nullB3 = (0);
+Base *nullB4 = false; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'bool'}}
+Base *nullB5 = ((0ULL));
+Base *nullB6 = 0.; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'double'}}
+enum Null { kNull };
+Base *nullB7 = kNull; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'Class::Null'}}
+static_assert(nullB1 == (1 - 1), ""); // expected-error {{comparison between pointer and integer}}
+
 
 
 namespace ConversionOperators {

Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=183883&r1=183882&r2=183883&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original)
+++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Wed Jun 12 21:46:14 2013
@@ -109,27 +109,30 @@ namespace PR12031 {
   }
 }
 
-namespace NullPtr {
+namespace Array {
   int &f(int *p);
   char &f(...);
   void g() {
-    int n = 0;
+    int n = -1;
     [=] {
-      char &k = f(n); // not a null pointer constant
+      int arr[n]; // VLA
     } ();
 
-    const int m = 0;
-    [=] {
-      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+    const int m = -1;
+    [] {
+      int arr[m]; // expected-error{{negative size}}
+    } ();
+
+    [&] {
+      int arr[m]; // expected-error{{negative size}}
     } ();
 
-    [=] () -> bool {
-      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
-      return &m == 0;
+    [=] {
+      int arr[m]; // expected-error{{negative size}}
     } ();
 
     [m] {
-      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+      int arr[m]; // expected-error{{negative size}}
     } ();
   }
 }





More information about the cfe-commits mailing list