[cfe-commits] r109962 - in /cfe/trunk: lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaStmt.cpp test/Analysis/misc-ps.m test/CodeGen/statements.c
John McCall
rjmccall at apple.com
Sat Jul 31 17:26:45 PDT 2010
Author: rjmccall
Date: Sat Jul 31 19:26:45 2010
New Revision: 109962
URL: http://llvm.org/viewvc/llvm-project?rev=109962&view=rev
Log:
Only run the jump-checker if there's a branch-protected scope *and* there's
a switch or goto somewhere in the function. Indirect gotos trigger the
jump-checker regardless, because the conditions there are slightly more
elaborate and it's too marginal a case to be worth optimizing.
Turns off the jump-checker in a lot of cases in C++. rdar://problem/7702918
Modified:
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/test/Analysis/misc-ps.m
cfe/trunk/test/CodeGen/statements.c
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=109962&r1=109961&r2=109962&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Sat Jul 31 19:26:45 2010
@@ -31,7 +31,10 @@
FunctionScopeInfo::~FunctionScopeInfo() { }
void FunctionScopeInfo::Clear(unsigned NumErrors) {
- NeedsScopeChecking = false;
+ HasBranchProtectedScope = false;
+ HasBranchIntoScope = false;
+ HasIndirectGoto = false;
+
LabelMap.clear();
SwitchStack.clear();
Returns.clear();
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=109962&r1=109961&r2=109962&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Jul 31 19:26:45 2010
@@ -116,11 +116,15 @@
/// a block.
bool IsBlockInfo;
- /// \brief Set true when a function, method contains a VLA or 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 NeedsScopeChecking;
+ /// \brief Whether this function contains a VLA, @try, try, C++
+ /// initializer, or anything else that can't be jumped past.
+ bool HasBranchProtectedScope;
+
+ /// \brief Whether this function contains any switches or direct gotos.
+ bool HasBranchIntoScope;
+
+ /// \brief Whether this function contains any indirect gotos.
+ bool HasIndirectGoto;
/// \brief The number of errors that had occurred before starting this
/// function or block.
@@ -139,9 +143,17 @@
/// block, if there is any chance of applying the named return value
/// optimization.
llvm::SmallVector<ReturnStmt *, 4> Returns;
+
+ bool NeedsScopeChecking() const {
+ return HasIndirectGoto ||
+ (HasBranchProtectedScope && HasBranchIntoScope);
+ }
FunctionScopeInfo(unsigned NumErrors)
- : IsBlockInfo(false), NeedsScopeChecking(false),
+ : IsBlockInfo(false),
+ HasBranchProtectedScope(false),
+ HasBranchIntoScope(false),
+ HasIndirectGoto(false),
NumErrorsAtStartOfFunction(NumErrors) { }
virtual ~FunctionScopeInfo();
@@ -706,13 +718,28 @@
/// \brief Determine whether the current function or block needs scope
/// checking.
- bool &FunctionNeedsScopeChecking() {
- if (FunctionScopes.empty())
- return TopFunctionScope.NeedsScopeChecking;
+ bool FunctionNeedsScopeChecking() {
+ if (!FunctionScopes.empty())
+ return FunctionScopes.back()->NeedsScopeChecking();
+ return false;
+ }
- return FunctionScopes.back()->NeedsScopeChecking;
+ void setFunctionHasBranchIntoScope() {
+ if (!FunctionScopes.empty())
+ FunctionScopes.back()->HasBranchIntoScope = true;
}
+ void setFunctionHasBranchProtectedScope() {
+ if (!FunctionScopes.empty())
+ FunctionScopes.back()->HasBranchProtectedScope = true;
+ }
+
+ void setFunctionHasIndirectGoto() {
+ if (!FunctionScopes.empty())
+ FunctionScopes.back()->HasIndirectGoto = true;
+ }
+
+
bool hasAnyErrorsInThisFunction() const;
/// \brief Retrieve the current block, if any.
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=109962&r1=109961&r2=109962&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Jul 31 19:26:45 2010
@@ -2380,7 +2380,7 @@
// then it shall have block scope.
QualType T = NewTD->getUnderlyingType();
if (T->isVariablyModifiedType()) {
- FunctionNeedsScopeChecking() = true;
+ setFunctionHasBranchProtectedScope();
if (S->getFnParent() == 0) {
bool SizeIsNegative;
@@ -2794,12 +2794,8 @@
bool isVM = T->isVariablyModifiedType();
if (isVM || NewVD->hasAttr<CleanupAttr>() ||
NewVD->hasAttr<BlocksAttr>() ||
- // FIXME: We need to diagnose jumps passed initialized variables in C++.
- // However, this turns on the scope checker for everything with a variable
- // which may impact compile time. See if we can find a better solution
- // to this, perhaps only checking functions that contain gotos in C++?
(LangOpts.CPlusPlus && NewVD->hasLocalStorage()))
- FunctionNeedsScopeChecking() = true;
+ setFunctionHasBranchProtectedScope();
if ((isVM && NewVD->hasLinkage()) ||
(T->isVariableArrayType() && NewVD->hasGlobalStorage())) {
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=109962&r1=109961&r2=109962&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Sat Jul 31 19:26:45 2010
@@ -441,6 +441,8 @@
if (!CondExpr)
return StmtError();
}
+
+ setFunctionHasBranchIntoScope();
SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, CondExpr);
getSwitchStack().push_back(SS);
@@ -962,6 +964,8 @@
// Look up the record for this label identifier.
LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+ setFunctionHasBranchIntoScope();
+
// If we haven't seen this label yet, create a forward reference.
if (LabelDecl == 0)
LabelDecl = new (Context) LabelStmt(LabelLoc, LabelII, 0);
@@ -982,6 +986,9 @@
if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
return StmtError();
}
+
+ setFunctionHasIndirectGoto();
+
return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
}
@@ -1504,7 +1511,7 @@
Action::OwningStmtResult
Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, StmtArg Try,
MultiStmtArg CatchStmts, StmtArg Finally) {
- FunctionNeedsScopeChecking() = true;
+ setFunctionHasBranchProtectedScope();
unsigned NumCatchStmts = CatchStmts.size();
return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try.takeAs<Stmt>(),
(Stmt **)CatchStmts.release(),
@@ -1549,7 +1556,7 @@
Action::OwningStmtResult
Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
StmtArg SynchBody) {
- FunctionNeedsScopeChecking() = true;
+ setFunctionHasBranchProtectedScope();
// Make sure the expression type is an ObjC pointer or "void *".
Expr *SyncExpr = static_cast<Expr*>(SynchExpr.get());
@@ -1658,13 +1665,14 @@
}
}
+ setFunctionHasBranchProtectedScope();
+
// FIXME: We should detect handlers that cannot catch anything because an
// earlier handler catches a superclass. Need to find a method that is not
// quadratic for this.
// Neither of these are explicitly forbidden, but every compiler detects them
// and warns.
- FunctionNeedsScopeChecking() = true;
RawHandlers.release();
return Owned(CXXTryStmt::Create(Context, TryLoc,
static_cast<Stmt*>(TryBlock.release()),
Modified: cfe/trunk/test/Analysis/misc-ps.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps.m?rev=109962&r1=109961&r2=109962&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps.m (original)
+++ cfe/trunk/test/Analysis/misc-ps.m Sat Jul 31 19:26:45 2010
@@ -298,6 +298,7 @@
typedef void *Opcode;
Opcode pr_4033_getOpcode();
void pr_4033(void) {
+ void *lbl = &&next_opcode;
next_opcode:
{
Opcode op = pr_4033_getOpcode();
Modified: cfe/trunk/test/CodeGen/statements.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/statements.c?rev=109962&r1=109961&r2=109962&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/statements.c (original)
+++ cfe/trunk/test/CodeGen/statements.c Sat Jul 31 19:26:45 2010
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wreturn-type < %s -emit-llvm
+// RUN: %clang_cc1 -Wreturn-type %s -emit-llvm
void test1(int x) {
switch (x) {
@@ -31,5 +31,10 @@
}
// PR3869
-int test5(long long b) { goto *b; }
+int test5(long long b) {
+ static void *lbls[] = { &&lbl };
+ goto *b;
+ lbl:
+ return 0;
+}
More information about the cfe-commits
mailing list