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 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++.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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}}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue