From f5d3335d75dfe13b1263bbc305514ccfbc25417d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 30 Nov 2018 21:26:09 +0000 Subject: [PATCH] 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 --- clang/include/clang/AST/Expr.h | 16 +- clang/lib/AST/ASTImporter.cpp | 2 +- clang/lib/AST/Expr.cpp | 22 +-- clang/lib/AST/ExprConstant.cpp | 147 +++++----------- clang/lib/Analysis/CFG.cpp | 19 +-- clang/lib/CodeGen/CGBuiltin.cpp | 54 ++---- clang/lib/CodeGen/CGDebugInfo.cpp | 6 +- clang/lib/CodeGen/CGExprScalar.cpp | 11 +- clang/lib/CodeGen/CGOpenMPRuntime.cpp | 11 +- clang/lib/CodeGen/CGStmt.cpp | 4 +- clang/lib/CodeGen/CGStmtOpenMP.cpp | 6 +- clang/lib/CodeGen/CodeGenFunction.cpp | 5 +- clang/lib/Sema/AnalysisBasedWarnings.cpp | 7 +- clang/lib/Sema/SemaCast.cpp | 5 +- clang/lib/Sema/SemaChecking.cpp | 47 ++---- clang/lib/Sema/SemaDecl.cpp | 6 +- clang/lib/Sema/SemaDeclCXX.cpp | 2 - clang/lib/Sema/SemaExpr.cpp | 74 +++----- clang/lib/Sema/SemaInit.cpp | 5 +- clang/lib/Sema/SemaOpenMP.cpp | 47 ++---- clang/lib/Sema/SemaOverload.cpp | 2 +- clang/lib/Sema/SemaStmt.cpp | 5 +- clang/lib/Sema/SemaStmtAsm.cpp | 5 +- clang/lib/Sema/SemaTemplateDeduction.cpp | 4 - clang/lib/Sema/SemaType.cpp | 4 + .../Checkers/BuiltinFunctionChecker.cpp | 5 +- .../Checkers/CheckSecuritySyntaxOnly.cpp | 5 +- .../MallocOverflowSecurityChecker.cpp | 9 +- .../NumberObjectConversionChecker.cpp | 5 +- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 3 + clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 5 +- clang/lib/StaticAnalyzer/Core/SValBuilder.cpp | 4 +- clang/test/Analysis/builtin-functions.cpp | 6 +- clang/test/CodeGen/builtin-constant-p.c | 159 ------------------ clang/test/CodeGenCXX/builtin-constant-p.cpp | 24 --- clang/test/Sema/builtins.c | 9 - clang/test/SemaCXX/compound-literal.cpp | 5 +- 37 files changed, 197 insertions(+), 558 deletions(-) delete mode 100644 clang/test/CodeGen/builtin-constant-p.c delete mode 100644 clang/test/CodeGenCXX/builtin-constant-p.cpp diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 7df7b56ca1f4..6165ff4bb636 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -583,8 +583,7 @@ public: /// this function returns true, it returns the folded constant in Result. If /// the expression is a glvalue, an lvalue-to-rvalue conversion will be /// applied. - bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, - bool InConstantContext = false) const; + bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const; /// EvaluateAsBooleanCondition - Return true if this is a constant /// which we can fold and convert to a boolean condition using @@ -601,7 +600,7 @@ public: /// EvaluateAsInt - Return true if this is a constant which we can fold and /// convert to an integer, using any crazy technique that we want to. - bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, + bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; /// EvaluateAsFloat - Return true if this is a constant which we can fold and @@ -902,15 +901,10 @@ public: /// ConstantExpr - An expression that occurs in a constant context. class ConstantExpr : public FullExpr { +public: ConstantExpr(Expr *subexpr) : FullExpr(ConstantExprClass, subexpr) {} -public: - static ConstantExpr *Create(const ASTContext &Context, Expr *E) { - assert(!isa(E)); - return new (Context) ConstantExpr(E); - } - /// Build an empty constant expression wrapper. explicit ConstantExpr(EmptyShell Empty) : FullExpr(ConstantExprClass, Empty) {} @@ -3093,8 +3087,8 @@ inline Expr *Expr::IgnoreImpCasts() { while (true) if (ImplicitCastExpr *ice = dyn_cast(e)) e = ice->getSubExpr(); - else if (FullExpr *fe = dyn_cast(e)) - e = fe->getSubExpr(); + else if (ConstantExpr *ce = dyn_cast(e)) + e = ce->getSubExpr(); else break; return e; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 633b2e48db4d..a50da5a32161 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -6388,7 +6388,7 @@ ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) { Expr *ToSubExpr; std::tie(ToSubExpr) = *Imp; - return ConstantExpr::Create(Importer.getToContext(), ToSubExpr); + return new (Importer.getToContext()) ConstantExpr(ToSubExpr); } ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) { diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 4de1342c77fe..d8df83def4b9 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2594,8 +2594,8 @@ Expr *Expr::IgnoreParenCasts() { E = NTTP->getReplacement(); continue; } - if (FullExpr *FE = dyn_cast(E)) { - E = FE->getSubExpr(); + if (ConstantExpr *CE = dyn_cast(E)) { + E = CE->getSubExpr(); continue; } return E; @@ -2619,8 +2619,8 @@ Expr *Expr::IgnoreCasts() { E = NTTP->getReplacement(); continue; } - if (FullExpr *FE = dyn_cast(E)) { - E = FE->getSubExpr(); + if (ConstantExpr *CE = dyn_cast(E)) { + E = CE->getSubExpr(); continue; } return E; @@ -2648,8 +2648,8 @@ Expr *Expr::IgnoreParenLValueCasts() { = dyn_cast(E)) { E = NTTP->getReplacement(); continue; - } else if (FullExpr *FE = dyn_cast(E)) { - E = FE->getSubExpr(); + } else if (ConstantExpr *CE = dyn_cast(E)) { + E = CE->getSubExpr(); continue; } break; @@ -2920,12 +2920,6 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, break; } - case ConstantExprClass: { - // FIXME: We should be able to return "true" here, but it can lead to extra - // error messages. E.g. in Sema/array-init.c. - const Expr *Exp = cast(this)->getSubExpr(); - return Exp->isConstantInitializer(Ctx, false, Culprit); - } case CompoundLiteralExprClass: { // This handles gcc's extension that allows global initializers like // "struct x {int x;} x = (struct x) {};". @@ -2965,8 +2959,8 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, const Expr *Elt = ILE->getInit(ElementNo++); if (Field->isBitField()) { // Bitfields have to evaluate to an integer. - EvalResult Result; - if (!Elt->EvaluateAsInt(Result, Ctx)) { + llvm::APSInt ResultTmp; + if (!Elt->EvaluateAsInt(ResultTmp, Ctx)) { if (Culprit) *Culprit = Elt; return false; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 91b3fbfa4663..b0dc7d4a4a95 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -45,7 +45,6 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetInfo.h" -#include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -722,10 +721,6 @@ namespace { /// Whether or not we're currently speculatively evaluating. bool IsSpeculativelyEvaluating; - /// Whether or not we're in a context where the front end requires a - /// constant value. - bool InConstantContext; - enum EvaluationMode { /// Evaluate as a constant expression. Stop if we find that the expression /// is not a constant expression. @@ -787,7 +782,7 @@ namespace { EvaluatingDecl((const ValueDecl *)nullptr), EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false), HasFoldFailureDiagnostic(false), IsSpeculativelyEvaluating(false), - InConstantContext(false), EvalMode(Mode) {} + EvalMode(Mode) {} void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) { EvaluatingDecl = Base; @@ -5630,10 +5625,8 @@ static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, return false; auto EvaluateAsSizeT = [&](const Expr *E, APSInt &Into) { - Expr::EvalResult ExprResult; - if (!E->EvaluateAsInt(ExprResult, Ctx, Expr::SE_AllowSideEffects)) + if (!E->EvaluateAsInt(Into, Ctx, Expr::SE_AllowSideEffects)) return false; - Into = ExprResult.Val.getInt(); if (Into.isNegative() || !Into.isIntN(BitsInSizeT)) return false; Into = Into.zextOrSelf(BitsInSizeT); @@ -7355,8 +7348,6 @@ public: // Visitor Methods //===--------------------------------------------------------------------===// - bool VisitConstantExpr(const ConstantExpr *E); - bool VisitIntegerLiteral(const IntegerLiteral *E) { return Success(E->getValue(), E); } @@ -8097,11 +8088,6 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, return true; } -bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) { - llvm::SaveAndRestore InConstantContext(Info.InConstantContext, true); - return ExprEvaluatorBaseTy::VisitConstantExpr(E); -} - bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { if (unsigned BuiltinOp = E->getBuiltinCallee()) return VisitBuiltinCallExpr(E, BuiltinOp); @@ -8189,19 +8175,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, return Success(Val.countLeadingZeros(), E); } - case Builtin::BI__builtin_constant_p: { - auto Arg = E->getArg(0); - if (EvaluateBuiltinConstantP(Info.Ctx, Arg)) - return Success(true, E); - auto ArgTy = Arg->IgnoreImplicit()->getType(); - if (!Info.InConstantContext && !Arg->HasSideEffects(Info.Ctx) && - !ArgTy->isAggregateType() && !ArgTy->isPointerType()) { - // We can delay calculation of __builtin_constant_p until after - // inlining. Note: This diagnostic won't be shown to the user. - Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); - } - return Success(false, E); - } + case Builtin::BI__builtin_constant_p: + return Success(EvaluateBuiltinConstantP(Info.Ctx, E->getArg(0)), E); case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: @@ -10771,46 +10746,19 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, return false; } -static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, - Expr::SideEffectsKind SEK) { - return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) || - (SEK < Expr::SE_AllowUndefinedBehavior && Result.HasUndefinedBehavior); -} - -static bool EvaluateAsRValue(const Expr *E, Expr::EvalResult &Result, - const ASTContext &Ctx, EvalInfo &Info) { - bool IsConst; - if (FastEvaluateAsRValue(E, Result, Ctx, IsConst)) - return IsConst; - - return EvaluateAsRValue(Info, E, Result.Val); -} - -static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, - const ASTContext &Ctx, - Expr::SideEffectsKind AllowSideEffects, - EvalInfo &Info) { - if (!E->getType()->isIntegralOrEnumerationType()) - return false; - - if (!::EvaluateAsRValue(E, ExprResult, Ctx, Info) || - !ExprResult.Val.isInt() || - hasUnacceptableSideEffect(ExprResult, AllowSideEffects)) - return false; - - return true; -} /// EvaluateAsRValue - Return true if this is a constant which we can fold using /// any crazy technique (that has nothing to do with language standards) that /// we want to. If this function returns true, it returns the folded constant /// in Result. If this expression is a glvalue, an lvalue-to-rvalue conversion /// will be applied to the result. -bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, - bool InConstantContext) const { +bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const { + bool IsConst; + if (FastEvaluateAsRValue(this, Result, Ctx, IsConst)) + return IsConst; + EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects); - Info.InConstantContext = InConstantContext; - return ::EvaluateAsRValue(this, Result, Ctx, Info); + return ::EvaluateAsRValue(Info, this, Result.Val); } bool Expr::EvaluateAsBooleanCondition(bool &Result, @@ -10820,10 +10768,24 @@ bool Expr::EvaluateAsBooleanCondition(bool &Result, HandleConversionToBool(Scratch.Val, Result); } -bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, +static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, + Expr::SideEffectsKind SEK) { + return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) || + (SEK < Expr::SE_AllowUndefinedBehavior && Result.HasUndefinedBehavior); +} + +bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects) const { - EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects); - return ::EvaluateAsInt(this, Result, Ctx, AllowSideEffects, Info); + if (!getType()->isIntegralOrEnumerationType()) + return false; + + EvalResult ExprResult; + if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() || + hasUnacceptableSideEffect(ExprResult, AllowSideEffects)) + return false; + + Result = ExprResult.Val.getInt(); + return true; } bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx, @@ -10881,7 +10843,6 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx, ? EvalInfo::EM_ConstantExpression : EvalInfo::EM_ConstantFold); InitInfo.setEvaluatingDecl(VD, Value); - InitInfo.InConstantContext = true; LValue LVal; LVal.set(VD); @@ -10911,46 +10872,41 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx, /// constant folded, but discard the result. bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const { EvalResult Result; - return EvaluateAsRValue(Result, Ctx, /* in constant context */ true) && + return EvaluateAsRValue(Result, Ctx) && !hasUnacceptableSideEffect(Result, SEK); } APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl *Diag) const { - EvalResult EVResult; - EVResult.Diag = Diag; - EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects); - Info.InConstantContext = true; - - bool Result = ::EvaluateAsRValue(this, EVResult, Ctx, Info); + EvalResult EvalResult; + EvalResult.Diag = Diag; + bool Result = EvaluateAsRValue(EvalResult, Ctx); (void)Result; assert(Result && "Could not evaluate expression"); - assert(EVResult.Val.isInt() && "Expression did not evaluate to integer"); + assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer"); - return EVResult.Val.getInt(); + return EvalResult.Val.getInt(); } APSInt Expr::EvaluateKnownConstIntCheckOverflow( const ASTContext &Ctx, SmallVectorImpl *Diag) const { - EvalResult EVResult; - EVResult.Diag = Diag; - EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow); - Info.InConstantContext = true; - - bool Result = ::EvaluateAsRValue(Info, this, EVResult.Val); + EvalResult EvalResult; + EvalResult.Diag = Diag; + EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow); + bool Result = ::EvaluateAsRValue(Info, this, EvalResult.Val); (void)Result; assert(Result && "Could not evaluate expression"); - assert(EVResult.Val.isInt() && "Expression did not evaluate to integer"); + assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer"); - return EVResult.Val.getInt(); + return EvalResult.Val.getInt(); } void Expr::EvaluateForOverflow(const ASTContext &Ctx) const { bool IsConst; - EvalResult EVResult; - if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) { - EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow); - (void)::EvaluateAsRValue(Info, this, EVResult.Val); + EvalResult EvalResult; + if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst)) { + EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow); + (void)::EvaluateAsRValue(Info, this, EvalResult.Val); } } @@ -11003,11 +10959,7 @@ static ICEDiag Worst(ICEDiag A, ICEDiag B) { return A.Kind >= B.Kind ? A : B; } static ICEDiag CheckEvalInICE(const Expr* E, const ASTContext &Ctx) { Expr::EvalResult EVResult; - Expr::EvalStatus Status; - EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression); - - Info.InConstantContext = true; - if (!::EvaluateAsRValue(E, EVResult, Ctx, Info) || EVResult.HasSideEffects || + if (!E->EvaluateAsRValue(EVResult, Ctx) || EVResult.HasSideEffects || !EVResult.Val.isInt()) return ICEDiag(IK_NotICE, E->getBeginLoc()); @@ -11445,20 +11397,12 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, const ASTContext &Ctx, if (!isIntegerConstantExpr(Ctx, Loc)) return false; - // The only possible side-effects here are due to UB discovered in the // evaluation (for instance, INT_MAX + 1). In such a case, we are still // required to treat the expression as an ICE, so we produce the folded // value. - EvalResult ExprResult; - Expr::EvalStatus Status; - EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects); - Info.InConstantContext = true; - - if (!::EvaluateAsInt(this, ExprResult, Ctx, SE_AllowSideEffects, Info)) + if (!EvaluateAsInt(Value, Ctx, SE_AllowSideEffects)) llvm_unreachable("ICE cannot be evaluated!"); - - Value = ExprResult.Val.getInt(); return true; } @@ -11544,7 +11488,6 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD, EvalInfo Info(FD->getASTContext(), Status, EvalInfo::EM_PotentialConstantExpression); - Info.InConstantContext = true; const CXXMethodDecl *MD = dyn_cast(FD); const CXXRecordDecl *RD = MD ? MD->getParent()->getCanonicalDecl() : nullptr; diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 96130c25be8a..cfda27dd37a2 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -1039,13 +1039,11 @@ private: if (!areExprTypesCompatible(Expr1, Expr2)) return {}; - Expr::EvalResult L1Result, L2Result; - if (!Expr1->EvaluateAsInt(L1Result, *Context) || - !Expr2->EvaluateAsInt(L2Result, *Context)) - return {}; + llvm::APSInt L1, L2; - llvm::APSInt L1 = L1Result.Val.getInt(); - llvm::APSInt L2 = L2Result.Val.getInt(); + if (!Expr1->EvaluateAsInt(L1, *Context) || + !Expr2->EvaluateAsInt(L2, *Context)) + return {}; // Can't compare signed with unsigned or with different bit width. if (L1.isSigned() != L2.isSigned() || L1.getBitWidth() != L2.getBitWidth()) @@ -1136,16 +1134,13 @@ private: case BO_And: { // If either operand is zero, we know the value // must be false. - Expr::EvalResult LHSResult; - if (Bop->getLHS()->EvaluateAsInt(LHSResult, *Context)) { - llvm::APSInt IntVal = LHSResult.Val.getInt(); + llvm::APSInt IntVal; + if (Bop->getLHS()->EvaluateAsInt(IntVal, *Context)) { if (!IntVal.getBoolValue()) { return TryResult(false); } } - Expr::EvalResult RHSResult; - if (Bop->getRHS()->EvaluateAsInt(RHSResult, *Context)) { - llvm::APSInt IntVal = RHSResult.Val.getInt(); + if (Bop->getRHS()->EvaluateAsInt(IntVal, *Context)) { if (!IntVal.getBoolValue()) { return TryResult(false); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index cb15f19224e7..cf7c0b0c2887 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1896,26 +1896,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI_rotr64: return emitRotate(E, true); - case Builtin::BI__builtin_constant_p: { - llvm::Type *ResultType = ConvertType(E->getType()); - if (CGM.getCodeGenOpts().OptimizationLevel == 0) - // At -O0, we don't perform inlining, so we don't need to delay the - // processing. - return RValue::get(ConstantInt::get(ResultType, 0)); - - const Expr *Arg = E->getArg(0); - QualType ArgType = Arg->getType(); - if (!hasScalarEvaluationKind(ArgType) || ArgType->isFunctionType()) - // We can only reason about scalar types. - return RValue::get(ConstantInt::get(ResultType, 0)); - - Value *ArgValue = EmitScalarExpr(Arg); - Value *F = CGM.getIntrinsic(Intrinsic::is_constant, ConvertType(ArgType)); - Value *Result = Builder.CreateCall(F, ArgValue); - if (Result->getType() != ResultType) - Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/false); - return RValue::get(Result); - } case Builtin::BI__builtin_object_size: { unsigned Type = E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue(); @@ -2180,12 +2160,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin___memcpy_chk: { // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. - Expr::EvalResult SizeResult, DstSizeResult; - if (!E->getArg(2)->EvaluateAsInt(SizeResult, CGM.getContext()) || - !E->getArg(3)->EvaluateAsInt(DstSizeResult, CGM.getContext())) + llvm::APSInt Size, DstSize; + if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || + !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) break; - llvm::APSInt Size = SizeResult.Val.getInt(); - llvm::APSInt DstSize = DstSizeResult.Val.getInt(); if (Size.ugt(DstSize)) break; Address Dest = EmitPointerWithAlignment(E->getArg(0)); @@ -2206,12 +2184,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin___memmove_chk: { // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2. - Expr::EvalResult SizeResult, DstSizeResult; - if (!E->getArg(2)->EvaluateAsInt(SizeResult, CGM.getContext()) || - !E->getArg(3)->EvaluateAsInt(DstSizeResult, CGM.getContext())) + llvm::APSInt Size, DstSize; + if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || + !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) break; - llvm::APSInt Size = SizeResult.Val.getInt(); - llvm::APSInt DstSize = DstSizeResult.Val.getInt(); if (Size.ugt(DstSize)) break; Address Dest = EmitPointerWithAlignment(E->getArg(0)); @@ -2246,12 +2222,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, } case Builtin::BI__builtin___memset_chk: { // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2. - Expr::EvalResult SizeResult, DstSizeResult; - if (!E->getArg(2)->EvaluateAsInt(SizeResult, CGM.getContext()) || - !E->getArg(3)->EvaluateAsInt(DstSizeResult, CGM.getContext())) + llvm::APSInt Size, DstSize; + if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || + !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) break; - llvm::APSInt Size = SizeResult.Val.getInt(); - llvm::APSInt DstSize = DstSizeResult.Val.getInt(); if (Size.ugt(DstSize)) break; Address Dest = EmitPointerWithAlignment(E->getArg(0)); @@ -5765,11 +5739,10 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, /*Variadic=*/false); - Expr::EvalResult Result; - if (!E->getArg(0)->EvaluateAsInt(Result, CGM.getContext())) + APSInt Value; + if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext())) llvm_unreachable("Sema will ensure that the parameter is constant"); - llvm::APSInt Value = Result.Val.getInt(); uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue(); llvm::InlineAsm *Emit = @@ -6872,11 +6845,10 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, } if (BuiltinID == AArch64::BI__getReg) { - Expr::EvalResult Result; - if (!E->getArg(0)->EvaluateAsInt(Result, CGM.getContext())) + APSInt Value; + if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext())) llvm_unreachable("Sema will ensure that the parameter is constant"); - llvm::APSInt Value = Result.Val.getInt(); LLVMContext &Context = CGM.getLLVMContext(); std::string Reg = Value == 31 ? "sp" : "x" + Value.toString(10); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index dbceaa7aa86b..88f7dcebd24f 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2523,9 +2523,9 @@ llvm::DIType *CGDebugInfo::CreateType(const ArrayType *Ty, llvm::DIFile *Unit) { Count = CAT->getSize().getZExtValue(); else if (const auto *VAT = dyn_cast(Ty)) { if (Expr *Size = VAT->getSizeExpr()) { - Expr::EvalResult Result; - if (Size->EvaluateAsInt(Result, CGM.getContext())) - Count = Result.Val.getInt().getExtValue(); + llvm::APSInt V; + if (Size->EvaluateAsInt(V, CGM.getContext())) + Count = V.getExtValue(); } } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 4980f53cc4de..e7c63ac11e9f 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -1717,9 +1717,8 @@ Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) { CGF.EmitIgnoredExpr(E->getBase()); return CGF.emitScalarConstant(Constant, E); } else { - Expr::EvalResult Result; - if (E->EvaluateAsInt(Result, CGF.getContext(), Expr::SE_AllowSideEffects)) { - llvm::APSInt Value = Result.Val.getInt(); + llvm::APSInt Value; + if (E->EvaluateAsInt(Value, CGF.getContext(), Expr::SE_AllowSideEffects)) { CGF.EmitIgnoredExpr(E->getBase()); return Builder.getInt(Value); } @@ -2598,11 +2597,9 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) { Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) { // Try folding the offsetof to a constant. - Expr::EvalResult EVResult; - if (E->EvaluateAsInt(EVResult, CGF.getContext())) { - llvm::APSInt Value = EVResult.Val.getInt(); + llvm::APSInt Value; + if (E->EvaluateAsInt(Value, CGF.getContext())) return Builder.getInt(Value); - } // Loop over the components of the offsetof to compute the value. unsigned n = E->getNumComponents(); diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index cade093941a5..e394a92a8e2f 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -6797,11 +6797,10 @@ private: } // Check if the length evaluates to 1. - Expr::EvalResult Result; - if (!Length->EvaluateAsInt(Result, CGF.getContext())) + llvm::APSInt ConstLength; + if (!Length->EvaluateAsInt(ConstLength, CGF.getContext())) return true; // Can have more that size 1. - llvm::APSInt ConstLength = Result.Val.getInt(); return ConstLength.getSExtValue() != 1; } @@ -9165,8 +9164,8 @@ void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD, ParamAttrTy &ParamAttr = ParamAttrs[Pos]; ParamAttr.Kind = Linear; if (*SI) { - Expr::EvalResult Result; - if (!(*SI)->EvaluateAsInt(Result, C, Expr::SE_AllowSideEffects)) { + if (!(*SI)->EvaluateAsInt(ParamAttr.StrideOrArg, C, + Expr::SE_AllowSideEffects)) { if (const auto *DRE = cast((*SI)->IgnoreParenImpCasts())) { if (const auto *StridePVD = cast(DRE->getDecl())) { @@ -9175,8 +9174,6 @@ void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD, ParamPositions[StridePVD->getCanonicalDecl()]); } } - } else { - ParamAttr.StrideOrArg = Result.Val.getInt(); } } ++SI; diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index caf68913819d..26598790f8ca 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -1821,9 +1821,9 @@ llvm::Value* CodeGenFunction::EmitAsmInput( // If this can't be a register or memory, i.e., has to be a constant // (immediate or symbolic), try to emit it as such. if (!Info.allowsRegister() && !Info.allowsMemory()) { - Expr::EvalResult Result; + llvm::APSInt Result; if (InputExpr->EvaluateAsInt(Result, getContext())) - return llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()); + return llvm::ConstantInt::get(getLLVMContext(), Result); assert(!Info.requiresImmediateConstant() && "Required-immediate inlineasm arg isn't constant?"); } diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index c92338a497de..9113b67684a3 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -2321,11 +2321,9 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( Chunk = EmitScalarConversion(Chunk, ChunkExpr->getType(), S.getIterationVariable()->getType(), S.getBeginLoc()); - Expr::EvalResult Result; - if (ChunkExpr->EvaluateAsInt(Result, getContext())) { - llvm::APSInt EvaluatedChunk = Result.Val.getInt(); + llvm::APSInt EvaluatedChunk; + if (ChunkExpr->EvaluateAsInt(EvaluatedChunk, getContext())) HasChunkSizeOne = (EvaluatedChunk.getLimitedValue() == 1); - } } const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 600640f78c19..7250bbc64d16 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1513,11 +1513,10 @@ bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond, bool AllowLabels) { // FIXME: Rename and handle conversion of other evaluatable things // to bool. - Expr::EvalResult Result; - if (!Cond->EvaluateAsInt(Result, getContext())) + llvm::APSInt Int; + if (!Cond->EvaluateAsInt(Int, getContext())) return false; // Not foldable, not integer or not fully evaluatable. - llvm::APSInt Int = Result.Val.getInt(); if (!AllowLabels && CodeGenFunction::ContainsLabel(Cond)) return false; // Contains a label. diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 3b6cbe9469b7..ab46554485f4 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -1309,10 +1309,11 @@ static bool isInLoop(const ASTContext &Ctx, const ParentMap &PM, case Stmt::ObjCForCollectionStmtClass: return true; case Stmt::DoStmtClass: { - Expr::EvalResult Result; - if (!cast(S)->getCond()->EvaluateAsInt(Result, Ctx)) + const Expr *Cond = cast(S)->getCond(); + llvm::APSInt Val; + if (!Cond->EvaluateAsInt(Val, Ctx)) return true; - return Result.Val.getInt().getBoolValue(); + return Val.getBoolValue(); } default: break; diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 0b4645e11c34..3b49f9315f86 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -2554,9 +2554,8 @@ void CastOperation::CheckCStyleCast() { // OpenCL v2.0 s6.13.10 - Allow casts from '0' to event_t type. if (Self.getLangOpts().OpenCL && DestType->isEventT()) { - Expr::EvalResult Result; - if (SrcExpr.get()->EvaluateAsInt(Result, Self.Context)) { - llvm::APSInt CastInt = Result.Val.getInt(); + llvm::APSInt CastInt; + if (SrcExpr.get()->EvaluateAsInt(CastInt, Self.Context)) { if (0 == CastInt) { Kind = CK_ZeroToOCLOpaqueType; return; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 4f891e092fdb..b74be1b30aaa 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -247,16 +247,13 @@ static void SemaBuiltinMemChkCall(Sema &S, FunctionDecl *FDecl, const Expr *SizeArg = TheCall->getArg(SizeIdx); const Expr *DstSizeArg = TheCall->getArg(DstSizeIdx); - Expr::EvalResult SizeResult, DstSizeResult; + llvm::APSInt Size, DstSize; // find out if both sizes are known at compile time - if (!SizeArg->EvaluateAsInt(SizeResult, S.Context) || - !DstSizeArg->EvaluateAsInt(DstSizeResult, S.Context)) + if (!SizeArg->EvaluateAsInt(Size, S.Context) || + !DstSizeArg->EvaluateAsInt(DstSize, S.Context)) return; - llvm::APSInt Size = SizeResult.Val.getInt(); - llvm::APSInt DstSize = DstSizeResult.Val.getInt(); - if (Size.ule(DstSize)) return; @@ -6484,12 +6481,13 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef Args, return SLCT_NotALiteral; } case Stmt::BinaryOperatorClass: { + llvm::APSInt LResult; + llvm::APSInt RResult; + const BinaryOperator *BinOp = cast(E); // A string literal + an int offset is still a string literal. if (BinOp->isAdditiveOp()) { - Expr::EvalResult LResult, RResult; - bool LIsInt = BinOp->getLHS()->EvaluateAsInt(LResult, S.Context); bool RIsInt = BinOp->getRHS()->EvaluateAsInt(RResult, S.Context); @@ -6498,12 +6496,12 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef Args, if (LIsInt) { if (BinOpKind == BO_Add) { - sumOffsets(Offset, LResult.Val.getInt(), BinOpKind, RIsInt); + sumOffsets(Offset, LResult, BinOpKind, RIsInt); E = BinOp->getRHS(); goto tryAgain; } } else { - sumOffsets(Offset, RResult.Val.getInt(), BinOpKind, RIsInt); + sumOffsets(Offset, RResult, BinOpKind, RIsInt); E = BinOp->getLHS(); goto tryAgain; } @@ -6516,10 +6514,9 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef Args, const UnaryOperator *UnaOp = cast(E); auto ASE = dyn_cast(UnaOp->getSubExpr()); if (UnaOp->getOpcode() == UO_AddrOf && ASE) { - Expr::EvalResult IndexResult; + llvm::APSInt IndexResult; if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.Context)) { - sumOffsets(Offset, IndexResult.Val.getInt(), BO_Add, - /*RHS is int*/ true); + sumOffsets(Offset, IndexResult, BO_Add, /*RHS is int*/ true); E = ASE->getBase(); goto tryAgain; } @@ -10264,8 +10261,8 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, Expr *OriginalInit = Init->IgnoreParenImpCasts(); unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context); - Expr::EvalResult Result; - if (!OriginalInit->EvaluateAsInt(Result, S.Context, + llvm::APSInt Value; + if (!OriginalInit->EvaluateAsInt(Value, S.Context, Expr::SE_AllowSideEffects)) { // The RHS is not constant. If the RHS has an enum type, make sure the // bitfield is wide enough to hold all the values of the enum without @@ -10321,8 +10318,6 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, return false; } - llvm::APSInt Value = Result.Val.getInt(); - unsigned OriginalWidth = Value.getBitWidth(); if (!Value.isSigned() || Value.isNegative()) @@ -10935,11 +10930,8 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, if (SourceRange.Width > TargetRange.Width) { // If the source is a constant, use a default-on diagnostic. // TODO: this should happen for bitfield stores, too. - Expr::EvalResult Result; - if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects)) { - llvm::APSInt Value(32); - Value = Result.Val.getInt(); - + llvm::APSInt Value(32); + if (E->EvaluateAsInt(Value, S.Context, Expr::SE_AllowSideEffects)) { if (S.SourceMgr.isInSystemMacro(CC)) return; @@ -10983,10 +10975,9 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, // source value is exactly the width of the target type, which will // cause a negative value to be stored. - Expr::EvalResult Result; - if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects) && + llvm::APSInt Value; + if (E->EvaluateAsInt(Value, S.Context, Expr::SE_AllowSideEffects) && !S.SourceMgr.isInSystemMacro(CC)) { - llvm::APSInt Value = Result.Val.getInt(); if (isSameWidthConstantConversion(S, E, T, CC)) { std::string PrettySourceValue = Value.toString(10); std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange); @@ -12273,11 +12264,9 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, if (!ArrayTy) return; - Expr::EvalResult Result; - if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects)) + llvm::APSInt index; + if (!IndexExpr->EvaluateAsInt(index, Context, Expr::SE_AllowSideEffects)) return; - - llvm::APSInt index = Result.Val.getInt(); if (IndexNegated) index = -index; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index becbb1f186d9..cf626e01012b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5575,13 +5575,11 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, if (VLATy->getElementType()->isVariablyModifiedType()) return QualType(); - Expr::EvalResult Result; + llvm::APSInt Res; if (!VLATy->getSizeExpr() || - !VLATy->getSizeExpr()->EvaluateAsInt(Result, Context)) + !VLATy->getSizeExpr()->EvaluateAsInt(Res, Context)) return QualType(); - llvm::APSInt Res = Result.Val.getInt(); - // Check whether the array size is negative. if (Res.isSigned() && Res.isNegative()) { SizeIsNegative = true; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index e408c0437918..73bdc50ff631 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -13860,8 +13860,6 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr); if (Converted.isInvalid()) Failed = true; - else - Converted = ConstantExpr::Create(Context, Converted.get()); llvm::APSInt Cond; if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9a83c5cb440b..8921d851ffb8 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4376,11 +4376,10 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, return ExprError(); if (LowerBound && !OriginalTy->isAnyPointerType()) { - Expr::EvalResult Result; - if (LowerBound->EvaluateAsInt(Result, Context)) { + llvm::APSInt LowerBoundValue; + if (LowerBound->EvaluateAsInt(LowerBoundValue, Context)) { // OpenMP 4.5, [2.4 Array Sections] // The array section must be a subset of the original array. - llvm::APSInt LowerBoundValue = Result.Val.getInt(); if (LowerBoundValue.isNegative()) { Diag(LowerBound->getExprLoc(), diag::err_omp_section_not_subset_of_array) << LowerBound->getSourceRange(); @@ -4390,11 +4389,10 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, } if (Length) { - Expr::EvalResult Result; - if (Length->EvaluateAsInt(Result, Context)) { + llvm::APSInt LengthValue; + if (Length->EvaluateAsInt(LengthValue, Context)) { // OpenMP 4.5, [2.4 Array Sections] // The length must evaluate to non-negative integers. - llvm::APSInt LengthValue = Result.Val.getInt(); if (LengthValue.isNegative()) { Diag(Length->getExprLoc(), diag::err_omp_section_length_negative) << LengthValue.toString(/*Radix=*/10, /*Signed=*/true) @@ -5801,13 +5799,6 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, ? VK_RValue : VK_LValue; - if (isFileScope) - if (auto ILE = dyn_cast(LiteralExpr)) - for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) { - Expr *Init = ILE->getInit(i); - ILE->setInit(i, ConstantExpr::Create(Context, Init)); - } - Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, VK, LiteralExpr, isFileScope); if (isFileScope) { @@ -5816,6 +5807,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, !literalType->isDependentType()) // C99 6.5.2.5p3 if (CheckForConstantInitializer(LiteralExpr, literalType)) return ExprError(); + E = new (Context) ConstantExpr(E); } else if (literalType.getAddressSpace() != LangAS::opencl_private && literalType.getAddressSpace() != LangAS::Default) { // Embedded-C extensions to C99 6.5.2.5: @@ -8411,8 +8403,8 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int, // Reject cases where the value of the Int is unknown as that would // possibly cause truncation, but accept cases where the scalar can be // demoted without loss of precision. - Expr::EvalResult EVResult; - bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context); + llvm::APSInt Result; + bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context); int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy); bool IntSigned = IntTy->hasSignedIntegerRepresentation(); bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation(); @@ -8420,7 +8412,6 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int, if (CstInt) { // If the scalar is constant and is of a higher order and has more active // bits that the vector element type, reject it. - llvm::APSInt Result = EVResult.Val.getInt(); unsigned NumBits = IntSigned ? (Result.isNegative() ? Result.getMinSignedBits() : Result.getActiveBits()) @@ -8448,9 +8439,8 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int, // Determine if the integer constant can be expressed as a floating point // number of the appropriate type. - Expr::EvalResult EVResult; - bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context); - + llvm::APSInt Result; + bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context); uint64_t Bits = 0; if (CstInt) { // Reject constants that would be truncated if they were converted to @@ -8458,7 +8448,6 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int, // FIXME: Ideally the conversion to an APFloat and from an APFloat // could be avoided if there was a convertFromAPInt method // which could signal back if implicit truncation occurred. - llvm::APSInt Result = EVResult.Val.getInt(); llvm::APFloat Float(S.Context.getFloatTypeSemantics(FloatTy)); Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(), llvm::APFloat::rmTowardZero); @@ -8798,10 +8787,9 @@ static void DiagnoseBadDivideOrRemainderValues(Sema& S, ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsDiv) { // Check for division/remainder by zero. - Expr::EvalResult RHSValue; + llvm::APSInt RHSValue; if (!RHS.get()->isValueDependent() && - RHS.get()->EvaluateAsInt(RHSValue, S.Context) && - RHSValue.Val.getInt() == 0) + RHS.get()->EvaluateAsInt(RHSValue, S.Context) && RHSValue == 0) S.DiagRuntimeBehavior(Loc, RHS.get(), S.PDiag(diag::warn_remainder_division_by_zero) << IsDiv << RHS.get()->getSourceRange()); @@ -9043,9 +9031,8 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc, if (!IsStringPlusInt || IndexExpr->isValueDependent()) return; - Expr::EvalResult Result; - if (IndexExpr->EvaluateAsInt(Result, Self.getASTContext())) { - llvm::APSInt index = Result.Val.getInt(); + llvm::APSInt index; + if (IndexExpr->EvaluateAsInt(index, Self.getASTContext())) { unsigned StrLenWithNull = StrExpr->getLength() + 1; if (index.isNonNegative() && index <= llvm::APSInt(llvm::APInt(index.getBitWidth(), StrLenWithNull), @@ -9189,11 +9176,10 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS, if (PExp->IgnoreParenCasts()->isNullPointerConstant( Context, Expr::NPC_ValueDependentIsNotNull)) { // In C++ adding zero to a null pointer is defined. - Expr::EvalResult KnownVal; + llvm::APSInt KnownVal; if (!getLangOpts().CPlusPlus || (!IExp->isValueDependent() && - (!IExp->EvaluateAsInt(KnownVal, Context) || - KnownVal.Val.getInt() != 0))) { + (!IExp->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) { // Check the conditions to see if this is the 'p = nullptr + n' idiom. bool IsGNUIdiom = BinaryOperator::isNullPointerArithmeticExtension( Context, BO_Add, PExp, IExp); @@ -9268,11 +9254,10 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, if (LHS.get()->IgnoreParenCasts()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull)) { // In C++ adding zero to a null pointer is defined. - Expr::EvalResult KnownVal; + llvm::APSInt KnownVal; if (!getLangOpts().CPlusPlus || (!RHS.get()->isValueDependent() && - (!RHS.get()->EvaluateAsInt(KnownVal, Context) || - KnownVal.Val.getInt() != 0))) { + (!RHS.get()->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) { diagnoseArithmeticOnNullPointer(*this, Loc, LHS.get(), false); } } @@ -9348,12 +9333,11 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, if (S.getLangOpts().OpenCL) return; + llvm::APSInt Right; // Check right/shifter operand - Expr::EvalResult RHSResult; if (RHS.get()->isValueDependent() || - !RHS.get()->EvaluateAsInt(RHSResult, S.Context)) + !RHS.get()->EvaluateAsInt(Right, S.Context)) return; - llvm::APSInt Right = RHSResult.Val.getInt(); if (Right.isNegative()) { S.DiagRuntimeBehavior(Loc, RHS.get(), @@ -9376,12 +9360,11 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, // according to C++ has undefined behavior ([expr.shift] 5.8/2). Unsigned // integers have defined behavior modulo one more than the maximum value // representable in the result type, so never warn for those. - Expr::EvalResult LHSResult; + llvm::APSInt Left; if (LHS.get()->isValueDependent() || LHSType->hasUnsignedIntegerRepresentation() || - !LHS.get()->EvaluateAsInt(LHSResult, S.Context)) + !LHS.get()->EvaluateAsInt(Left, S.Context)) return; - llvm::APSInt Left = LHSResult.Val.getInt(); // If LHS does not have a signed type and non-negative value // then, the behavior is undefined. Warn about it. @@ -10751,9 +10734,8 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS, // that isn't 0 or 1 (which indicate a potential logical operation that // happened to fold to true/false) then warn. // Parens on the RHS are ignored. - Expr::EvalResult EVResult; - if (RHS.get()->EvaluateAsInt(EVResult, Context)) { - llvm::APSInt Result = EVResult.Val.getInt(); + llvm::APSInt Result; + if (RHS.get()->EvaluateAsInt(Result, Context)) if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() && !RHS.get()->getExprLoc().isMacroID()) || (Result != 0 && Result != 1)) { @@ -10773,7 +10755,6 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS, SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()), RHS.get()->getEndLoc())); } - } } if (!Context.getLangOpts().CPlusPlus) { @@ -14189,15 +14170,12 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, return ExprError(); } - if (!isa(E)) - E = ConstantExpr::Create(Context, E); - // Circumvent ICE checking in C++11 to avoid evaluating the expression twice // in the non-ICE case. if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) *Result = E->EvaluateKnownConstIntCheckOverflow(Context); - return E; + return new (Context) ConstantExpr(E); } Expr::EvalResult EvalResult; @@ -14215,7 +14193,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) { if (Result) *Result = EvalResult.Val.getInt(); - return E; + return new (Context) ConstantExpr(E); } // If our only note is the usual "invalid subexpression" note, just point @@ -14243,7 +14221,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, if (Result) *Result = EvalResult.Val.getInt(); - return E; + return new (Context) ConstantExpr(E); } namespace { diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 129460600843..3184be803860 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -8050,9 +8050,8 @@ ExprResult InitializationSequence::Perform(Sema &S, break; } - Expr::EvalResult EVResult; - Init->EvaluateAsInt(EVResult, S.Context); - llvm::APSInt Result = EVResult.Val.getInt(); + llvm::APSInt Result; + Init->EvaluateAsInt(Result, S.Context); const uint64_t SamplerValue = Result.getLimitedValue(); // 32-bit value of sampler's initializer is interpreted as // bit-field with the following structure: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 2daf45411ec6..84c3023081ae 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5048,16 +5048,15 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, unsigned NestedLoopCount = 1; if (CollapseLoopCountExpr) { // Found 'collapse' clause - calculate collapse number. - Expr::EvalResult Result; + llvm::APSInt Result; if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) - NestedLoopCount = Result.Val.getInt().getLimitedValue(); + NestedLoopCount = Result.getLimitedValue(); } unsigned OrderedLoopCount = 1; if (OrderedLoopCountExpr) { // Found 'ordered' clause - calculate collapse number. - Expr::EvalResult EVResult; - if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) { - llvm::APSInt Result = EVResult.Val.getInt(); + llvm::APSInt Result; + if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { if (Result.getLimitedValue() < NestedLoopCount) { SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), diag::err_omp_wrong_ordered_loop_count) @@ -5653,6 +5652,7 @@ static bool checkSimdlenSafelenSpecified(Sema &S, } if (Simdlen && Safelen) { + llvm::APSInt SimdlenRes, SafelenRes; const Expr *SimdlenLength = Simdlen->getSimdlen(); const Expr *SafelenLength = Safelen->getSafelen(); if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || @@ -5663,11 +5663,8 @@ static bool checkSimdlenSafelenSpecified(Sema &S, SafelenLength->isInstantiationDependent() || SafelenLength->containsUnexpandedParameterPack()) return false; - Expr::EvalResult SimdlenResult, SafelenResult; - SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); - SafelenLength->EvaluateAsInt(SafelenResult, S.Context); - llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); - llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); + SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); + SafelenLength->EvaluateAsInt(SafelenRes, S.Context); // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] // If both simdlen and safelen clauses are specified, the value of the // simdlen parameter must be less than or equal to the value of the safelen @@ -10672,11 +10669,10 @@ static bool checkOMPArraySectionConstantForReduction( SingleElement = true; ArraySizes.push_back(llvm::APSInt::get(1)); } else { - Expr::EvalResult Result; - if (!Length->EvaluateAsInt(Result, Context)) + llvm::APSInt ConstantLengthValue; + if (!Length->EvaluateAsInt(ConstantLengthValue, Context)) return false; - llvm::APSInt ConstantLengthValue = Result.Val.getInt(); SingleElement = (ConstantLengthValue.getSExtValue() == 1); ArraySizes.push_back(ConstantLengthValue); } @@ -10697,12 +10693,9 @@ static bool checkOMPArraySectionConstantForReduction( // This is an array subscript which has implicit length 1! ArraySizes.push_back(llvm::APSInt::get(1)); } else { - Expr::EvalResult Result; - if (!Length->EvaluateAsInt(Result, Context)) - return false; - - llvm::APSInt ConstantLengthValue = Result.Val.getInt(); - if (ConstantLengthValue.getSExtValue() != 1) + llvm::APSInt ConstantLengthValue; + if (!Length->EvaluateAsInt(ConstantLengthValue, Context) || + ConstantLengthValue.getSExtValue() != 1) return false; ArraySizes.push_back(ConstantLengthValue); @@ -12225,11 +12218,9 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, // If there is a lower bound that does not evaluates to zero, we are not // covering the whole dimension. if (LowerBound) { - Expr::EvalResult Result; - if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) + llvm::APSInt ConstLowerBound; + if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) return false; // Can't get the integer value as a constant. - - llvm::APSInt ConstLowerBound = Result.Val.getInt(); if (ConstLowerBound.getSExtValue()) return true; } @@ -12249,11 +12240,10 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, if (!CATy) return false; - Expr::EvalResult Result; - if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) + llvm::APSInt ConstLength; + if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) return false; // Can't get the integer value as a constant. - llvm::APSInt ConstLength = Result.Val.getInt(); return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); } @@ -12284,11 +12274,10 @@ static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, } // Check if the length evaluates to 1. - Expr::EvalResult Result; - if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) + llvm::APSInt ConstLength; + if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) return false; // Can't get the integer value as a constant. - llvm::APSInt ConstLength = Result.Val.getInt(); return ConstLength.getSExtValue() != 1; } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f36668f76140..ba4b67a23d46 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -5469,7 +5469,7 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, if (Notes.empty()) { // It's a constant expression. - return ConstantExpr::Create(S.Context, Result.get()); + return new (S.Context) ConstantExpr(Result.get()); } } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index cc3c25cfb5a8..91357de91baa 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -945,11 +945,8 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, llvm::APSInt ConstantCondValue; bool HasConstantCond = false; if (!HasDependentValue && !TheDefaultStmt) { - Expr::EvalResult Result; - HasConstantCond = CondExpr->EvaluateAsInt(Result, Context, + HasConstantCond = CondExpr->EvaluateAsInt(ConstantCondValue, Context, Expr::SE_AllowSideEffects); - if (Result.Val.isInt()) - ConstantCondValue = Result.Val.getInt(); assert(!HasConstantCond || (ConstantCondValue.getBitWidth() == CondWidth && ConstantCondValue.isSigned() == CondIsSigned)); diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index d209266049e6..e6d9b34dee91 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -378,12 +378,11 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, << InputExpr->getSourceRange()); } else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) { if (!InputExpr->isValueDependent()) { - Expr::EvalResult EVResult; - if (!InputExpr->EvaluateAsInt(EVResult, Context)) + llvm::APSInt Result; + if (!InputExpr->EvaluateAsInt(Result, Context)) return StmtError( Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected) << Info.getConstraintStr() << InputExpr->getSourceRange()); - llvm::APSInt Result = EVResult.Val.getInt(); if (!Info.isValidAsmImmediate(Result)) return StmtError(Diag(InputExpr->getBeginLoc(), diag::err_invalid_asm_value_for_constraint) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index c96bf10fb2c6..192ab8eb2423 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -178,8 +178,6 @@ getDeducedParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) { while (true) { if (ImplicitCastExpr *IC = dyn_cast(E)) E = IC->getSubExpr(); - else if (ConstantExpr *CE = dyn_cast(E)) - E = CE->getSubExpr(); else if (SubstNonTypeTemplateParmExpr *Subst = dyn_cast(E)) E = Subst->getReplacement(); @@ -5227,8 +5225,6 @@ MarkUsedTemplateParameters(ASTContext &Ctx, while (true) { if (const ImplicitCastExpr *ICE = dyn_cast(E)) E = ICE->getSubExpr(); - else if (const ConstantExpr *CE = dyn_cast(E)) - E = CE->getSubExpr(); else if (const SubstNonTypeTemplateParmExpr *Subst = dyn_cast(E)) E = Subst->getReplacement(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 011d0a585f09..b23f3634b1fa 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2234,6 +2234,10 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); } + if (ArraySize && !CurContext->isFunctionOrMethod()) + // A file-scoped array must have a constant array size. + ArraySize = new (Context) ConstantExpr(ArraySize); + // OpenCL v1.2 s6.9.d: variable length arrays are not supported. if (getLangOpts().OpenCL && T->isVariableArrayType()) { Diag(Loc, diag::err_opencl_vla); diff --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp index 3541b7f269b2..0e781d08e24c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -101,10 +101,9 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE, // This must be resolvable at compile time, so we defer to the constant // evaluator for a value. SVal V = UnknownVal(); - Expr::EvalResult EVResult; - if (CE->EvaluateAsInt(EVResult, C.getASTContext(), Expr::SE_NoSideEffects)) { + llvm::APSInt Result; + if (CE->EvaluateAsInt(Result, C.getASTContext(), Expr::SE_NoSideEffects)) { // Make sure the result has the correct type. - llvm::APSInt Result = EVResult.Val.getInt(); SValBuilder &SVB = C.getSValBuilder(); BasicValueFactory &BVF = SVB.getBasicValueFactory(); BVF.getAPSIntType(CE->getType()).apply(Result); diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp index 1d93ca6485de..202233acffab 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -597,10 +597,9 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) { unsigned suffix = 0; if (ArgSuffix.second >= 0) { const Expr *suffixEx = CE->getArg((unsigned)ArgSuffix.second); - Expr::EvalResult EVResult; - if (!suffixEx->EvaluateAsInt(EVResult, BR.getContext())) + llvm::APSInt Result; + if (!suffixEx->EvaluateAsInt(Result, BR.getContext())) return; - llvm::APSInt Result = EVResult.Val.getInt(); // FIXME: Issue a warning. if (Result.isNegative()) return; diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp index 4e45a37fd89e..fc2ab1d6e3f7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp @@ -135,9 +135,9 @@ private: bool isIntZeroExpr(const Expr *E) const { if (!E->getType()->isIntegralOrEnumerationType()) return false; - Expr::EvalResult Result; + llvm::APSInt Result; if (E->EvaluateAsInt(Result, Context)) - return Result.Val.getInt() == 0; + return Result == 0; return false; } @@ -191,11 +191,8 @@ private: if (const BinaryOperator *BOp = dyn_cast(rhse)) { if (BOp->getOpcode() == BO_Div) { const Expr *denom = BOp->getRHS()->IgnoreParenImpCasts(); - Expr::EvalResult Result; - if (denom->EvaluateAsInt(Result, Context)) { - denomVal = Result.Val.getInt(); + if (denom->EvaluateAsInt(denomVal, Context)) denomKnown = true; - } const Expr *numerator = BOp->getLHS()->IgnoreParenImpCasts(); if (numerator->isEvaluatable(Context)) numeratorKnown = true; diff --git a/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp index f80873934726..d342bd072a4e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp @@ -87,10 +87,9 @@ void Callback::run(const MatchFinder::MatchResult &Result) { MacroIndicatesWeShouldSkipTheCheck = true; } if (!MacroIndicatesWeShouldSkipTheCheck) { - Expr::EvalResult EVResult; + llvm::APSInt Result; if (CheckIfNull->IgnoreParenCasts()->EvaluateAsInt( - EVResult, ACtx, Expr::SE_AllowSideEffects)) { - llvm::APSInt Result = EVResult.Val.getInt(); + Result, ACtx, Expr::SE_AllowSideEffects)) { if (Result == 0) { if (!C->Pedantic) return; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index fa5a61971fcc..8a942054650e 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1274,6 +1274,9 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, break; case Expr::ConstantExprClass: + // Handled due to it being a wrapper class. + break; + case Stmt::ExprWithCleanupsClass: // Handled due to fully linearised CFG. break; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 7d47cf4f3379..fb13e89b5fa3 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -810,9 +810,8 @@ void ExprEngine:: VisitOffsetOfExpr(const OffsetOfExpr *OOE, ExplodedNode *Pred, ExplodedNodeSet &Dst) { StmtNodeBuilder B(Pred, Dst, *currBldrCtx); - Expr::EvalResult Result; - if (OOE->EvaluateAsInt(Result, getContext())) { - APSInt IV = Result.Val.getInt(); + APSInt IV; + if (OOE->EvaluateAsInt(IV, getContext())) { assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType())); assert(OOE->getType()->isBuiltinType()); assert(OOE->getType()->getAs()->isInteger()); diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp index 617c4ba27d46..129e81c94156 100644 --- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -362,9 +362,9 @@ Optional SValBuilder::getConstantVal(const Expr *E) { return None; ASTContext &Ctx = getContext(); - Expr::EvalResult Result; + llvm::APSInt Result; if (E->EvaluateAsInt(Result, Ctx)) - return makeIntVal(Result.Val.getInt()); + return makeIntVal(Result); if (Loc::isLocType(E->getType())) if (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull)) diff --git a/clang/test/Analysis/builtin-functions.cpp b/clang/test/Analysis/builtin-functions.cpp index da2fcf915d31..19984963b4fa 100644 --- a/clang/test/Analysis/builtin-functions.cpp +++ b/clang/test/Analysis/builtin-functions.cpp @@ -70,14 +70,14 @@ void test_constant_p() { const int j = 2; constexpr int k = 3; clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}} clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}} } diff --git a/clang/test/CodeGen/builtin-constant-p.c b/clang/test/CodeGen/builtin-constant-p.c deleted file mode 100644 index 5cdcc721235a..000000000000 --- a/clang/test/CodeGen/builtin-constant-p.c +++ /dev/null @@ -1,159 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O2 | FileCheck %s - -int a = 42; - -inline int bcp(int x) { - return __builtin_constant_p(x); -} - -/* --- Compound literals */ - -struct foo { int x, y; }; - -int y; -struct foo f = (struct foo){ __builtin_constant_p(y), 42 }; - -struct foo test0(int expr) { - // CHECK: define i64 @test0(i32 %expr) - // CHECK: call i1 @llvm.is.constant.i32(i32 %expr) - struct foo f = (struct foo){ __builtin_constant_p(expr), 42 }; - return f; -} - -/* --- Pointer types */ - -inline int test1_i(int *x) { - return *x; -} - -int test1() { - // CHECK: define i32 @test1 - // CHECK: add nsw i32 %0, -13 - // CHECK-NEXT: call i1 @llvm.is.constant.i32(i32 %sub) - return bcp(test1_i(&a) - 13); -} - -int test2() { - // CHECK: define i32 @test2 - // CHECK: ret i32 0 - return __builtin_constant_p(&a - 13); -} - -inline int test3_i(int *x) { - return 42; -} - -int test3() { - // CHECK: define i32 @test3 - // CHECK: ret i32 1 - return bcp(test3_i(&a) - 13); -} - -/* --- Aggregate types */ - -int b[] = {1, 2, 3}; - -int test4() { - // CHECK: define i32 @test4 - // CHECK: ret i32 0 - return __builtin_constant_p(b); -} - -const char test5_c[] = {1, 2, 3, 0}; - -int test5() { - // CHECK: define i32 @test5 - // CHECK: ret i32 0 - return __builtin_constant_p(test5_c); -} - -inline char test6_i(const char *x) { - return x[1]; -} - -int test6() { - // CHECK: define i32 @test6 - // CHECK: ret i32 0 - return __builtin_constant_p(test6_i(test5_c)); -} - -/* --- Non-constant global variables */ - -int test7() { - // CHECK: define i32 @test7 - // CHECK: call i1 @llvm.is.constant.i32(i32 %0) - return bcp(a); -} - -/* --- Constant global variables */ - -const int c = 42; - -int test8() { - // CHECK: define i32 @test8 - // CHECK: ret i32 1 - return bcp(c); -} - -/* --- Array types */ - -int arr[] = { 1, 2, 3 }; -const int c_arr[] = { 1, 2, 3 }; - -int test9() { - // CHECK: define i32 @test9 - // CHECK: call i1 @llvm.is.constant.i32(i32 %0) - return __builtin_constant_p(arr[2]); -} - -int test10() { - // CHECK: define i32 @test10 - // CHECK: ret i32 1 - return __builtin_constant_p(c_arr[2]); -} - -int test11() { - // CHECK: define i32 @test11 - // CHECK: ret i32 0 - return __builtin_constant_p(c_arr); -} - -/* --- Function pointers */ - -int test12() { - // CHECK: define i32 @test12 - // CHECK: ret i32 0 - return __builtin_constant_p(&test10); -} - -int test13() { - // CHECK: define i32 @test13 - // CHECK: ret i32 1 - return __builtin_constant_p(&test10 != 0); -} - -typedef unsigned long uintptr_t; -#define assign(p, v) ({ \ - uintptr_t _r_a_p__v = (uintptr_t)(v); \ - if (__builtin_constant_p(v) && _r_a_p__v == (uintptr_t)0) { \ - union { \ - uintptr_t __val; \ - char __c[1]; \ - } __u = { \ - .__val = (uintptr_t)_r_a_p__v \ - }; \ - *(volatile unsigned int*)&p = *(unsigned int*)(__u.__c); \ - __u.__val; \ - } \ - _r_a_p__v; \ -}) - -typedef void fn_p(void); -extern fn_p *dest_p; - -static void src_fn(void) { -} - -void test14() { - assign(dest_p, src_fn); -} diff --git a/clang/test/CodeGenCXX/builtin-constant-p.cpp b/clang/test/CodeGenCXX/builtin-constant-p.cpp deleted file mode 100644 index 6d853e8a6828..000000000000 --- a/clang/test/CodeGenCXX/builtin-constant-p.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s - -// Don't crash if the argument to __builtin_constant_p isn't scalar. -template -constexpr bool is_constant(const T v) { - return __builtin_constant_p(v); -} - -template -class numeric { - public: - using type = T; - - template - constexpr numeric(S value) - : value_(static_cast(value)) {} - - private: - const T value_; -}; - -bool bcp() { - return is_constant(numeric(1)); -} diff --git a/clang/test/Sema/builtins.c b/clang/test/Sema/builtins.c index 7d01e89756cd..e874f5988571 100644 --- a/clang/test/Sema/builtins.c +++ b/clang/test/Sema/builtins.c @@ -122,14 +122,6 @@ int test16() { __builtin_constant_p(1, 2); // expected-error {{too many arguments}} } -// __builtin_constant_p cannot resolve non-constants as a file scoped array. -int expr; -char y[__builtin_constant_p(expr) ? -1 : 1]; // no warning, the builtin is false. - -// no warning, the builtin is false. -struct foo { int a; }; -struct foo x = (struct foo) { __builtin_constant_p(42) ? 37 : 927 }; - const int test17_n = 0; const char test17_c[] = {1, 2, 3, 0}; const char test17_d[] = {1, 2, 3, 4}; @@ -169,7 +161,6 @@ void test17() { F(&test17_d); F((struct Aggregate){0, 1}); F((IntVector){0, 1, 2, 3}); - F(test17); // Ensure that a technique used in glibc is handled correctly. #define OPT(...) (__builtin_constant_p(__VA_ARGS__) && strlen(__VA_ARGS__) < 4) diff --git a/clang/test/SemaCXX/compound-literal.cpp b/clang/test/SemaCXX/compound-literal.cpp index 353be2cf48e4..8ef3f2c93051 100644 --- a/clang/test/SemaCXX/compound-literal.cpp +++ b/clang/test/SemaCXX/compound-literal.cpp @@ -36,11 +36,10 @@ namespace brace_initializers { POD p = (POD){1, 2}; // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD' - // CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' + // CHECK: ConstantExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD' - // CHECK-NEXT: ConstantExpr {{.*}} // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} - // CHECK-NEXT: ConstantExpr {{.*}} // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}} void test() {