diff options
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 26 | ||||
| -rw-r--r-- | clang/test/SemaObjC/arc.m | 7 |
2 files changed, 31 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ce4c22bb7f9..e76a8b6da0f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13634,8 +13634,30 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var, if (BuildAndDiagnose) { SourceLocation VarLoc = Var->getLocation(); S.Diag(Loc, diag::warn_block_capture_autoreleasing); - S.Diag(VarLoc, diag::note_declare_parameter_autoreleasing) << - FixItHint::CreateInsertion(VarLoc, "__autoreleasing"); + { + auto AddAutoreleaseNote = + S.Diag(VarLoc, diag::note_declare_parameter_autoreleasing); + // Provide a fix-it for the '__autoreleasing' keyword at the + // appropriate location in the variable's type. + if (const auto *TSI = Var->getTypeSourceInfo()) { + PointerTypeLoc PTL = + TSI->getTypeLoc().getAsAdjusted<PointerTypeLoc>(); + if (PTL) { + SourceLocation Loc = PTL.getPointeeLoc().getEndLoc(); + Loc = Lexer::getLocForEndOfToken(Loc, 0, S.getSourceManager(), + S.getLangOpts()); + if (Loc.isValid()) { + StringRef CharAtLoc = Lexer::getSourceText( + CharSourceRange::getCharRange(Loc, Loc.getLocWithOffset(1)), + S.getSourceManager(), S.getLangOpts()); + AddAutoreleaseNote << FixItHint::CreateInsertion( + Loc, CharAtLoc.empty() || !isWhitespace(CharAtLoc[0]) + ? " __autoreleasing " + : " __autoreleasing"); + } + } + } + } S.Diag(VarLoc, diag::note_declare_parameter_strong); } } diff --git a/clang/test/SemaObjC/arc.m b/clang/test/SemaObjC/arc.m index 72c07a9ff10..e90d0a87e31 100644 --- a/clang/test/SemaObjC/arc.m +++ b/clang/test/SemaObjC/arc.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s +// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -Wno-objc-root-class -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s typedef unsigned long NSUInteger; typedef const void * CFTypeRef; @@ -821,6 +822,12 @@ void block_capture_autoreleasing(A * __autoreleasing *a, id _Nullable __autoreleasing *j, id * _Nullable k, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} id __autoreleasing * _Nullable l) { + // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:37-[[@LINE-11]]:37}:" __autoreleasing " + // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:47-[[@LINE-11]]:47}:" __autoreleasing" + // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:37-[[@LINE-10]]:37}:" __autoreleasing " + // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:36-[[@LINE-8]]:36}:" __autoreleasing" + // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:46-[[@LINE-8]]:46}:" __autoreleasing" + // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:36-[[@LINE-7]]:36}:" __autoreleasing" ^{ (void)*a; (void)*b; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} |

