]> granicus.if.org Git - clang/commitdiff
add support for goto checking and @synchronized blocks,
authorChris Lattner <sabre@nondot.org>
Tue, 21 Apr 2009 06:01:00 +0000 (06:01 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 21 Apr 2009 06:01:00 +0000 (06:01 +0000)
rdar://6810106

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69667 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Stmt.h
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/JumpDiagnostics.cpp
lib/Sema/SemaStmt.cpp
test/SemaObjC/scope-check.m

index 3c1e04f47aad4822df9222e8440c76f5ce72e56f..0d01d88e37201ad58db83188c6c8b6c5f358d441 100644 (file)
@@ -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<CompoundStmt*>(SubStmts[SYNC_BODY]);
index 28a97f87631277334ff653baf3635d5ccf000757..b270feccc885e7543d1bd4484792f00e5cda1b6e 100644 (file)
@@ -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">;
index 82db0bbd2c3c89ae0888c1a44973bbd57ddba17c..b812f06f76be3063d6764fcc2a8c12b775534d91 100644 (file)
@@ -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<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.
     BuildScopeInformation(SubStmt, ParentScope);
   }
index 35dffa10f2af4ad51a3eaf5a17505f7c8d81b078..26cba5bec74e8596f5f141d54bb697342fc46ae2 100644 (file)
@@ -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<Stmt*>(SynchExpr.release()),
                      static_cast<Stmt*>(SynchBody.release())));
index 7da4e429a68abab3a12a4b1d938df37b02d3640a..0835373ba7484c4d1394896c7714c32e0c45521c 100644 (file)
@@ -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) {