aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-14 21:38:30 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-14 21:38:30 +0000
commit70488e201ccd94d4bb1ef0868cc13cca2b7d4ff6 (patch)
treeba334a4211ad43de9a739a2e5e3f236e3004b083
parenta91ac5bae3944e0eed9ef25294dfb2b8681b8159 (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.h4
-rw-r--r--lib/AST/Expr.cpp15
-rw-r--r--lib/AST/ExprConstant.cpp5
-rw-r--r--test/SemaCXX/nullptr.cpp11
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}}
+
+}