From: Chris Lattner Date: Tue, 21 Apr 2009 06:01:00 +0000 (+0000) Subject: add support for goto checking and @synchronized blocks, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=46c3c4ba78766ac0f1c5ec631b424773e21f5271;p=clang 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 --- diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 3c1e04f47a..0d01d88e37 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -1410,10 +1410,12 @@ public: ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, Stmt *synchBody) : Stmt(ObjCAtSynchronizedStmtClass) { - SubStmts[SYNC_EXPR] = synchExpr; - SubStmts[SYNC_BODY] = synchBody; - AtSynchronizedLoc = atSynchronizedLoc; - } + SubStmts[SYNC_EXPR] = synchExpr; + SubStmts[SYNC_BODY] = synchBody; + AtSynchronizedLoc = atSynchronizedLoc; + } + + SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; } const CompoundStmt *getSynchBody() const { return reinterpret_cast(SubStmts[SYNC_BODY]); diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 28a97f8763..b270feccc8 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -868,6 +868,8 @@ def note_protected_by_objc_catch : Note< "jump bypasses initialization of @catch block">; def note_protected_by_objc_finally : Note< "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< "function cannot return array or function type %0">; diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp index 82db0bbd2c..b812f06f76 100644 --- a/lib/Sema/JumpDiagnostics.cpp +++ b/lib/Sema/JumpDiagnostics.cpp @@ -168,6 +168,22 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) { continue; } + // Disallow jumps into the protected statement of an @synchronized, but + // allow jumps into the object expression it protects. + if (ObjCAtSynchronizedStmt *AS = dyn_cast(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. BuildScopeInformation(SubStmt, ParentScope); } diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 35dffa10f2..26cba5bec7 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1090,6 +1090,8 @@ Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg expr,Scope *CurScope) { Action::OwningStmtResult Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr, StmtArg SynchBody) { + CurFunctionNeedsScopeChecking = true; + return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, static_cast(SynchExpr.release()), static_cast(SynchBody.release()))); diff --git a/test/SemaObjC/scope-check.m b/test/SemaObjC/scope-check.m index 7da4e429a6..0835373ba7 100644 --- a/test/SemaObjC/scope-check.m +++ b/test/SemaObjC/scope-check.m @@ -44,6 +44,16 @@ L3: ; } @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}} 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) {