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
This commit is contained in:
Richard Smith 2012-02-14 21:38:30 +00:00
parent 89dbd3ba40
commit 98a0a49fbf
4 changed files with 31 additions and 4 deletions

View File

@ -423,6 +423,10 @@ public:
bool isEvaluated = true) const; bool isEvaluated = true) const;
bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) 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 /// isCXX11ConstantExpr - Return true if this expression is a constant
/// expression in C++11. Can only be used in C++. /// expression in C++11. Can only be used in C++.
/// ///

View File

@ -2728,11 +2728,18 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
return NPCK_NotNull; return NPCK_NotNull;
// If we have an integer constant expression, we need to *evaluate* it and // If we have an integer constant expression, we need to *evaluate* it and
// test for the value 0. // test for the value 0. Don't use the C++11 constant expression semantics
llvm::APSInt Result; // for this, for now; once the dust settles on core issue 903, we might only
bool IsNull = isIntegerConstantExpr(Result, Ctx) && Result == 0; // 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 /// \brief If this expression is an l-value for an Objective C

View File

@ -6435,12 +6435,17 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, ASTContext &Ctx,
return true; return true;
} }
bool Expr::isCXX98IntegralConstantExpr(ASTContext &Ctx) const {
return CheckICE(this, Ctx).Val == 0;
}
bool Expr::isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result, bool Expr::isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result,
SourceLocation *Loc) const { SourceLocation *Loc) const {
// We support this checking in C++98 mode in order to diagnose compatibility // We support this checking in C++98 mode in order to diagnose compatibility
// issues. // issues.
assert(Ctx.getLangOptions().CPlusPlus); assert(Ctx.getLangOptions().CPlusPlus);
// Build evaluation settings.
Expr::EvalStatus Status; Expr::EvalStatus Status;
llvm::SmallVector<PartialDiagnosticAt, 8> Diags; llvm::SmallVector<PartialDiagnosticAt, 8> Diags;
Status.Diag = &Diags; Status.Diag = &Diags;

View File

@ -161,3 +161,14 @@ namespace templates {
X2<nullptr, nullptr, nullptr, nullptr> x2; 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}}
}