From 98a0a49fbfdfc1933e1f40cce630d7f4bccf5afa Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 14 Feb 2012 21:38:30 +0000 Subject: [PATCH] Pending clear answer from WG21 on whether core issue 903 is intended to apply to C++11 or just C++17, restrict the set of null pointer constants in C++11 mode back to those which were considered null in C++98. llvm-svn: 150510 --- clang/include/clang/AST/Expr.h | 4 ++++ clang/lib/AST/Expr.cpp | 15 +++++++++++---- clang/lib/AST/ExprConstant.cpp | 5 +++++ clang/test/SemaCXX/nullptr.cpp | 11 +++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index adf12c1b2d08..8a80803f01c2 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -423,6 +423,10 @@ public: bool isEvaluated = true) const; bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const; + /// isCXX98IntegralConstantExpr - Return true if this expression is an + /// integral constant expression in C++98. Can only be used in C++. + bool isCXX98IntegralConstantExpr(ASTContext &Ctx) const; + /// isCXX11ConstantExpr - Return true if this expression is a constant /// expression in C++11. Can only be used in C++. /// diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 5d22d144f48c..5b511cc88315 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2728,11 +2728,18 @@ Expr::isNullPointerConstant(ASTContext &Ctx, return NPCK_NotNull; // If we have an integer constant expression, we need to *evaluate* it and - // test for the value 0. - llvm::APSInt Result; - bool IsNull = isIntegerConstantExpr(Result, Ctx) && Result == 0; + // 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.getLangOptions().CPlusPlus0x) { + if (!isCXX98IntegralConstantExpr(Ctx)) + return NPCK_NotNull; + } else { + if (!isIntegerConstantExpr(Ctx)) + return NPCK_NotNull; + } - return (IsNull ? NPCK_ZeroInteger : NPCK_NotNull); + return (EvaluateKnownConstInt(Ctx) == 0) ? NPCK_ZeroInteger : NPCK_NotNull; } /// \brief If this expression is an l-value for an Objective C diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index c0fff5e4781e..787e722a7cb4 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6435,12 +6435,17 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, ASTContext &Ctx, return true; } +bool Expr::isCXX98IntegralConstantExpr(ASTContext &Ctx) const { + return CheckICE(this, Ctx).Val == 0; +} + bool Expr::isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result, SourceLocation *Loc) const { // We support this checking in C++98 mode in order to diagnose compatibility // issues. assert(Ctx.getLangOptions().CPlusPlus); + // Build evaluation settings. Expr::EvalStatus Status; llvm::SmallVector Diags; Status.Diag = &Diags; diff --git a/clang/test/SemaCXX/nullptr.cpp b/clang/test/SemaCXX/nullptr.cpp index 6f660366e998..0e6771b57fcb 100644 --- a/clang/test/SemaCXX/nullptr.cpp +++ b/clang/test/SemaCXX/nullptr.cpp @@ -161,3 +161,14 @@ namespace templates { X2 x2; } + +namespace null_pointer_constant { + +// Pending implementation of core issue 903, ensure we don't allow any of the +// C++11 constant evaluation semantics in null pointer constants. +struct S { int n; }; +constexpr int null() { return 0; } +void *p = S().n; // expected-error {{cannot initialize}} +void *q = null(); // expected-error {{cannot initialize}} + +}