From 38c5ebd7b1b65304c7b5c7b9bf3f9162df22e77d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 19 Apr 2009 05:21:20 +0000 Subject: [PATCH] add a new Sema::CurFunctionNeedsScopeChecking bool that is used to avoid 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 | 6 ++++++ lib/Sema/SemaDecl.cpp | 26 +++++++++++++++++--------- lib/Sema/SemaDeclObjC.cpp | 2 ++ lib/Sema/SemaStmt.cpp | 1 + test/Sema/scope-check.c | 11 ++--------- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index b08a120e58..e8742e8e51 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -153,6 +153,12 @@ public: /// handle the case when they are in a block. llvm::SmallVector 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. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 887c86cef5..7ed0e2dd31 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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()) 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()) + 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(D.getAs()); + 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; } diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 208562f8f1..db81cacc2b 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -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); diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 4a5facb39c..35dffa10f2 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -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(Try.release()), static_cast(Catch.release()), diff --git a/test/Sema/scope-check.c b/test/Sema/scope-check.c index 1d1c5aa2f9..59fd832dc6 100644 --- a/test/Sema/scope-check.c +++ b/test/Sema/scope-check.c @@ -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 - -- 2.40.0