[cfe-commits] r40134 - in /cfe/trunk: Sema/SemaStmt.cpp include/clang/Basic/DiagnosticKinds.def test/Sema/default.c

Chris Lattner sabre at nondot.org
Fri Jul 20 20:00:27 PDT 2007


Author: lattner
Date: Fri Jul 20 22:00:26 2007
New Revision: 40134

URL: http://llvm.org/viewvc/llvm-project?rev=40134&view=rev
Log:
Two fixes: 
1) fix a crash on test/Sema/default.c by making
   sure that the switch scope is non-null.
2) if there is an error sema'ing a default or case stmt,
   make sure to return the substmt up, so that the error
   recovery code has more acurate info to continue with.



Added:
    cfe/trunk/test/Sema/default.c
Modified:
    cfe/trunk/Sema/SemaStmt.cpp
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaStmt.cpp?rev=40134&r1=40133&r2=40134&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/Sema/SemaStmt.cpp Fri Jul 20 22:00:26 2007
@@ -52,55 +52,63 @@
 Action::StmtResult
 Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval,
                     SourceLocation DotDotDotLoc, ExprTy *rhsval,
-                    SourceLocation ColonLoc, StmtTy *SubStmt) {
+                    SourceLocation ColonLoc, StmtTy *subStmt) {
+  Stmt *SubStmt = static_cast<Stmt*>(subStmt);
   Expr *LHSVal = ((Expr *)lhsval);
   assert((LHSVal != 0) && "missing expression in case statement");
     
   SourceLocation ExpLoc;
   // C99 6.8.4.2p3: The expression shall be an integer constant.
-  if (!LHSVal->isIntegerConstantExpr(Context, &ExpLoc))
-    return Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
-                LHSVal->getSourceRange());
+  if (!LHSVal->isIntegerConstantExpr(Context, &ExpLoc)) {
+    Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
+         LHSVal->getSourceRange());
+    return SubStmt;
+  }
 
   // GCC extension: The expression shall be an integer constant.
   Expr *RHSVal = ((Expr *)rhsval);
-  if (RHSVal) {
-    if (!RHSVal->isIntegerConstantExpr(Context, &ExpLoc))
-      return Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
-                  RHSVal->getSourceRange());
+  if (RHSVal && !RHSVal->isIntegerConstantExpr(Context, &ExpLoc)) {
+    Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
+         RHSVal->getSourceRange());
+    return SubStmt;
   }
 
-  return new CaseStmt(LHSVal, (Expr*)RHSVal, (Stmt*)SubStmt);
+  return new CaseStmt(LHSVal, (Expr*)RHSVal, SubStmt);
 }
 
 Action::StmtResult
 Sema::ParseDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, 
-                       StmtTy *SubStmt, Scope *CurScope) {
+                       StmtTy *subStmt, Scope *CurScope) {
+  Stmt *SubStmt = static_cast<Stmt*>(subStmt);
   Scope *S = CurScope->getBreakParent();
   
+  if (!S) {
+    Diag(DefaultLoc, diag::err_default_not_in_switch);
+    return SubStmt;
+  }
+  
   if (S->getDefaultStmt()) {
     Diag(DefaultLoc, diag::err_multiple_default_labels_defined);
     Diag(((DefaultStmt *)S->getDefaultStmt())->getDefaultLoc(), 
          diag::err_first_label);
-
-    return true;
+    return SubStmt;
   }
   
-  DefaultStmt *DS = new DefaultStmt(DefaultLoc, (Stmt*)SubStmt);
+  DefaultStmt *DS = new DefaultStmt(DefaultLoc, SubStmt);
   S->setDefaultStmt(DS);
-  
   return DS;
 }
 
 Action::StmtResult
 Sema::ParseLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
-                     SourceLocation ColonLoc, StmtTy *SubStmt) {
+                     SourceLocation ColonLoc, StmtTy *subStmt) {
+  Stmt *SubStmt = static_cast<Stmt*>(subStmt);
   // Look up the record for this label identifier.
   LabelStmt *&LabelDecl = LabelMap[II];
   
   // If not forward referenced or defined already, just create a new LabelStmt.
   if (LabelDecl == 0)
-    return LabelDecl = new LabelStmt(IdentLoc, II, (Stmt*)SubStmt);
+    return LabelDecl = new LabelStmt(IdentLoc, II, SubStmt);
   
   assert(LabelDecl->getID() == II && "Label mismatch!");
   
@@ -109,13 +117,13 @@
   if (LabelDecl->getSubStmt()) {
     Diag(IdentLoc, diag::err_redefinition_of_label, LabelDecl->getName());
     Diag(LabelDecl->getIdentLoc(), diag::err_previous_definition);
-    return (Stmt*)SubStmt;
+    return SubStmt;
   }
   
   // Otherwise, this label was forward declared, and we just found its real
   // definition.  Fill in the forward definition and return it.
   LabelDecl->setIdentLoc(IdentLoc);
-  LabelDecl->setSubStmt((Stmt*)SubStmt);
+  LabelDecl->setSubStmt(SubStmt);
   return LabelDecl;
 }
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=40134&r1=40133&r2=40134&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Jul 20 22:00:26 2007
@@ -653,6 +653,8 @@
      "'continue' statement not in loop statement")
 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_typecheck_return_incompatible, ERROR,
      "incompatible type returning '%1', expected '%0'")
 DIAG(ext_typecheck_return_pointer_int, EXTENSION,

Added: cfe/trunk/test/Sema/default.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/default.c?rev=40134&view=auto

==============================================================================
--- cfe/trunk/test/Sema/default.c (added)
+++ cfe/trunk/test/Sema/default.c Fri Jul 20 22:00:26 2007
@@ -0,0 +1,8 @@
+// RUN: clang -parse-ast-check %s
+
+void f5 (int z) { 
+  if (z) 
+    default:  // expected-error {{not in switch statement}}
+      ; 
+} 
+





More information about the cfe-commits mailing list