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:
parent
89dbd3ba40
commit
98a0a49fbf
|
@ -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++.
|
||||
///
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue