From e80f767a1deee63608df9864f80e237740a1039f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 18 Apr 2009 07:47:21 +0000 Subject: [PATCH] split code out into a new CheckFunctionJumpScopes routine, add some comments, change type from void* -> Stmt*, use smallvector instead of vector. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69430 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 76 +++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d714a19ba5..7c3e7e035e 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2905,30 +2905,35 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) { return DeclPtrTy::make(FD); } -static bool StatementCreatesScope(Stmt* S) { +/// StatementCreatesScope - Return true if the specified statement should start +/// a new cleanup scope that cannot be entered with a goto. +static bool StatementCreatesScope(Stmt *S) { + // Only decl statements create scopes. + DeclStmt *DS = dyn_cast(S); + if (DS == 0) return false; - if (DeclStmt *DS = dyn_cast(S)) { - for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); - I != E; ++I) { - if (VarDecl *D = dyn_cast(*I)) { - if (D->getType()->isVariablyModifiedType() || - D->hasAttr()) - return true; - } else if (TypedefDecl *D = dyn_cast(*I)) { - if (D->getUnderlyingType()->isVariablyModifiedType()) - return true; - } + // The decl statement creates a scope if any of the decls in it are VLAs or + // have the cleanup attribute. + for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); + I != E; ++I) { + if (VarDecl *D = dyn_cast(*I)) { + if (D->getType()->isVariablyModifiedType() || + D->hasAttr()) + return true; + } else if (TypedefDecl *D = dyn_cast(*I)) { + if (D->getUnderlyingType()->isVariablyModifiedType()) + return true; } - } + } return false; } -static void RecursiveCalcLabelScopes(llvm::DenseMap& LabelScopeMap, - llvm::DenseMap& PopScopeMap, - std::vector& ScopeStack, - Stmt* CurStmt, - Stmt* ParentCompoundStmt, Sema &S) { +static void RecursiveCalcLabelScopes(llvm::DenseMap &LabelScopeMap, + llvm::DenseMap &PopScopeMap, + llvm::SmallVectorImpl &ScopeStack, + Stmt *CurStmt, Stmt *ParentCompoundStmt, + Sema &S) { for (Stmt::child_iterator i = CurStmt->child_begin(); i != CurStmt->child_end(); ++i) { if (!*i) continue; @@ -2958,10 +2963,10 @@ static void RecursiveCalcLabelScopes(llvm::DenseMap& LabelScopeMap ScopeStack.pop_back(); } -static void RecursiveCalcJumpScopes(llvm::DenseMap& LabelScopeMap, - llvm::DenseMap& PopScopeMap, - llvm::DenseMap& GotoScopeMap, - std::vector& ScopeStack, +static void RecursiveCalcJumpScopes(llvm::DenseMap &LabelScopeMap, + llvm::DenseMap &PopScopeMap, + llvm::DenseMap &GotoScopeMap, + llvm::SmallVectorImpl &ScopeStack, Stmt *CurStmt, Sema &S) { for (Stmt::child_iterator i = CurStmt->child_begin(); i != CurStmt->child_end(); ++i) { @@ -2989,6 +2994,20 @@ static void RecursiveCalcJumpScopes(llvm::DenseMap& LabelScopeMap, ScopeStack.pop_back(); } +/// CheckFunctionJumpScopes - Check the body of a function to see if gotos obey +/// the scopes of VLAs and other things correctly. +static void CheckFunctionJumpScopes(Stmt *Body, Sema &S) { + llvm::DenseMap LabelScopeMap; + llvm::DenseMap PopScopeMap; + llvm::DenseMap GotoScopeMap; + llvm::SmallVector ScopeStack; + RecursiveCalcLabelScopes(LabelScopeMap, PopScopeMap, ScopeStack, Body, Body, + S); + RecursiveCalcJumpScopes(LabelScopeMap, PopScopeMap, GotoScopeMap, + ScopeStack, Body, S); +} + + Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) { Decl *dcl = D.getAs(); Stmt *Body = static_cast(BodyArg.release()); @@ -3039,16 +3058,9 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) { if (!Body) return D; - if (HaveLabels) { - llvm::DenseMap LabelScopeMap; - llvm::DenseMap PopScopeMap; - llvm::DenseMap GotoScopeMap; - std::vector ScopeStack; - RecursiveCalcLabelScopes(LabelScopeMap, PopScopeMap, ScopeStack, Body, Body, - *this); - RecursiveCalcJumpScopes(LabelScopeMap, PopScopeMap, GotoScopeMap, - ScopeStack, Body, *this); - } + // If we have labels, verify that goto doesn't jump into scopes illegally. + if (HaveLabels) + CheckFunctionJumpScopes(Body, *this); return D; } -- 2.40.0