summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTImporter.cpp12
-rw-r--r--clang/lib/AST/Expr.cpp15
-rw-r--r--clang/lib/AST/ExprConstant.cpp2
-rw-r--r--clang/lib/ASTMatchers/ASTMatchersInternal.cpp1
-rw-r--r--clang/lib/ASTMatchers/Dynamic/Registry.cpp1
-rw-r--r--clang/lib/Analysis/CFG.cpp12
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp2
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp4
-rw-r--r--clang/lib/CodeGen/CGExprComplex.cpp3
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp10
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp46
-rw-r--r--clang/lib/Sema/SemaInit.cpp3
-rw-r--r--clang/lib/Sema/SemaOverload.cpp2
-rw-r--r--clang/lib/Sema/SemaType.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Core/Environment.cpp1
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp7
17 files changed, 101 insertions, 27 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 53568f1169a..486fd4d43ae 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -579,6 +579,7 @@ namespace clang {
ExpectedStmt VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
ExpectedStmt VisitAtomicExpr(AtomicExpr *E);
ExpectedStmt VisitAddrLabelExpr(AddrLabelExpr *E);
+ ExpectedStmt VisitConstantExpr(ConstantExpr *E);
ExpectedStmt VisitParenExpr(ParenExpr *E);
ExpectedStmt VisitParenListExpr(ParenListExpr *E);
ExpectedStmt VisitStmtExpr(StmtExpr *E);
@@ -6366,6 +6367,17 @@ ExpectedStmt ASTNodeImporter::VisitAddrLabelExpr(AddrLabelExpr *E) {
ToAmpAmpLoc, ToLabelLoc, ToLabel, ToType);
}
+ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) {
+ auto Imp = importSeq(E->getSubExpr());
+ if (!Imp)
+ return Imp.takeError();
+
+ Expr *ToSubExpr;
+ std::tie(ToSubExpr) = *Imp;
+
+ return new (Importer.getToContext()) ConstantExpr(ToSubExpr);
+}
+
ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
auto Imp = importSeq(E->getLParen(), E->getRParen(), E->getSubExpr());
if (!Imp)
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 8b512815e81..c2351955ee1 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2585,6 +2585,10 @@ Expr *Expr::IgnoreParenCasts() {
E = NTTP->getReplacement();
continue;
}
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
+ continue;
+ }
return E;
}
}
@@ -2606,6 +2610,10 @@ Expr *Expr::IgnoreCasts() {
E = NTTP->getReplacement();
continue;
}
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
+ continue;
+ }
return E;
}
}
@@ -2631,6 +2639,9 @@ Expr *Expr::IgnoreParenLValueCasts() {
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
+ continue;
}
break;
}
@@ -2672,6 +2683,10 @@ Expr *Expr::IgnoreParenImpCasts() {
E = NTTP->getReplacement();
continue;
}
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
+ continue;
+ }
return E;
}
}
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 78c747196c0..30800568a22 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4719,6 +4719,8 @@ public:
return Error(E);
}
+ bool VisitConstantExpr(const ConstantExpr *E)
+ { return StmtVisitorTy::Visit(E->getSubExpr()); }
bool VisitParenExpr(const ParenExpr *E)
{ return StmtVisitorTy::Visit(E->getSubExpr()); }
bool VisitUnaryExtension(const UnaryOperator *E)
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index 38825257105..08fca5b46bd 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -666,6 +666,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingValueDecl>
unresolvedUsingValueDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl>
unresolvedUsingTypenameDecl;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr> constantExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
cxxConstructExpr;
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index 318f39dee94..7493389fbda 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -153,6 +153,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(compoundStmt);
REGISTER_MATCHER(conditionalOperator);
REGISTER_MATCHER(constantArrayType);
+ REGISTER_MATCHER(constantExpr);
REGISTER_MATCHER(containsDeclaration);
REGISTER_MATCHER(continueStmt);
REGISTER_MATCHER(cStyleCastExpr);
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index c7724e200b7..cfda27dd37a 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -551,6 +551,7 @@ private:
CFGBlock *VisitGotoStmt(GotoStmt *G);
CFGBlock *VisitIfStmt(IfStmt *I);
CFGBlock *VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc);
+ CFGBlock *VisitConstantExpr(ConstantExpr *E, AddStmtChoice asc);
CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I);
CFGBlock *VisitLabelStmt(LabelStmt *L);
CFGBlock *VisitBlockExpr(BlockExpr *E, AddStmtChoice asc);
@@ -2100,6 +2101,9 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) {
case Stmt::ImplicitCastExprClass:
return VisitImplicitCastExpr(cast<ImplicitCastExpr>(S), asc);
+ case Stmt::ConstantExprClass:
+ return VisitConstantExpr(cast<ConstantExpr>(S), asc);
+
case Stmt::IndirectGotoStmtClass:
return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S));
@@ -4380,6 +4384,10 @@ CFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E,
return Visit(E->getSubExpr(), AddStmtChoice());
}
+CFGBlock *CFGBuilder::VisitConstantExpr(ConstantExpr *E, AddStmtChoice asc) {
+ return Visit(E->getSubExpr(), AddStmtChoice());
+}
+
CFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) {
// Lazily create the indirect-goto dispatch block if there isn't one already.
CFGBlock *IBlock = cfg->getIndirectGotoBlock();
@@ -4436,6 +4444,10 @@ tryAgain:
E = cast<CXXFunctionalCastExpr>(E)->getSubExpr();
goto tryAgain;
+ case Stmt::ConstantExprClass:
+ E = cast<ConstantExpr>(E)->getSubExpr();
+ goto tryAgain;
+
case Stmt::ParenExprClass:
E = cast<ParenExpr>(E)->getSubExpr();
goto tryAgain;
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 0fd19c9578e..dafca7cf7cc 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1260,6 +1260,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
return EmitVAArgExprLValue(cast<VAArgExpr>(E));
case Expr::DeclRefExprClass:
return EmitDeclRefLValue(cast<DeclRefExpr>(E));
+ case Expr::ConstantExprClass:
+ return EmitLValue(cast<ConstantExpr>(E)->getSubExpr());
case Expr::ParenExprClass:
return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
case Expr::GenericSelectionExprClass:
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 42481939fa1..db49b3f28a5 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -125,6 +125,10 @@ public:
return Visit(E->getReplacement());
}
+ void VisitConstantExpr(ConstantExpr *E) {
+ return Visit(E->getSubExpr());
+ }
+
// l-values.
void VisitDeclRefExpr(DeclRefExpr *E) { EmitAggLoadOfLValue(E); }
void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index c0b87c850e9..2db693b44c9 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -101,6 +101,9 @@ public:
llvm_unreachable("Stmt can't have complex result type!");
}
ComplexPairTy VisitExpr(Expr *S);
+ ComplexPairTy VisitConstantExpr(ConstantExpr *E) {
+ return Visit(E->getSubExpr());
+ }
ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
return Visit(GE->getResultExpr());
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 1339c06646c..eb5e0109684 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -723,6 +723,10 @@ public:
return nullptr;
}
+ llvm::Constant *VisitConstantExpr(ConstantExpr *CE, QualType T) {
+ return Visit(CE->getSubExpr(), T);
+ }
+
llvm::Constant *VisitParenExpr(ParenExpr *PE, QualType T) {
return Visit(PE->getSubExpr(), T);
}
@@ -1601,6 +1605,7 @@ private:
ConstantLValue tryEmitBase(const APValue::LValueBase &base);
ConstantLValue VisitStmt(const Stmt *S) { return nullptr; }
+ ConstantLValue VisitConstantExpr(const ConstantExpr *E);
ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
ConstantLValue VisitStringLiteral(const StringLiteral *E);
ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
@@ -1756,6 +1761,11 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
}
ConstantLValue
+ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *E) {
+ return Visit(E->getSubExpr());
+}
+
+ConstantLValue
ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E);
}
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 0611b9186af..801f4a9fc1a 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -398,6 +398,9 @@ public:
}
Value *VisitExpr(Expr *S);
+ Value *VisitConstantExpr(ConstantExpr *E) {
+ return Visit(E->getSubExpr());
+ }
Value *VisitParenExpr(ParenExpr *PE) {
return Visit(PE->getSubExpr());
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 428bd7a5922..c549514da83 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5745,21 +5745,6 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
LiteralExpr = Result.get();
bool isFileScope = !CurContext->isFunctionOrMethod();
- if (isFileScope) {
- if (!LiteralExpr->isTypeDependent() &&
- !LiteralExpr->isValueDependent() &&
- !literalType->isDependentType()) // C99 6.5.2.5p3
- if (CheckForConstantInitializer(LiteralExpr, literalType))
- return ExprError();
- } else if (literalType.getAddressSpace() != LangAS::opencl_private &&
- literalType.getAddressSpace() != LangAS::Default) {
- // Embedded-C extensions to C99 6.5.2.5:
- // "If the compound literal occurs inside the body of a function, the
- // type name shall not be qualified by an address-space qualifier."
- Diag(LParenLoc, diag::err_compound_literal_with_address_space)
- << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd());
- return ExprError();
- }
// In C, compound literals are l-values for some reason.
// For GCC compatibility, in C++, file-scope array compound literals with
@@ -5784,9 +5769,26 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
? VK_RValue
: VK_LValue;
- return MaybeBindToTemporary(
- new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
- VK, LiteralExpr, isFileScope));
+ Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
+ VK, LiteralExpr, isFileScope);
+ if (isFileScope) {
+ if (!LiteralExpr->isTypeDependent() &&
+ !LiteralExpr->isValueDependent() &&
+ !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:
+ // "If the compound literal occurs inside the body of a function, the
+ // type name shall not be qualified by an address-space qualifier."
+ Diag(LParenLoc, diag::err_compound_literal_with_address_space)
+ << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd());
+ return ExprError();
+ }
+
+ return MaybeBindToTemporary(E);
}
ExprResult
@@ -14144,7 +14146,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
if (Result)
*Result = E->EvaluateKnownConstIntCheckOverflow(Context);
- return E;
+ return new (Context) ConstantExpr(E);
}
Expr::EvalResult EvalResult;
@@ -14162,7 +14164,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
@@ -14190,7 +14192,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
if (Result)
*Result = EvalResult.Val.getInt();
- return E;
+ return new (Context) ConstantExpr(E);
}
namespace {
@@ -16634,4 +16636,4 @@ ExprResult Sema::ActOnObjCAvailabilityCheckExpr(
return new (Context)
ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);
-} \ No newline at end of file
+}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 11a1f8509a1..438e90414d6 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -5527,7 +5527,8 @@ void InitializationSequence::InitializeFrom(Sema &S,
// array from a compound literal that creates an array of the same
// type, so long as the initializer has no side effects.
if (!S.getLangOpts().CPlusPlus && Initializer &&
- isa<CompoundLiteralExpr>(Initializer->IgnoreParens()) &&
+ (isa<ConstantExpr>(Initializer->IgnoreParens()) ||
+ isa<CompoundLiteralExpr>(Initializer->IgnoreParens())) &&
Initializer->getType()->isArrayType()) {
const ArrayType *SourceAT
= Context.getAsArrayType(Initializer->getType());
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index edb2ec21f04..3466da6e5a7 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -5444,7 +5444,7 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
if (Notes.empty()) {
// It's a constant expression.
- return Result;
+ return new (S.Context) ConstantExpr(Result.get());
}
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 200bab6c84b..957090c1be3 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2233,6 +2233,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/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp
index da99dbc7acb..43bbcd7c6af 100644
--- a/clang/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp
@@ -92,6 +92,7 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry,
case Stmt::ExprWithCleanupsClass:
case Stmt::GenericSelectionExprClass:
case Stmt::OpaqueValueExprClass:
+ case Stmt::ConstantExprClass:
case Stmt::ParenExprClass:
case Stmt::SubstNonTypeTemplateParmExprClass:
llvm_unreachable("Should have been handled by ignoreTransparentExprs");
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 2b48cd0f72d..91f022d1e44 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1267,9 +1267,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::ObjCPropertyRefExprClass:
llvm_unreachable("These are handled by PseudoObjectExpr");
- case Expr::ConstantExprClass:
- return Visit(cast<ConstantExpr>(S)->getSubExpr(), Pred, DstTop);
-
case Stmt::GNUNullExprClass: {
// GNU __null is a pointer-width integer, not an actual pointer.
ProgramStateRef state = Pred->getState();
@@ -1285,6 +1282,10 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
Bldr.addNodes(Dst);
break;
+ case Expr::ConstantExprClass:
+ // Handled due to it being a wrapper class.
+ break;
+
case Stmt::ExprWithCleanupsClass:
// Handled due to fully linearised CFG.
break;
OpenPOWER on IntegriCloud