aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-07-23 17:05:23 +0000
committerChris Lattner <sabre@nondot.org>2007-07-23 17:05:23 +0000
commit8a87e57beb96212ee61dc08a5f691cd7f7710703 (patch)
treedc4378dda1d48bc0c172c050cb2148525caa07ad
parentf063721c4b1c5f2fd82bcbe2ef86fe4f61d21111 (diff)
correctly verify that default and case are in a switchstmt,
this fixes test/Sema/switch.c. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40438 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Sema/SemaStmt.cpp22
-rw-r--r--include/clang/Basic/DiagnosticKinds.def2
-rw-r--r--test/Sema/switch.c9
3 files changed, 20 insertions, 13 deletions
diff --git a/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp
index 33a11344e7..f19737e30a 100644
--- a/Sema/SemaStmt.cpp
+++ b/Sema/SemaStmt.cpp
@@ -55,7 +55,7 @@ Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval,
SourceLocation DotDotDotLoc, ExprTy *rhsval,
SourceLocation ColonLoc, StmtTy *subStmt) {
Stmt *SubStmt = static_cast<Stmt*>(subStmt);
- Expr *LHSVal = ((Expr *)lhsval);
+ Expr *LHSVal = ((Expr *)lhsval), *RHSVal = ((Expr *)rhsval);
assert((LHSVal != 0) && "missing expression in case statement");
SourceLocation ExpLoc;
@@ -67,19 +67,19 @@ Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval,
}
// GCC extension: The expression shall be an integer constant.
- Expr *RHSVal = ((Expr *)rhsval);
if (RHSVal && !RHSVal->isIntegerConstantExpr(Context, &ExpLoc)) {
Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
RHSVal->getSourceRange());
return SubStmt;
}
+
+ if (SwitchStack.empty()) {
+ Diag(CaseLoc, diag::err_case_not_in_switch);
+ return SubStmt;
+ }
CaseStmt *CS = new CaseStmt(LHSVal, RHSVal, SubStmt);
-
- assert(!SwitchStack.empty() && "missing push/pop in switch stack!");
- SwitchStmt *SS = SwitchStack.back();
- SS->addSwitchCase(CS);
-
+ SwitchStack.back()->addSwitchCase(CS);
return CS;
}
@@ -87,18 +87,14 @@ Action::StmtResult
Sema::ParseDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
StmtTy *subStmt, Scope *CurScope) {
Stmt *SubStmt = static_cast<Stmt*>(subStmt);
- Scope *S = CurScope->getBreakParent();
- if (!S) {
+ if (SwitchStack.empty()) {
Diag(DefaultLoc, diag::err_default_not_in_switch);
return SubStmt;
}
DefaultStmt *DS = new DefaultStmt(DefaultLoc, SubStmt);
-
- assert(!SwitchStack.empty() && "missing push/pop in switch stack!");
- SwitchStmt *SS = SwitchStack.back();
- SS->addSwitchCase(DS);
+ SwitchStack.back()->addSwitchCase(DS);
return DS;
}
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def
index 2224d7e057..4069bda645 100644
--- a/include/clang/Basic/DiagnosticKinds.def
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -655,6 +655,8 @@ DIAG(err_break_not_in_loop_or_switch, ERROR,
"'break' statement not in loop or switch statement")
DIAG(err_default_not_in_switch, ERROR,
"'default' statement not in switch statement")
+DIAG(err_case_not_in_switch, ERROR,
+ "'case' statement not in switch statement")
DIAG(err_typecheck_return_incompatible, ERROR,
"incompatible type returning '%1', expected '%0'")
DIAG(ext_typecheck_return_pointer_int, EXTENSION,
diff --git a/test/Sema/switch.c b/test/Sema/switch.c
new file mode 100644
index 0000000000..0c244cfcf5
--- /dev/null
+++ b/test/Sema/switch.c
@@ -0,0 +1,9 @@
+// RUN: clang -parse-ast-check %s
+
+
+void f (int z) {
+ while (z) {
+ default: z--; // expected-error {{statement not in switch}}
+ }
+}
+