summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp2
-rw-r--r--clang/lib/AST/Expr.cpp37
-rw-r--r--clang/lib/AST/ExprConstant.cpp2
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--clang/lib/Sema/SemaExpr.cpp13
5 files changed, 41 insertions, 15 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 7f73531a83b..d7778a71964 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -908,7 +908,7 @@ void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) {
Parents.reset();
}
-void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
+void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const {
Deallocations.push_back({Callback, Data});
}
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index cc92689cb92..d342bda962d 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -239,6 +239,7 @@ ConstantExpr::ResultStorageKind
ConstantExpr::getStorageKind(const APValue &Value) {
switch (Value.getKind()) {
case APValue::None:
+ case APValue::Indeterminate:
return ConstantExpr::RSK_None;
case APValue::Int:
if (!Value.getInt().needsCleanup())
@@ -249,9 +250,18 @@ ConstantExpr::getStorageKind(const APValue &Value) {
}
}
+ConstantExpr::ResultStorageKind
+ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) {
+ if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64)
+ return ConstantExpr::RSK_Int64;
+ return ConstantExpr::RSK_APValue;
+}
+
void ConstantExpr::DefaultInit(ResultStorageKind StorageKind) {
ConstantExprBits.ResultKind = StorageKind;
- if (StorageKind == RSK_APValue)
+ ConstantExprBits.APValueKind = APValue::None;
+ ConstantExprBits.HasCleanup = false;
+ if (StorageKind == ConstantExpr::RSK_APValue)
::new (getTrailingObjects<APValue>()) APValue();
}
@@ -269,8 +279,6 @@ ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
StorageKind == ConstantExpr::RSK_Int64);
void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
ConstantExpr *Self = new (Mem) ConstantExpr(E, StorageKind);
- if (StorageKind == ConstantExpr::RSK_APValue)
- Context.AddAPValueCleanup(&Self->APValueResult());
return Self;
}
@@ -278,7 +286,7 @@ ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
const APValue &Result) {
ResultStorageKind StorageKind = getStorageKind(Result);
ConstantExpr *Self = Create(Context, E, StorageKind);
- Self->SetResult(Result);
+ Self->SetResult(Result, Context);
return Self;
}
@@ -296,14 +304,13 @@ ConstantExpr *ConstantExpr::CreateEmpty(const ASTContext &Context,
StorageKind == ConstantExpr::RSK_Int64);
void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
ConstantExpr *Self = new (Mem) ConstantExpr(StorageKind, Empty);
- if (StorageKind == ConstantExpr::RSK_APValue)
- Context.AddAPValueCleanup(&Self->APValueResult());
return Self;
}
-void ConstantExpr::MoveIntoResult(APValue &Value) {
+void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) {
assert(getStorageKind(Value) == ConstantExprBits.ResultKind &&
"Invalid storage for this value kind");
+ ConstantExprBits.APValueKind = Value.getKind();
switch (ConstantExprBits.ResultKind) {
case RSK_None:
return;
@@ -313,12 +320,28 @@ void ConstantExpr::MoveIntoResult(APValue &Value) {
ConstantExprBits.IsUnsigned = Value.getInt().isUnsigned();
return;
case RSK_APValue:
+ if (!ConstantExprBits.HasCleanup && Value.needsCleanup()) {
+ ConstantExprBits.HasCleanup = true;
+ Context.addDestruction(&APValueResult());
+ }
APValueResult() = std::move(Value);
return;
}
llvm_unreachable("Invalid ResultKind Bits");
}
+llvm::APSInt ConstantExpr::getResultAsAPSInt() const {
+ switch (ConstantExprBits.ResultKind) {
+ case ConstantExpr::RSK_APValue:
+ return APValueResult().getInt();
+ case ConstantExpr::RSK_Int64:
+ return llvm::APSInt(llvm::APInt(ConstantExprBits.BitWidth, Int64Result()),
+ ConstantExprBits.IsUnsigned);
+ default:
+ llvm_unreachable("invalid Accessor");
+ }
+}
+
APValue ConstantExpr::getAPValueResult() const {
switch (ConstantExprBits.ResultKind) {
case ConstantExpr::RSK_APValue:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index c0c807b11c9..3282bc0a0af 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8963,6 +8963,8 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) {
llvm::SaveAndRestore<bool> InConstantContext(Info.InConstantContext, true);
+ if (E->getResultAPValueKind() != APValue::None)
+ return Success(E->getAPValueResult(), E);
return ExprEvaluatorBaseTy::VisitConstantExpr(E);
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 6dda693c6ad..0fda8ea515b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -14013,8 +14013,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 9b1e362c262..9b09059c153 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14538,14 +14538,13 @@ 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);
+ if (!isa<ConstantExpr>(E))
+ E = ConstantExpr::Create(Context, E);
return E;
}
@@ -14555,8 +14554,12 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
// Try to evaluate the expression, and produce diagnostics explaining why it's
// not a constant expression as a side-effect.
- bool Folded = E->EvaluateAsRValue(EvalResult, Context) &&
- EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+ bool Folded =
+ E->EvaluateAsRValue(EvalResult, Context, /*isConstantContext*/ true) &&
+ EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+
+ if (!isa<ConstantExpr>(E))
+ E = ConstantExpr::Create(Context, E, EvalResult.Val);
// In C++11, we can rely on diagnostics being produced for any expression
// which is not a constant expression. If no diagnostics were produced, then
OpenPOWER on IntegriCloud