diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-14 21:38:30 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-14 21:38:30 +0000 |
commit | 70488e201ccd94d4bb1ef0868cc13cca2b7d4ff6 (patch) | |
tree | ba334a4211ad43de9a739a2e5e3f236e3004b083 | |
parent | a91ac5bae3944e0eed9ef25294dfb2b8681b8159 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150510 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 4 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 15 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 5 | ||||
-rw-r--r-- | test/SemaCXX/nullptr.cpp | 11 |
4 files changed, 31 insertions, 4 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index adf12c1b2d..8a80803f01 100644 --- a/include/clang/AST/Expr.h +++ b/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/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 5d22d144f4..5b511cc883 100644 --- a/lib/AST/Expr.cpp +++ b/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/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index c0fff5e478..787e722a7c 100644 --- a/lib/AST/ExprConstant.cpp +++ b/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<PartialDiagnosticAt, 8> Diags; Status.Diag = &Diags; diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp index 6f660366e9..0e6771b57f 100644 --- a/test/SemaCXX/nullptr.cpp +++ b/test/SemaCXX/nullptr.cpp @@ -161,3 +161,14 @@ namespace templates { X2<nullptr, nullptr, nullptr, nullptr> 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}} + +} |