45
45
#include " clang/AST/TypeLoc.h"
46
46
#include " clang/Basic/Builtins.h"
47
47
#include " clang/Basic/TargetInfo.h"
48
- #include " llvm/Support/SaveAndRestore.h"
49
48
#include " llvm/Support/raw_ostream.h"
50
49
#include < cstring>
51
50
#include < functional>
@@ -722,10 +721,6 @@ namespace {
722
721
// / Whether or not we're currently speculatively evaluating.
723
722
bool IsSpeculativelyEvaluating;
724
723
725
- // / Whether or not we're in a context where the front end requires a
726
- // / constant value.
727
- bool InConstantContext;
728
-
729
724
enum EvaluationMode {
730
725
// / Evaluate as a constant expression. Stop if we find that the expression
731
726
// / is not a constant expression.
@@ -787,7 +782,7 @@ namespace {
787
782
EvaluatingDecl((const ValueDecl *)nullptr),
788
783
EvaluatingDeclValue(nullptr ), HasActiveDiagnostic(false ),
789
784
HasFoldFailureDiagnostic(false ), IsSpeculativelyEvaluating(false ),
790
- InConstantContext( false ), EvalMode(Mode) {}
785
+ EvalMode(Mode) {}
791
786
792
787
void setEvaluatingDecl (APValue::LValueBase Base, APValue &Value) {
793
788
EvaluatingDecl = Base;
@@ -5630,10 +5625,8 @@ static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx,
5630
5625
return false ;
5631
5626
5632
5627
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))
5635
5629
return false ;
5636
- Into = ExprResult.Val .getInt ();
5637
5630
if (Into.isNegative () || !Into.isIntN (BitsInSizeT))
5638
5631
return false ;
5639
5632
Into = Into.zextOrSelf (BitsInSizeT);
@@ -7355,8 +7348,6 @@ class IntExprEvaluator
7355
7348
// Visitor Methods
7356
7349
// ===--------------------------------------------------------------------===//
7357
7350
7358
- bool VisitConstantExpr (const ConstantExpr *E);
7359
-
7360
7351
bool VisitIntegerLiteral (const IntegerLiteral *E) {
7361
7352
return Success (E->getValue (), E);
7362
7353
}
@@ -8097,11 +8088,6 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
8097
8088
return true ;
8098
8089
}
8099
8090
8100
- bool IntExprEvaluator::VisitConstantExpr (const ConstantExpr *E) {
8101
- llvm::SaveAndRestore<bool > InConstantContext (Info.InConstantContext , true );
8102
- return ExprEvaluatorBaseTy::VisitConstantExpr (E);
8103
- }
8104
-
8105
8091
bool IntExprEvaluator::VisitCallExpr (const CallExpr *E) {
8106
8092
if (unsigned BuiltinOp = E->getBuiltinCallee ())
8107
8093
return VisitBuiltinCallExpr (E, BuiltinOp);
@@ -8189,19 +8175,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
8189
8175
return Success (Val.countLeadingZeros (), E);
8190
8176
}
8191
8177
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);
8205
8180
8206
8181
case Builtin::BI__builtin_ctz:
8207
8182
case Builtin::BI__builtin_ctzl:
@@ -10771,46 +10746,19 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
10771
10746
return false ;
10772
10747
}
10773
10748
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
- }
10803
10749
10804
10750
// / EvaluateAsRValue - Return true if this is a constant which we can fold using
10805
10751
// / any crazy technique (that has nothing to do with language standards) that
10806
10752
// / we want to. If this function returns true, it returns the folded constant
10807
10753
// / in Result. If this expression is a glvalue, an lvalue-to-rvalue conversion
10808
10754
// / 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
+
10811
10760
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 );
10814
10762
}
10815
10763
10816
10764
bool Expr::EvaluateAsBooleanCondition (bool &Result,
@@ -10820,10 +10768,24 @@ bool Expr::EvaluateAsBooleanCondition(bool &Result,
10820
10768
HandleConversionToBool (Scratch.Val , Result);
10821
10769
}
10822
10770
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,
10824
10778
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 ;
10827
10789
}
10828
10790
10829
10791
bool Expr::EvaluateAsFloat (APFloat &Result, const ASTContext &Ctx,
@@ -10881,7 +10843,6 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
10881
10843
? EvalInfo::EM_ConstantExpression
10882
10844
: EvalInfo::EM_ConstantFold);
10883
10845
InitInfo.setEvaluatingDecl (VD, Value);
10884
- InitInfo.InConstantContext = true ;
10885
10846
10886
10847
LValue LVal;
10887
10848
LVal.set (VD);
@@ -10911,46 +10872,41 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
10911
10872
// / constant folded, but discard the result.
10912
10873
bool Expr::isEvaluatable (const ASTContext &Ctx, SideEffectsKind SEK) const {
10913
10874
EvalResult Result;
10914
- return EvaluateAsRValue (Result, Ctx, /* in constant context */ true ) &&
10875
+ return EvaluateAsRValue (Result, Ctx) &&
10915
10876
!hasUnacceptableSideEffect (Result, SEK);
10916
10877
}
10917
10878
10918
10879
APSInt Expr::EvaluateKnownConstInt (const ASTContext &Ctx,
10919
10880
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);
10926
10884
(void )Result;
10927
10885
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" );
10929
10887
10930
- return EVResult .Val .getInt ();
10888
+ return EvalResult .Val .getInt ();
10931
10889
}
10932
10890
10933
10891
APSInt Expr::EvaluateKnownConstIntCheckOverflow (
10934
10892
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 );
10941
10897
(void )Result;
10942
10898
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" );
10944
10900
10945
- return EVResult .Val .getInt ();
10901
+ return EvalResult .Val .getInt ();
10946
10902
}
10947
10903
10948
10904
void Expr::EvaluateForOverflow (const ASTContext &Ctx) const {
10949
10905
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 );
10954
10910
}
10955
10911
}
10956
10912
@@ -11003,11 +10959,7 @@ static ICEDiag Worst(ICEDiag A, ICEDiag B) { return A.Kind >= B.Kind ? A : B; }
11003
10959
11004
10960
static ICEDiag CheckEvalInICE (const Expr* E, const ASTContext &Ctx) {
11005
10961
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 ||
11011
10963
!EVResult.Val .isInt ())
11012
10964
return ICEDiag (IK_NotICE, E->getBeginLoc ());
11013
10965
@@ -11445,20 +11397,12 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, const ASTContext &Ctx,
11445
11397
11446
11398
if (!isIntegerConstantExpr (Ctx, Loc))
11447
11399
return false ;
11448
-
11449
11400
// The only possible side-effects here are due to UB discovered in the
11450
11401
// evaluation (for instance, INT_MAX + 1). In such a case, we are still
11451
11402
// required to treat the expression as an ICE, so we produce the folded
11452
11403
// 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))
11459
11405
llvm_unreachable (" ICE cannot be evaluated!" );
11460
-
11461
- Value = ExprResult.Val .getInt ();
11462
11406
return true ;
11463
11407
}
11464
11408
@@ -11544,7 +11488,6 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
11544
11488
11545
11489
EvalInfo Info (FD->getASTContext (), Status,
11546
11490
EvalInfo::EM_PotentialConstantExpression);
11547
- Info.InConstantContext = true ;
11548
11491
11549
11492
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
11550
11493
const CXXRecordDecl *RD = MD ? MD->getParent ()->getCanonicalDecl () : nullptr ;
0 commit comments