[cfe-commits] r69465 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaStmt.cpp test/Sema/block-misc.c

Chris Lattner sabre at nondot.org
Sat Apr 18 13:10:59 PDT 2009


Author: lattner
Date: Sat Apr 18 15:10:59 2009
New Revision: 69465

URL: http://llvm.org/viewvc/llvm-project?rev=69465&view=rev
Log:
abstract the SwitchStack for blocks just like we do the goto labels.
This fixes a crash on invalid (test10). rdar://6805469

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/test/Sema/block-misc.c

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=69465&r1=69464&r2=69465&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Apr 18 15:10:59 2009
@@ -103,6 +103,10 @@
   /// labels have a LabelStmt created for them with a null location & SubStmt.
   llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
   
+  /// SwitchStack - This is the current set of active switch statements in the
+  /// block.
+  llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
+  
   /// PrevBlockInfo - If this is nested inside another block, this points
   /// to the outer block.
   BlockSemaInfo *PrevBlockInfo;
@@ -144,7 +148,10 @@
   /// to handle blocks properly.
   llvm::DenseMap<IdentifierInfo*, LabelStmt*> FunctionLabelMap;
   
-  llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
+  /// FunctionSwitchStack - This is the current set of active switch statements
+  /// in the top level function.  Clients should always use getSwitchStack() to
+  /// handle the case when they are in a block.
+  llvm::SmallVector<SwitchStmt*, 8> FunctionSwitchStack;
   
   /// ExtVectorDecls - This is a list all the extended vector types. This allows
   /// us to associate a raw vector type with one of the ext_vector type names.
@@ -336,6 +343,12 @@
     return CurBlock ? CurBlock->LabelMap : FunctionLabelMap;
   }
   
+  /// getSwitchStack - This is returns the switch stack for the current block or
+  /// function.
+  llvm::SmallVector<SwitchStmt*,8> &getSwitchStack() {
+    return CurBlock ? CurBlock->SwitchStack : FunctionSwitchStack;
+  }
+  
   //===--------------------------------------------------------------------===//
   // Type Analysis / Processing: SemaType.cpp.
   //

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Sat Apr 18 15:10:59 2009
@@ -112,7 +112,7 @@
     rhsval = 0;
   }
 
-  if (SwitchStack.empty()) {
+  if (getSwitchStack().empty()) {
     Diag(CaseLoc, diag::err_case_not_in_switch);
     return StmtError();
   }
@@ -121,7 +121,7 @@
   lhsval.release();
   rhsval.release();
   CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc);
-  SwitchStack.back()->addSwitchCase(CS);
+  getSwitchStack().back()->addSwitchCase(CS);
   return Owned(CS);
 }
 
@@ -137,13 +137,13 @@
                        StmtArg subStmt, Scope *CurScope) {
   Stmt *SubStmt = static_cast<Stmt*>(subStmt.release());
 
-  if (SwitchStack.empty()) {
+  if (getSwitchStack().empty()) {
     Diag(DefaultLoc, diag::err_default_not_in_switch);
     return Owned(SubStmt);
   }
 
   DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, SubStmt);
-  SwitchStack.back()->addSwitchCase(DS);
+  getSwitchStack().back()->addSwitchCase(DS);
   return Owned(DS);
 }
 
@@ -241,7 +241,7 @@
   }
 
   SwitchStmt *SS = new (Context) SwitchStmt(Cond);
-  SwitchStack.push_back(SS);
+  getSwitchStack().push_back(SS);
   return Owned(SS);
 }
 
@@ -325,11 +325,11 @@
                             StmtArg Body) {
   Stmt *BodyStmt = (Stmt*)Body.release();
 
-  SwitchStmt *SS = SwitchStack.back();
+  SwitchStmt *SS = getSwitchStack().back();
   assert(SS == (SwitchStmt*)Switch.get() && "switch stack missing push/pop!");
 
   SS->setBody(BodyStmt, SwitchLoc);
-  SwitchStack.pop_back(); 
+  getSwitchStack().pop_back(); 
 
   Expr *CondExpr = SS->getCond();
   QualType CondType = CondExpr->getType();

Modified: cfe/trunk/test/Sema/block-misc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-misc.c?rev=69465&r1=69464&r2=69465&view=diff

==============================================================================
--- cfe/trunk/test/Sema/block-misc.c (original)
+++ cfe/trunk/test/Sema/block-misc.c Sat Apr 18 15:10:59 2009
@@ -95,4 +95,21 @@
   ^{ somelabel: ; }();
 }
 
+void test10(int i) {
+  switch (i) {
+  case 41: ;
+  ^{ case 42: ; }();     // expected-error {{'case' statement not in switch statement}}
+  }
+}
+
+void test11(int i) {
+  switch (i) {
+  case 41: ;
+    ^{ break; }();     // expected-error {{'break' statement not in loop or switch statement}}
+  }
+  
+  for (; i < 100; ++i)
+    ^{ break; }();     // expected-error {{'break' statement not in loop or switch statement}}
+}
+
 





More information about the cfe-commits mailing list