Skip to content

Commit f5d3335

Browse files
committed
Revert r347417 "Re-Reinstate 347294 with a fix for the failures."
Kept the "indirect_builtin_constant_p" test case in test/SemaCXX/constant-expression-cxx1y.cpp while we are investigating why the following snippet fails: extern char extern_var; struct { int a; } a = {__builtin_constant_p(extern_var)}; llvm-svn: 348039
1 parent d1a4b06 commit f5d3335

37 files changed

+197
-558
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -583,8 +583,7 @@ class Expr : public Stmt {
583583
/// this function returns true, it returns the folded constant in Result. If
584584
/// the expression is a glvalue, an lvalue-to-rvalue conversion will be
585585
/// applied.
586-
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
587-
bool InConstantContext = false) const;
586+
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const;
588587

589588
/// EvaluateAsBooleanCondition - Return true if this is a constant
590589
/// which we can fold and convert to a boolean condition using
@@ -601,7 +600,7 @@ class Expr : public Stmt {
601600

602601
/// EvaluateAsInt - Return true if this is a constant which we can fold and
603602
/// convert to an integer, using any crazy technique that we want to.
604-
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
603+
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,
605604
SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
606605

607606
/// EvaluateAsFloat - Return true if this is a constant which we can fold and
@@ -902,15 +901,10 @@ class FullExpr : public Expr {
902901

903902
/// ConstantExpr - An expression that occurs in a constant context.
904903
class ConstantExpr : public FullExpr {
904+
public:
905905
ConstantExpr(Expr *subexpr)
906906
: FullExpr(ConstantExprClass, subexpr) {}
907907

908-
public:
909-
static ConstantExpr *Create(const ASTContext &Context, Expr *E) {
910-
assert(!isa<ConstantExpr>(E));
911-
return new (Context) ConstantExpr(E);
912-
}
913-
914908
/// Build an empty constant expression wrapper.
915909
explicit ConstantExpr(EmptyShell Empty)
916910
: FullExpr(ConstantExprClass, Empty) {}
@@ -3093,8 +3087,8 @@ inline Expr *Expr::IgnoreImpCasts() {
30933087
while (true)
30943088
if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
30953089
e = ice->getSubExpr();
3096-
else if (FullExpr *fe = dyn_cast<FullExpr>(e))
3097-
e = fe->getSubExpr();
3090+
else if (ConstantExpr *ce = dyn_cast<ConstantExpr>(e))
3091+
e = ce->getSubExpr();
30983092
else
30993093
break;
31003094
return e;

clang/lib/AST/ASTImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6388,7 +6388,7 @@ ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) {
63886388
Expr *ToSubExpr;
63896389
std::tie(ToSubExpr) = *Imp;
63906390

6391-
return ConstantExpr::Create(Importer.getToContext(), ToSubExpr);
6391+
return new (Importer.getToContext()) ConstantExpr(ToSubExpr);
63926392
}
63936393

63946394
ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) {

clang/lib/AST/Expr.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2594,8 +2594,8 @@ Expr *Expr::IgnoreParenCasts() {
25942594
E = NTTP->getReplacement();
25952595
continue;
25962596
}
2597-
if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
2598-
E = FE->getSubExpr();
2597+
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
2598+
E = CE->getSubExpr();
25992599
continue;
26002600
}
26012601
return E;
@@ -2619,8 +2619,8 @@ Expr *Expr::IgnoreCasts() {
26192619
E = NTTP->getReplacement();
26202620
continue;
26212621
}
2622-
if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
2623-
E = FE->getSubExpr();
2622+
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
2623+
E = CE->getSubExpr();
26242624
continue;
26252625
}
26262626
return E;
@@ -2648,8 +2648,8 @@ Expr *Expr::IgnoreParenLValueCasts() {
26482648
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
26492649
E = NTTP->getReplacement();
26502650
continue;
2651-
} else if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
2652-
E = FE->getSubExpr();
2651+
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
2652+
E = CE->getSubExpr();
26532653
continue;
26542654
}
26552655
break;
@@ -2920,12 +2920,6 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
29202920

