summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-10-16 16:45:22 +0000
committerChris Lattner <sabre@nondot.org>2009-10-16 16:45:22 +0000
commita96d4279660b5fa49ce44b5cec1f25f895158881 (patch)
tree184b69c3aafaf955fd099f7c50f2cfe4df7ccc8b
parent519486256cfb15ab61527c90fb45cc44e4389199 (diff)
downloadbcm5719-llvm-a96d4279660b5fa49ce44b5cec1f25f895158881.tar.gz
bcm5719-llvm-a96d4279660b5fa49ce44b5cec1f25f895158881.zip
Implement PR4407 - missing warnings on case value overflow,
patch by Zhanyong Wan! llvm-svn: 84259
-rw-r--r--clang/lib/Sema/SemaStmt.cpp29
-rw-r--r--clang/test/Sema/switch.c7
2 files changed, 34 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index e8cd6b081de..efa7e22b2ef 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -368,6 +368,21 @@ static bool CmpCaseVals(const std::pair<llvm::APSInt, CaseStmt*>& lhs,
return false;
}
+/// GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of
+/// potentially integral-promoted expression @p expr.
+static QualType GetTypeBeforeIntegralPromotion(const Expr* expr) {
+ const ImplicitCastExpr *ImplicitCast =
+ dyn_cast_or_null<ImplicitCastExpr>(expr);
+ if (ImplicitCast != NULL) {
+ const Expr *ExprBeforePromotion = ImplicitCast->getSubExpr();
+ QualType TypeBeforePromotion = ExprBeforePromotion->getType();
+ if (TypeBeforePromotion->isIntegralType()) {
+ return TypeBeforePromotion;
+ }
+ }
+ return expr->getType();
+}
+
Action::OwningStmtResult
Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
StmtArg Body) {
@@ -382,6 +397,16 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
Expr *CondExpr = SS->getCond();
QualType CondType = CondExpr->getType();
+ // C++ 6.4.2.p2:
+ // Integral promotions are performed (on the switch condition).
+ //
+ // A case value unrepresentable by the original switch condition
+ // type (before the promotion) doesn't make sense, even when it can
+ // be represented by the promoted type. Therefore we need to find
+ // the pre-promotion type of the switch condition.
+ QualType CondTypeBeforePromotion =
+ GetTypeBeforeIntegralPromotion(CondExpr);
+
if (!CondExpr->isTypeDependent() &&
!CondType->isIntegerType()) { // C99 6.8.4.2p1
Diag(SwitchLoc, diag::err_typecheck_statement_requires_integer)
@@ -395,8 +420,8 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
= CondExpr->isTypeDependent() || CondExpr->isValueDependent();
unsigned CondWidth
= HasDependentValue? 0
- : static_cast<unsigned>(Context.getTypeSize(CondType));
- bool CondIsSigned = CondType->isSignedIntegerType();
+ : static_cast<unsigned>(Context.getTypeSize(CondTypeBeforePromotion));
+ bool CondIsSigned = CondTypeBeforePromotion->isSignedIntegerType();
// Accumulate all of the case values in a vector so that we can sort them
// and detect duplicates. This vector contains the APInt for the case after
diff --git a/clang/test/Sema/switch.c b/clang/test/Sema/switch.c
index 5999f342aef..122947e7ce5 100644
--- a/clang/test/Sema/switch.c
+++ b/clang/test/Sema/switch.c
@@ -68,3 +68,10 @@ void test5(int z) {
}
}
+void test6() {
+ const char ch = 'a';
+ switch(ch) {
+ case 1234: // expected-warning {{overflow converting case value}}
+ break;
+ }
+}
OpenPOWER on IntegriCloud