aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-08-06 07:30:58 +0000
committerJohn McCall <rjmccall@apple.com>2011-08-06 07:30:58 +0000
commita8e0cd8cdecc7e0ba1792e46773b884c6eed4829 (patch)
treedb7a19e171a67f6cc7a3912908fa84f449f2712d /lib/Sema/SemaStmt.cpp
parent993124ecdd44ec1430a3b7f01b22f65bbaadb586 (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.cpp35
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).