]> granicus.if.org Git - clang/commitdiff
correctly verify that default and case are in a switchstmt,
authorChris Lattner <sabre@nondot.org>
Mon, 23 Jul 2007 17:05:23 +0000 (17:05 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 23 Jul 2007 17:05:23 +0000 (17:05 +0000)
this fixes test/Sema/switch.c.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40438 91177308-0d34-0410-b5e6-96231b3b80d8

Sema/SemaStmt.cpp
include/clang/Basic/DiagnosticKinds.def
test/Sema/switch.c [new file with mode: 0644]

index 33a11344e7aa292c0e8e28b914d37256e32e4a64..f19737e30a967211c9bfd37e0fd23f6b49e5c115 100644 (file)
@@ -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;
 }
index 2224d7e057463c4d6dde4440255fe3378668ce41..4069bda64538c04eac855e15513c75e0af485883 100644 (file)
@@ -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 (file)
index 0000000..0c244cf
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: clang -parse-ast-check %s
+
+
+void f (int z) { 
+  while (z) { 
+    default: z--;   // expected-error {{statement not in switch}}
+  } 
+}
+