29212921
break;
29222922
}
2923-
case ConstantExprClass: {
2924-
// FIXME: We should be able to return "true" here, but it can lead to extra
2925-
// error messages. E.g. in Sema/array-init.c.
2926-
const Expr *Exp = cast<ConstantExpr>(this)->getSubExpr();
2927-
return Exp->isConstantInitializer(Ctx, false, Culprit);
2928-
}
29292923
case CompoundLiteralExprClass: {
29302924
// This handles gcc's extension that allows global initializers like
29312925
// "struct x {int x;} x = (struct x) {};".
@@ -2965,8 +2959,8 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
29652959
const Expr *Elt = ILE->getInit(ElementNo++);
29662960
if (Field->isBitField()) {
29672961
// Bitfields have to evaluate to an integer.
2968-
EvalResult Result;
2969-
if (!Elt->EvaluateAsInt(Result, Ctx)) {
2962+
llvm::APSInt ResultTmp;
2963+
if (!Elt->EvaluateAsInt(ResultTmp, Ctx)) {
29702964
if (Culprit)
29712965
*Culprit = Elt;
29722966
return false;

clang/lib/AST/ExprConstant.cpp

Lines changed: 45 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
#include "clang/AST/TypeLoc.h"
4646
#include "clang/Basic/Builtins.h"
4747
#include "clang/Basic/TargetInfo.h"
48-
#include "llvm/Support/SaveAndRestore.h"
4948
#include "llvm/Support/raw_ostream.h"
5049
#include <cstring>
5150
#include <functional>
@@ -722,10 +721,6 @@ namespace {
722721
/// Whether or not we're currently speculatively evaluating.
723722
bool IsSpeculativelyEvaluating;
724723

725-
/// Whether or not we're in a context where the front end requires a
726-
/// constant value.
727-
bool InConstantContext;
728-
729724
enum EvaluationMode {
730725
/// Evaluate as a constant expression. Stop if we find that the expression
731726
/// is not a constant expression.
@@ -787,7 +782,7 @@ namespace {
787782
EvaluatingDecl((const ValueDecl *)nullptr),
788783
EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
789784
HasFoldFailureDiagnostic(false), IsSpeculativelyEvaluating(false),
790-
InConstantContext(false), EvalMode(Mode) {}
785+
EvalMode(Mode) {}
791786

792787
void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
793788
EvaluatingDecl = Base;
@@ -5630,10 +5625,8 @@ static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx,
56305625
return false;
56315626

56325627
auto EvaluateAsSizeT = [&](const Expr *E, APSInt &Into) {
5633-
Expr::EvalResult ExprResult;
5634-
if (!E->EvaluateAsInt(ExprResult, Ctx, Expr::SE_AllowSideEffects))
5628+
if (!E->EvaluateAsInt(Into, Ctx, Expr::SE_AllowSideEffects))
56355629
return false;
5636-
Into = ExprResult.Val.getInt();
56375630
if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
56385631
return false;
56395632
Into = Into.zextOrSelf(BitsInSizeT);
@@ -7355,8 +7348,6 @@ class IntExprEvaluator
73557348
// Visitor Methods
73567349
//===--------------------------------------------------------------------===//
73577350

7358-
bool VisitConstantExpr(const ConstantExpr *E);
7359-
73607351
bool VisitIntegerLiteral(const IntegerLiteral *E) {
73617352
return Success(E->getValue(), E);
73627353
}
@@ -8097,11 +8088,6 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
80978088
return true;
80988089
}
80998090

8100-
bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) {
8101-
llvm::SaveAndRestore<bool> InConstantContext(Info.InConstantContext, true);
8102-
return ExprEvaluatorBaseTy::VisitConstantExpr(E);
8103-
}
8104-
81058091
bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
81068092
if (unsigned BuiltinOp = E->getBuiltinCallee())
81078093
return VisitBuiltinCallExpr(E, BuiltinOp);
@@ -8189,19 +8175,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
81898175
return Success(Val.countLeadingZeros(), E);
81908176
}
81918177

8192-
case Builtin::BI__builtin_constant_p: {
8193-
auto Arg = E->getArg(0);
8194-
if (EvaluateBuiltinConstantP(Info.Ctx, Arg))
8195-
return Success(true, E);
8196-
auto ArgTy = Arg->IgnoreImplicit()->getType();
8197-
if (!Info.InConstantContext && !Arg->HasSideEffects(Info.Ctx) &&
8198-
!ArgTy->isAggregateType() && !ArgTy->isPointerType()) {
8199-
// We can delay calculation of __builtin_constant_p until after
8200-
// inlining. Note: This diagnostic won't be shown to the user.
8201-
Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
8202-
}
8203-
return Success(false, E);
8204-
}
8178+
case Builtin::BI__builtin_constant_p:
8179+
return Success(EvaluateBuiltinConstantP(Info.Ctx, E->getArg(0)), E);
82058180

82068181
case Builtin::BI__builtin_ctz:
82078182
case Builtin::BI__builtin_ctzl:
@@ -10771,46 +10746,19 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
1077110746
return false;
1077210747
}
1077310748

10774-
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result,
10775-
Expr::SideEffectsKind SEK) {
10776-
return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) ||
10777-
(SEK < Expr::SE_AllowUndefinedBehavior && Result.HasUndefinedBehavior);
10778-
}
10779-
10780-
static bool EvaluateAsRValue(const Expr *E, Expr::EvalResult &Result,
10781-
const ASTContext &Ctx, EvalInfo &Info) {
10782-
bool IsConst;
10783-
if (FastEvaluateAsRValue(E, Result, Ctx, IsConst))
10784-
return IsConst;
10785-
10786-
return EvaluateAsRValue(Info, E, Result.Val);
10787-
}
10788-
10789-
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult,
10790-
const ASTContext &Ctx,
10791-
Expr::SideEffectsKind AllowSideEffects,
10792-
EvalInfo &Info) {
10793-
if (!E->getType()->isIntegralOrEnumerationType())
10794-
return false;
10795-
10796-
if (!::EvaluateAsRValue(E, ExprResult, Ctx, Info) ||
10797-
!ExprResult.Val.isInt() ||
10798-
hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
10799-
return false;
10800-
10801-
return true;
10802-
}
1080310749

1080410750
/// EvaluateAsRValue - Return true if this is a constant which we can fold using
1080510751
/// any crazy technique (that has nothing to do with language standards) that
1080610752
/// we want to. If this function returns true, it returns the folded constant
1080710753
/// in Result. If this expression is a glvalue, an lvalue-to-rvalue conversion
1080810754
/// will be applied to the result.
10809-
bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
10810-
bool InConstantContext) const {
10755+
bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const {
10756+
bool IsConst;
10757+
if (FastEvaluateAsRValue(this, Result, Ctx, IsConst))
10758+
return IsConst;
10759+
1081110760
EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
10812-
Info.InConstantContext = InConstantContext;
10813-
return ::EvaluateAsRValue(this, Result, Ctx, Info);
10761+
return ::EvaluateAsRValue(Info, this, Result.Val);
1081410762
}
1081510763

1081610764
bool Expr::EvaluateAsBooleanCondition(bool &Result,
@@ -10820,10 +10768,24 @@ bool Expr::EvaluateAsBooleanCondition(bool &Result,
1082010768
HandleConversionToBool(Scratch.Val, Result);
1082110769
}
1082210770

10823-
bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
10771+
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result,
10772+
Expr::SideEffectsKind SEK) {
10773+
return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) ||
10774+
(SEK < Expr::SE_AllowUndefinedBehavior && Result.HasUndefinedBehavior);
10775+
}
10776+
10777+
bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx,
1082410778
SideEffectsKind AllowSideEffects) const {
10825-
EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
10826-
return ::EvaluateAsInt(this, Result, Ctx, AllowSideEffects, Info);
10779+
if (!getType()->isIntegralOrEnumerationType())
10780+
return false;
10781+
10782+
EvalResult ExprResult;
10783+
if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() ||
10784+
hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
10785+
return false;
10786+
10787+
Result = ExprResult.Val.getInt();
10788+
return true;
1082710789
}
1082810790

