diff --git a/clang/lib/AST/CFG.cpp b/clang/lib/AST/CFG.cpp index e601d4ff69eb..f5b604554d89 100644 --- a/clang/lib/AST/CFG.cpp +++ b/clang/lib/AST/CFG.cpp @@ -140,9 +140,7 @@ public: // a 'return'. CFGBlock* VisitObjCAtThrowStmt(ObjCAtThrowStmt* S); - CFGBlock* VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S){ - return NYS(); - } + CFGBlock* VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S); // Blocks. CFGBlock* VisitBlockExpr(BlockExpr* E) { return NYS(); } @@ -935,6 +933,16 @@ CFGBlock* CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) { return addStmt(S->getCollection()); } +CFGBlock* CFGBuilder::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S) { + // FIXME: Add locking 'primitives' to CFG for @synchronized. + + // Inline the body. + Visit(S->getSynchBody()); + + // Inline the sync expression. + return Visit(S->getSynchExpr()); +} + CFGBlock* CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt* S) { return NYS(); } diff --git a/clang/test/Analysis/NSString.m b/clang/test/Analysis/NSString.m index 160c64c21fc9..2f6d5912cf8a 100644 --- a/clang/test/Analysis/NSString.m +++ b/clang/test/Analysis/NSString.m @@ -271,3 +271,11 @@ typedef NSString* WonkyTypedef; void test_isTrackedObjectType(void) { NSString *str = [TestIsTracked newString]; // expected-warning{{Potential leak}} } + +// Test @synchronized +void test_synchronized(id x) { + @synchronized(x) { + NSString *string = [[NSString stringWithFormat:@"%ld", (long) 100] retain]; // expected-warning {{leak}} + } +} +