aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-04-19 05:21:20 +0000
committerChris Lattner <sabre@nondot.org>2009-04-19 05:21:20 +0000
commit38c5ebd7b1b65304c7b5c7b9bf3f9162df22e77d (patch)
treef35fc7fc5142abf6533b8e22f9dc80dccd7a0e49
parent4f9c06ae362c10af797957b92a46fe91d5874899 (diff)
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
-rw-r--r--lib/Sema/Sema.h6
-rw-r--r--lib/Sema/SemaDecl.cpp26
-rw-r--r--lib/Sema/SemaDeclObjC.cpp2
-rw-r--r--lib/Sema/SemaStmt.cpp1
-rw-r--r--test/Sema/scope-check.c11
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<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.
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<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;
}
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<Stmt*>(Try.release()),
static_cast<Stmt*>(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
-