diff options
author | Steve Naroff <snaroff@apple.com> | 2008-08-19 13:04:19 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2008-08-19 13:04:19 +0000 |
commit | c7089f1be946f3ca6e59596f0e0f92d96136e4c8 (patch) | |
tree | a37b898942a6f5af978d21a2846f906fb52e231a | |
parent | e9d89d886a240f9ba7c49bfdeac4e468ac92f674 (diff) |
Fix crasher in RewriteObjC::RewriteObjCSynchronizedStmt(). Can't depend on the source locations of the sync expression (since it may have been rewritten.
Fixes <rdar://problem/6156363> clang ObjC rewriter: rewriting attached file causes assertion failure: invalid FileID
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54986 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Driver/RewriteObjC.cpp | 12 | ||||
-rw-r--r-- | test/Rewriter/objc-synchronized-1.m | 4 |
2 files changed, 11 insertions, 5 deletions
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp index 8de2c0a693..36e973d723 100644 --- a/Driver/RewriteObjC.cpp +++ b/Driver/RewriteObjC.cpp @@ -1304,11 +1304,13 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { std::string buf; buf = "objc_sync_enter"; ReplaceText(startLoc, 13, buf.c_str(), buf.size()); - SourceLocation endLoc = S->getSynchExpr()->getLocEnd(); + // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since + // the sync expression is typically a message expression that's already + // been rewritten! (which implies the SourceLocation's are invalid). + SourceLocation endLoc = S->getSynchBody()->getLocStart(); const char *endBuf = SM->getCharacterData(endLoc); - endBuf++; - const char *rparenBuf = strchr(endBuf, ')'); - SourceLocation rparenLoc = startLoc.getFileLocWithOffset(rparenBuf-startBuf); + while (*endBuf != ')') endBuf--; + SourceLocation rparenLoc = startLoc.getFileLocWithOffset(endBuf-startBuf); buf = ");\n"; // declare a new scope with two variables, _stack and _rethrow. buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n"; @@ -1321,7 +1323,7 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { startLoc = S->getSynchBody()->getLocEnd(); startBuf = SM->getCharacterData(startLoc); - assert((*startBuf == '}') && "bogus @try block"); + assert((*startBuf == '}') && "bogus @synchronized block"); SourceLocation lastCurlyLoc = startLoc; buf = "}\nelse {\n"; buf += " _rethrow = objc_exception_extract(&_stack);\n"; diff --git a/test/Rewriter/objc-synchronized-1.m b/test/Rewriter/objc-synchronized-1.m index c2aa348654..5f8ae31d5d 100644 --- a/test/Rewriter/objc-synchronized-1.m +++ b/test/Rewriter/objc-synchronized-1.m @@ -13,4 +13,8 @@ void foo(id sem) return; } SYNC_AFTER(); + @synchronized ([sem self]) { + SYNCH_BODY(); + return; + } } |