diff options
author | John McCall <rjmccall@apple.com> | 2011-08-06 07:30:58 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-08-06 07:30:58 +0000 |
commit | a8e0cd8cdecc7e0ba1792e46773b884c6eed4829 (patch) | |
tree | db7a19e171a67f6cc7a3912908fa84f449f2712d /lib/Sema/SemaStmt.cpp | |
parent | 993124ecdd44ec1430a3b7f01b22f65bbaadb586 (diff) |
Do l-value conversion, etc., on a switch condition expression in
ActOnStartOfSwitchStmt (i.e. before binding up a full-expression)
instead of ActOnFinishSwitchStmt.
Among other things, this means that property l-values are properly
converted inside the full-expression.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137014 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 6b2935fdf7..6e814e53bd 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -407,13 +407,12 @@ static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs, /// GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of /// potentially integral-promoted expression @p expr. -static QualType GetTypeBeforeIntegralPromotion(const Expr* expr) { - if (const CastExpr *ImplicitCast = dyn_cast<ImplicitCastExpr>(expr)) { - const Expr *ExprBeforePromotion = ImplicitCast->getSubExpr(); - QualType TypeBeforePromotion = ExprBeforePromotion->getType(); - if (TypeBeforePromotion->isIntegralOrEnumerationType()) { - return TypeBeforePromotion; - } +static QualType GetTypeBeforeIntegralPromotion(Expr *&expr) { + if (ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(expr)) + expr = cleanups->getSubExpr(); + while (ImplicitCastExpr *impcast = dyn_cast<ImplicitCastExpr>(expr)) { + if (impcast->getCastKind() != CK_IntegralCast) break; + expr = impcast->getSubExpr(); } return expr->getType(); } @@ -449,6 +448,11 @@ Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond, if (CondResult.isInvalid()) return StmtError(); Cond = CondResult.take(); + // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr. + CondResult = UsualUnaryConversions(Cond); + if (CondResult.isInvalid()) return StmtError(); + Cond = CondResult.take(); + if (!CondVar) { CheckImplicitConversions(Cond, SwitchLoc); CondResult = MaybeCreateExprWithCleanups(Cond); @@ -482,21 +486,14 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, SS->setBody(BodyStmt, SwitchLoc); getCurFunction()->SwitchStack.pop_back(); - if (SS->getCond() == 0) - return StmtError(); - Expr *CondExpr = SS->getCond(); - Expr *CondExprBeforePromotion = CondExpr; - QualType CondTypeBeforePromotion = - GetTypeBeforeIntegralPromotion(CondExpr); + if (!CondExpr) return StmtError(); - // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr. - ExprResult CondResult = UsualUnaryConversions(CondExpr); - if (CondResult.isInvalid()) - return StmtError(); - CondExpr = CondResult.take(); QualType CondType = CondExpr->getType(); - SS->setCond(CondExpr); + + Expr *CondExprBeforePromotion = CondExpr; + QualType CondTypeBeforePromotion = + GetTypeBeforeIntegralPromotion(CondExprBeforePromotion); // C++ 6.4.2.p2: // Integral promotions are performed (on the switch condition). |