1082910791
bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx,
@@ -10881,7 +10843,6 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
1088110843
? EvalInfo::EM_ConstantExpression
1088210844
: EvalInfo::EM_ConstantFold);
1088310845
InitInfo.setEvaluatingDecl(VD, Value);
10884-
InitInfo.InConstantContext = true;
1088510846

1088610847
LValue LVal;
1088710848
LVal.set(VD);
@@ -10911,46 +10872,41 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
1091110872
/// constant folded, but discard the result.
1091210873
bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const {
1091310874
EvalResult Result;
10914-
return EvaluateAsRValue(Result, Ctx, /* in constant context */ true) &&
10875+
return EvaluateAsRValue(Result, Ctx) &&
1091510876
!hasUnacceptableSideEffect(Result, SEK);
1091610877
}
1091710878

1091810879
APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,
1091910880
SmallVectorImpl<PartialDiagnosticAt> *Diag) const {
10920-
EvalResult EVResult;
10921-
EVResult.Diag = Diag;
10922-
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
10923-
Info.InConstantContext = true;
10924-
10925-
bool Result = ::EvaluateAsRValue(this, EVResult, Ctx, Info);
10881+
EvalResult EvalResult;
10882+
EvalResult.Diag = Diag;
10883+
bool Result = EvaluateAsRValue(EvalResult, Ctx);
1092610884
(void)Result;
1092710885
assert(Result && "Could not evaluate expression");
10928-
assert(EVResult.Val.isInt() && "Expression did not evaluate to integer");
10886+
assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer");
1092910887

10930-
return EVResult.Val.getInt();
10888+
return EvalResult.Val.getInt();
1093110889
}
1093210890

