]> granicus.if.org Git - clang/commitdiff
add a new Sema::CurFunctionNeedsScopeChecking bool that is used to avoid
authorChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 05:21:20 +0000 (05:21 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 05:21:20 +0000 (05:21 +0000)
calling into the jump checker when a function or method is known to contain
no VLAs or @try blocks.

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

lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaStmt.cpp
test/Sema/scope-check.c

index b08a120e58aa7c0b4fe1b5faa6feaea02c07dcd0..e8742e8e513e6616d9ad27b9de412ea100b992ca 100644 (file)
@@ -153,6 +153,12 @@ public:
   /// handle the case when they are in a block.
   llvm::SmallVector<SwitchStmt*, 8> FunctionSwitchStack;
   
+  /// CurFunctionNeedsScopeChecking - This is set to true when a function or
+  /// ObjC method body contains a VLA or an ObjC try block, which introduce
+  /// scopes that need to be checked for goto conditions.  If a function does
+  /// not contain this, then it need not have the jump checker run on it.
+  bool CurFunctionNeedsScopeChecking;
+  
   /// 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.
   /// This is only necessary for issuing pretty diagnostics.
index 887c86cef59e0ea927c59135329bf8e28d4ecd5f..7ed0e2dd31625ed39d77ddfd2495826f05ccf036 100644 (file)
@@ -1564,11 +1564,13 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
       InvalidDecl = true;
   }
 
-  if (S->getFnParent() == 0) {
-    QualType T = NewTD->getUnderlyingType();
-    // C99 6.7.7p2: If a typedef name specifies a variably modified type
-    // then it shall have block scope.
-    if (T->isVariablyModifiedType()) {
+  // C99 6.7.7p2: If a typedef name specifies a variably modified type
+  // then it shall have block scope.
+  QualType T = NewTD->getUnderlyingType();
+  if (T->isVariablyModifiedType()) {
+    CurFunctionNeedsScopeChecking = true;
+  
+    if (S->getFnParent() == 0) {
       bool SizeIsNegative;
       QualType FixedTy =
           TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
@@ -1810,9 +1812,12 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
       && !NewVD->hasAttr<BlocksAttr>())
     Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
 
-  bool isIllegalVLA = T->isVariableArrayType() && NewVD->hasGlobalStorage();
-  bool isIllegalVM = T->isVariablyModifiedType() && NewVD->hasLinkage();
-  if (isIllegalVLA || isIllegalVM) {
+  bool isVM = T->isVariablyModifiedType();
+  if (isVM || NewVD->hasAttr<CleanupAttr>())
+    CurFunctionNeedsScopeChecking = true;
+  
+  if ((isVM && NewVD->hasLinkage()) ||
+      (T->isVariableArrayType() && NewVD->hasGlobalStorage())) {
     bool SizeIsNegative;
     QualType FixedTy =
         TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
@@ -2822,6 +2827,8 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
 Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
   FunctionDecl *FD = cast<FunctionDecl>(D.getAs<Decl>());
 
+  CurFunctionNeedsScopeChecking = false;
+  
   // See if this is a redefinition.
   const FunctionDecl *Definition;
   if (FD->getBody(Context, Definition)) {
@@ -2964,7 +2971,8 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) {
   if (!Body) return D;
 
   // Verify that that gotos and switch cases don't jump into scopes illegally.
-  DiagnoseInvalidJumps(Body);
+  if (CurFunctionNeedsScopeChecking)
+    DiagnoseInvalidJumps(Body);
 
   return D;
 }
index 208562f8f12dc959d26f157e3a335d06f9ed95fc..db81cacc2b685f9761868dc1b7db405edcb19bf4 100644 (file)
@@ -28,6 +28,8 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
   if (!MDecl)
     return;
 
+  CurFunctionNeedsScopeChecking = false;
+
   // Allow the rest of sema to find private method decl implementations.
   if (MDecl->isInstanceMethod())
     AddInstanceMethodToGlobalPool(MDecl);
index 4a5facb39ccec9540e5e682c7786a5b35f88b417..35dffa10f2af4ad51a3eaf5a17505f7c8d81b078 100644 (file)
@@ -1056,6 +1056,7 @@ Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, StmtArg Body) {
 Action::OwningStmtResult
 Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc,
                          StmtArg Try, StmtArg Catch, StmtArg Finally) {
+  CurFunctionNeedsScopeChecking = true;
   return Owned(new (Context) ObjCAtTryStmt(AtLoc,
                                         static_cast<Stmt*>(Try.release()),
                                         static_cast<Stmt*>(Catch.release()),
index 1d1c5aa2f9b2a2fbaaf9d550c70a66df4b5c1a4d..59fd832dc6373563d55256e4c101323d461a48b9 100644 (file)
@@ -164,8 +164,9 @@ L2:
   return;
 }
 
+
 // TODO: When and if gotos are allowed in blocks, this should work.
-void test11(int n) {
+void test13(int n) {
   void *P = ^{
     goto L1;  // expected-error {{goto not allowed in block literal}}
   L1:
@@ -180,11 +181,3 @@ void test11(int n) {
   };
 }
 
-
-
-#if 0
-// in Sema::CheckVariableDeclaration
-// FIXME: This won't give the correct result for
-// int a[10][n];    
-#endif
-