diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 7 |
3 files changed, 21 insertions, 1 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 26a2a11444..2f30e6bd2b 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -258,7 +258,8 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) { Sema::ConstantEvaluated); ExprResult LHS(ParseCastExpression(false, false, isTypeCast)); - return ParseRHSOfBinaryExpression(LHS, prec::Conditional); + ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + return Actions.ActOnConstantExpression(Res); } /// ParseRHSOfBinaryExpression - Parse a binary expression that starts with diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 30a02b2953..5a2b2dc7e9 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -10023,6 +10023,18 @@ void Sema::UpdateMarkingForLValueToRValue(Expr *E) { MaybeODRUseExprs.erase(E->IgnoreParens()); } +ExprResult Sema::ActOnConstantExpression(ExprResult Res) { + if (!Res.isUsable()) + return Res; + + // If a constant-expression is a reference to a variable where we delay + // deciding whether it is an odr-use, just assume we will apply the + // lvalue-to-rvalue conversion. In the one case where this doesn't happen + // (a non-type template argument), we have special handling anyway. + UpdateMarkingForLValueToRValue(Res.get()); + return Res; +} + void Sema::CleanupVarDeclMarking() { for (llvm::SmallPtrSetIterator<Expr*> i = MaybeODRUseExprs.begin(), e = MaybeODRUseExprs.end(); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 11f03fc133..82bfe6fa70 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2950,6 +2950,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument( EnterExpressionEvaluationContext Unevaluated(getSema(), Sema::ConstantEvaluated); ExprResult E = getDerived().TransformExpr(SourceExpr); + E = SemaRef.ActOnConstantExpression(E); SourceExpr = (E.isInvalid() ? 0 : E.take()); } @@ -2990,6 +2991,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument( if (!InputExpr) InputExpr = Input.getArgument().getAsExpr(); ExprResult E = getDerived().TransformExpr(InputExpr); + E = SemaRef.ActOnConstantExpression(E); if (E.isInvalid()) return true; Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take()); return false; @@ -3654,6 +3656,7 @@ TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB, EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::ConstantEvaluated); Size = getDerived().TransformExpr(Size).template takeAs<Expr>(); + Size = SemaRef.ActOnConstantExpression(Size).take(); } NewTL.setSizeExpr(Size); @@ -3744,6 +3747,7 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB, ExprResult sizeResult = getDerived().TransformExpr(origSize); + sizeResult = SemaRef.ActOnConstantExpression(sizeResult); if (sizeResult.isInvalid()) return QualType(); @@ -3788,6 +3792,7 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType( Sema::ConstantEvaluated); ExprResult Size = getDerived().TransformExpr(T->getSizeExpr()); + Size = SemaRef.ActOnConstantExpression(Size); if (Size.isInvalid()) return QualType(); @@ -5061,11 +5066,13 @@ TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) { // Transform the left-hand case value. LHS = getDerived().TransformExpr(S->getLHS()); + LHS = SemaRef.ActOnConstantExpression(LHS); if (LHS.isInvalid()) return StmtError(); // Transform the right-hand case value (for the GNU case-range extension). RHS = getDerived().TransformExpr(S->getRHS()); + RHS = SemaRef.ActOnConstantExpression(RHS); if (RHS.isInvalid()) return StmtError(); } |