1093310891
APSInt Expr::EvaluateKnownConstIntCheckOverflow(
1093410892
const ASTContext &Ctx, SmallVectorImpl<PartialDiagnosticAt> *Diag) const {
10935-
EvalResult EVResult;
10936-
EVResult.Diag = Diag;
10937-
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
10938-
Info.InConstantContext = true;
10939-
10940-
bool Result = ::EvaluateAsRValue(Info, this, EVResult.Val);
10893+
EvalResult EvalResult;
10894+
EvalResult.Diag = Diag;
10895+
EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
10896+
bool Result = ::EvaluateAsRValue(Info, this, EvalResult.Val);
1094110897
(void)Result;
1094210898
assert(Result && "Could not evaluate expression");
10943-
assert(EVResult.Val.isInt() && "Expression did not evaluate to integer");
10899+
assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer");
1094410900

10945-
return EVResult.Val.getInt();
10901+
return EvalResult.Val.getInt();
1094610902
}
1094710903

1094810904
void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
1094910905
bool IsConst;
10950-
EvalResult EVResult;
10951-
if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
10952-
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
10953-
(void)::EvaluateAsRValue(Info, this, EVResult.Val);
10906+
EvalResult EvalResult;
10907+
if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst)) {
10908+
EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
10909+
(void)::EvaluateAsRValue(Info, this, EvalResult.Val);
1095410910
}
1095510911
}
1095610912

@@ -11003,11 +10959,7 @@ static ICEDiag Worst(ICEDiag A, ICEDiag B) { return A.Kind >= B.Kind ? A : B; }
1100310959

1100410960
static ICEDiag CheckEvalInICE(const Expr* E, const ASTContext &Ctx) {
1100510961
Expr::EvalResult EVResult;
11006-
Expr::EvalStatus Status;
11007-
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
11008-
11009-
Info.InConstantContext = true;
11010-
if (!::EvaluateAsRValue(E, EVResult, Ctx, Info) || EVResult.HasSideEffects ||
10962+
if (!E->EvaluateAsRValue(EVResult, Ctx) || EVResult.HasSideEffects ||
1101110963
!EVResult.Val.isInt())
1101210964
return ICEDiag(IK_NotICE, E->getBeginLoc());
1101310965

@@ -11445,20 +11397,12 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, const ASTContext &Ctx,
1144511397

1144611398
if (!isIntegerConstantExpr(Ctx, Loc))
1144711399
return false;
11448-
1144911400
// The only possible side-effects here are due to UB discovered in the
1145011401
// evaluation (for instance, INT_MAX + 1). In such a case, we are still
1145111402
// required to treat the expression as an ICE, so we produce the folded
1145211403
// value.
11453-
EvalResult ExprResult;
11454-
Expr::EvalStatus Status;
11455-
EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
11456-
Info.InConstantContext = true;
11457-
11458-
if (!::EvaluateAsInt(this, ExprResult, Ctx, SE_AllowSideEffects, Info))
11404+
if (!EvaluateAsInt(Value, Ctx, SE_AllowSideEffects))
1145911405
llvm_unreachable("ICE cannot be evaluated!");
11460-
11461-
Value = ExprResult.Val.getInt();
1146211406
return true;
1146311407
}
1146411408

@@ -11544,7 +11488,6 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
1154411488

1154511489
EvalInfo Info(FD->getASTContext(), Status,
1154611490
EvalInfo::EM_PotentialConstantExpression);
11547-
Info.InConstantContext = true;
1154811491

1154911492
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1155011493
const CXXRecordDecl *RD = MD ? MD->getParent()->getCanonicalDecl() : nullptr;

0 commit comments

Comments
 (0)