From ad7013b1e612be7aaa722b4d5bba96643e797517 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Tue, 19 Aug 2008 13:04:19 +0000 Subject: [PATCH] Fix crasher in RewriteObjC::RewriteObjCSynchronizedStmt(). Can't depend on the source locations of the sync expression (since it may have been rewritten. Fixes clang ObjC rewriter: rewriting attached file causes assertion failure: invalid FileID llvm-svn: 54986 --- clang/Driver/RewriteObjC.cpp | 12 +++++++----- clang/test/Rewriter/objc-synchronized-1.m | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp index 8de2c0a69336..36e973d7236c 100644 --- a/clang/Driver/RewriteObjC.cpp +++ b/clang/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/clang/test/Rewriter/objc-synchronized-1.m b/clang/test/Rewriter/objc-synchronized-1.m index c2aa3486549e..5f8ae31d5d8c 100644 --- a/clang/test/Rewriter/objc-synchronized-1.m +++ b/clang/test/Rewriter/objc-synchronized-1.m @@ -13,4 +13,8 @@ void foo(id sem) return; } SYNC_AFTER(); + @synchronized ([sem self]) { + SYNCH_BODY(); + return; + } }