add support for goto checking and @synchronized blocks,

rdar://6810106


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69667 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2009-04-21 06:01:00 +00:00
Родитель 62f86c4555
Коммит 46c3c4ba78
5 изменённых файлов: 36 добавлений и 4 удалений

Просмотреть файл

@ -1410,10 +1410,12 @@ public:
ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
Stmt *synchBody) Stmt *synchBody)
: Stmt(ObjCAtSynchronizedStmtClass) { : Stmt(ObjCAtSynchronizedStmtClass) {
SubStmts[SYNC_EXPR] = synchExpr; SubStmts[SYNC_EXPR] = synchExpr;
SubStmts[SYNC_BODY] = synchBody; SubStmts[SYNC_BODY] = synchBody;
AtSynchronizedLoc = atSynchronizedLoc; AtSynchronizedLoc = atSynchronizedLoc;
} }
SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
const CompoundStmt *getSynchBody() const { const CompoundStmt *getSynchBody() const {
return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);

Просмотреть файл

@ -868,6 +868,8 @@ def note_protected_by_objc_catch : Note<
"jump bypasses initialization of @catch block">; "jump bypasses initialization of @catch block">;
def note_protected_by_objc_finally : Note< def note_protected_by_objc_finally : Note<
"jump bypasses initialization of @finally block">; "jump bypasses initialization of @finally block">;
def note_protected_by_objc_synchronized : Note<
"jump bypasses initialization of @synchronized block">;
def err_func_returning_array_function : Error< def err_func_returning_array_function : Error<
"function cannot return array or function type %0">; "function cannot return array or function type %0">;

Просмотреть файл

@ -168,6 +168,22 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
continue; continue;
} }
// Disallow jumps into the protected statement of an @synchronized, but
// allow jumps into the object expression it protects.
if (ObjCAtSynchronizedStmt *AS = dyn_cast<ObjCAtSynchronizedStmt>(SubStmt)){
// Recursively walk the AST for the @synchronized object expr, it is
// evaluated in the normal scope.
BuildScopeInformation(AS->getSynchExpr(), ParentScope);
// Recursively walk the AST for the @synchronized part, protected by a new
// scope.
Scopes.push_back(GotoScope(ParentScope,
diag::note_protected_by_objc_synchronized,
AS->getAtSynchronizedLoc()));
BuildScopeInformation(AS->getSynchBody(), Scopes.size()-1);
continue;
}
// Recursively walk the AST. // Recursively walk the AST.
BuildScopeInformation(SubStmt, ParentScope); BuildScopeInformation(SubStmt, ParentScope);
} }

Просмотреть файл

@ -1090,6 +1090,8 @@ Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg expr,Scope *CurScope) {
Action::OwningStmtResult Action::OwningStmtResult
Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr, Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
StmtArg SynchBody) { StmtArg SynchBody) {
CurFunctionNeedsScopeChecking = true;
return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc,
static_cast<Stmt*>(SynchExpr.release()), static_cast<Stmt*>(SynchExpr.release()),
static_cast<Stmt*>(SynchBody.release()))); static_cast<Stmt*>(SynchBody.release())));

Просмотреть файл

@ -44,6 +44,16 @@ L3: ;
} @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}} } @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}}
L8: ; L8: ;
} }
// rdar://6810106
id X;
goto L9; // expected-error{{illegal goto into protected scope}}
goto L10; // ok
@synchronized // expected-note {{jump bypasses initialization of @synchronized block}}
( ({ L10: ; X; })) {
L9:
;
}
} }
void test2(int a) { void test2(int a) {