summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2018-11-27 14:01:40 +0000
committerHans Wennborg <hans@hanshq.net>2018-11-27 14:01:40 +0000
commit8c79706e89dd2792bcc7b1e44d8f5db6abaf1617 (patch)
treeb1ebe35d9001f44880de2719abd98aeaa260270a
parent032f3e7fd8a12ceab800b0d9c3aca0f769f7b7cc (diff)
downloadbcm5719-llvm-8c79706e89dd2792bcc7b1e44d8f5db6abaf1617.tar.gz
bcm5719-llvm-8c79706e89dd2792bcc7b1e44d8f5db6abaf1617.zip
Revert r347417 "Re-Reinstate 347294 with a fix for the failures."
This caused a miscompile in Chrome (see crbug.com/908372) that's illustrated by this small reduction: static bool f(int *a, int *b) { return !__builtin_constant_p(b - a) || (!(b - a)); } int arr[] = {1,2,3}; bool g() { return f(arr, arr + 3); } $ clang -O2 -S -emit-llvm a.cc -o - g() should return true, but after r347417 it became false for some reason. This also reverts the follow-up commits. r347417: > Re-Reinstate 347294 with a fix for the failures. > > Don't try to emit a scalar expression for a non-scalar argument to > __builtin_constant_p(). > > Third time's a charm! r347446: > The result of is.constant() is unsigned. r347480: > A __builtin_constant_p() returns 0 with a function type. r347512: > isEvaluatable() implies a constant context. > > Assume that we're in a constant context if we're asking if the expression can > be compiled into a constant initializer. This fixes the issue where a > __builtin_constant_p() in a compound literal was diagnosed as not being > constant, even though it's always possible to convert the builtin into a > constant. r347531: > A "constexpr" is evaluated in a constant context. Make sure this is reflected > if a __builtin_constant_p() is a part of a constexpr. llvm-svn: 347656
-rw-r--r--clang/include/clang/AST/Expr.h16
-rw-r--r--clang/lib/AST/ASTImporter.cpp2
-rw-r--r--clang/lib/AST/Expr.cpp22
-rw-r--r--clang/lib/AST/ExprConstant.cpp148
-rw-r--r--clang/lib/Analysis/CFG.cpp19
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp54
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp6
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp11
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp11
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp4
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp6
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp5
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp7
-rw-r--r--clang/lib/Sema/SemaCast.cpp5
-rw-r--r--clang/lib/Sema/SemaChecking.cpp47
-rw-r--r--clang/lib/Sema/SemaDecl.cpp6
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--clang/lib/Sema/SemaExpr.cpp74
-rw-r--r--clang/lib/Sema/SemaInit.cpp5
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp47
-rw-r--r--clang/lib/Sema/SemaOverload.cpp2
-rw-r--r--clang/lib/Sema/SemaStmt.cpp5
-rw-r--r--clang/lib/Sema/SemaStmtAsm.cpp5
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp4
-rw-r--r--clang/lib/Sema/SemaType.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp9
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Core/SValBuilder.cpp4
-rw-r--r--clang/test/Analysis/builtin-functions.cpp6
-rw-r--r--clang/test/CodeGen/builtin-constant-p.c159
-rw-r--r--clang/test/CodeGenCXX/builtin-constant-p.cpp24
-rw-r--r--clang/test/Sema/builtins.c9
-rw-r--r--clang/test/SemaCXX/compound-literal.cpp5
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx1y.cpp8
38 files changed, 197 insertions, 567 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 7df7b56ca1f..6165ff4bb63 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<ConstantExpr>(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<ImplicitCastExpr>(e))
e = ice->getSubExpr();
- else if (FullExpr *fe = dyn_cast<FullExpr>(e))
- e = fe->getSubExpr();
+ else if (ConstantExpr *ce = dyn_cast<ConstantExpr>(e))
+ e = ce->getSubExpr();
else
break;
return e;
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 67feef16f26..6f8454c6795 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 e343949ac1f..ec6f084aedf 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<FullExpr>(E)) {
- E = FE->getSubExpr();
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
continue;
}
return E;
@@ -2619,8 +2619,8 @@ Expr *Expr::IgnoreCasts() {
E = NTTP->getReplacement();
continue;
}
- if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
- E = FE->getSubExpr();
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
continue;
}
return E;
@@ -2648,8 +2648,8 @@ Expr *Expr::IgnoreParenLValueCasts() {
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
- } else if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
- E = FE->getSubExpr();
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(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<ConstantExpr>(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 5eb2f2e7b84..b0dc7d4a4a9 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 <cstring>
#include <functional>
@@ -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<bool> InConstantContext(Info.InConstantContext, true);
- return ExprEvaluatorBaseTy::VisitConstantExpr(E);
-}
-
bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
if (unsigned BuiltinOp = E->getBuiltinCallee())
return VisitBuiltinCallExpr(E, BuiltinOp);
@@ -8189,20 +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 false;
- }
- 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:
@@ -10772,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,
@@ -10821,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,
@@ -10882,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);
@@ -10912,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<PartialDiagnosticAt> *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<PartialDiagnosticAt> *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);
}
}
@@ -11004,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());
@@ -11446,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;
}
@@ -11545,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<CXXMethodDecl>(FD);
const CXXRecordDecl *RD = MD ? MD->getParent()->getCanonicalDecl() : nullptr;
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 96130c25be8..cfda27dd37a 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 cb15f19224e..cf7c0b0c288 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 dbceaa7aa86..88f7dcebd24 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<VariableArrayType>(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 4980f53cc4d..e7c63ac11e9 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 cade093941a..e394a92a8e2 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<DeclRefExpr>((*SI)->IgnoreParenImpCasts())) {
if (const auto *StridePVD = cast<ParmVarDecl>(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 6e470ce1139..10700bcf79b 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1822,9 +1822,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 c92338a497d..9113b67684a 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 600640f78c1..7250bbc64d1 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 3b6cbe9469b..ab46554485f 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<DoStmt>(S)->getCond()->EvaluateAsInt(Result, Ctx))
+ const Expr *Cond = cast<DoStmt>(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 0b4645e11c3..3b49f9315f8 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 4b77ac61970..a45d4fdfd70 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;
@@ -6486,12 +6483,13 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,
return SLCT_NotALiteral;
}
case Stmt::BinaryOperatorClass: {
+ llvm::APSInt LResult;
+ llvm::APSInt RResult;
+
const BinaryOperator *BinOp = cast<BinaryOperator>(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);
@@ -6500,12 +6498,12 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> 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;
}
@@ -6518,10 +6516,9 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,
const UnaryOperator *UnaOp = cast<UnaryOperator>(E);
auto ASE = dyn_cast<ArraySubscriptExpr>(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;
}
@@ -10266,8 +10263,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
@@ -10323,8 +10320,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())
@@ -10937,11 +10932,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;
@@ -10985,10 +10977,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);
@@ -12275,11 +12266,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 5c31589e0b2..5c003ed6093 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 8a716ed4cca..61ef7cb9373 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 925988e4a7f..c9be58be9f1 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)
@@ -5797,13 +5795,6 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
? VK_RValue
: VK_LValue;
- if (isFileScope)
- if (auto ILE = dyn_cast<InitListExpr>(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) {
@@ -5812,6 +5803,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:
@@ -8407,8 +8399,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();
@@ -8416,7 +8408,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())
@@ -8444,9 +8435,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
@@ -8454,7 +8444,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);
@@ -8794,10 +8783,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());
@@ -9039,9 +9027,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),
@@ -9185,11 +9172,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);
@@ -9264,11 +9250,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);
}
}
@@ -9344,12 +9329,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(),
@@ -9372,12 +9356,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.
@@ -10747,9 +10730,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)) {
@@ -10769,7 +10751,6 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()),
RHS.get()->getEndLoc()));
}
- }
}
if (!Context.getLangOpts().CPlusPlus) {
@@ -14185,15 +14166,12 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
return ExprError();
}
- if (!isa<ConstantExpr>(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;
@@ -14211,7 +14189,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
@@ -14239,7 +14217,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 12946060084..3184be80386 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 2daf45411ec..84c3023081a 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 f36668f7614..ba4b67a23d4 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 cc3c25cfb5a..91357de91ba 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 d209266049e..e6d9b34dee9 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 c96bf10fb2c..192ab8eb242 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<ImplicitCastExpr>(E))
E = IC->getSubExpr();
- else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E))
- E = CE->getSubExpr();
else if (SubstNonTypeTemplateParmExpr *Subst =
dyn_cast<SubstNonTypeTemplateParmExpr>(E))
E = Subst->getReplacement();
@@ -5227,8 +5225,6 @@ MarkUsedTemplateParameters(ASTContext &Ctx,
while (true) {
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
E = ICE->getSubExpr();
- else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(E))
- E = CE->getSubExpr();
else if (const SubstNonTypeTemplateParmExpr *Subst =
dyn_cast<SubstNonTypeTemplateParmExpr>(E))
E = Subst->getReplacement();
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 99ea2d129ef..a407b6bc4ee 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 3541b7f269b..0e781d08e24 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 1d93ca6485d..202233acffa 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 4e45a37fd89..fc2ab1d6e3f 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<BinaryOperator>(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 f8087393472..d342bd072a4 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 d001f4de940..91f022d1e44 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1283,6 +1283,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 7d47cf4f337..fb13e89b5fa 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<BuiltinType>()->isInteger());
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 8c39b798946..ef3d5b76659 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -362,9 +362,9 @@ Optional<SVal> 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 da2fcf915d3..19984963b4f 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 5cdcc721235..00000000000
--- 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 6d853e8a682..00000000000
--- 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 <typename T>
-constexpr bool is_constant(const T v) {
- return __builtin_constant_p(v);
-}
-
-template <typename T>
-class numeric {
- public:
- using type = T;
-
- template <typename S>
- constexpr numeric(S value)
- : value_(static_cast<T>(value)) {}
-
- private:
- const T value_;
-};
-
-bool bcp() {
- return is_constant(numeric<int>(1));
-}
diff --git a/clang/test/Sema/builtins.c b/clang/test/Sema/builtins.c
index 7d01e89756c..e874f598857 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 353be2cf48e..8ef3f2c9305 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() {
diff --git a/clang/test/SemaCXX/constant-expression-cxx1y.cpp b/clang/test/SemaCXX/constant-expression-cxx1y.cpp
index 3214a2c0862..eb555737d12 100644
--- a/clang/test/SemaCXX/constant-expression-cxx1y.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -1122,11 +1122,3 @@ constexpr E e2 = E{0};
static_assert(e2.x != e2.y, "");
} // namespace IndirectFields
-
-constexpr bool __constant_string_p(const char *__s) {
- while (__builtin_constant_p(*__s) && *__s)
- __s++;
- return __builtin_constant_p(*__s);
-}
-
-constexpr bool n = __constant_string_p("a");
OpenPOWER on IntegriCloud