From: Fariborz Jahanian Date: Thu, 8 Mar 2012 00:22:50 +0000 (+0000) Subject: improve on diagnostic and provide a fixit hint when X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a34194f035096dd8dce10574e3a186da968aa211;p=clang improve on diagnostic and provide a fixit hint when an uninitialized block variable is being called inside the block literal. // rdar://10817031 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152271 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 6ea8962322..ec7a0597f1 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1143,6 +1143,11 @@ def warn_uninit_var_captured_by_block : Warning< def warn_maybe_uninit_var_captured_by_block : Warning< "variable %0 may be uninitialized when captured by block">, InGroup, DefaultIgnore; +def warn_uninit_byref_blockvar_captured_by_block : Warning< + "block pointer variable %0 is uninitialized when captured by block">, + InGroup, DefaultIgnore; +def note_block_var_fixit_add_initialization : Note< + "consider using a '__block' variable %0 to silence this warning">; def note_var_fixit_add_initialization : Note< "initialize the variable %0 to silence this warning">; def err_init_incomplete_type : Error<"initialization of incomplete type %0">; diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index bcb138118d..13ab5428b8 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -425,17 +425,24 @@ public: } static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) { + QualType VariableTy = VD->getType().getCanonicalType(); + if (VariableTy->isBlockPointerType() && + !VD->hasAttr()) { + S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) << VD->getDeclName() + << FixItHint::CreateInsertion(VD->getLocation(), "__block "); + return true; + } + // Don't issue a fixit if there is already an initializer. if (VD->getInit()) return false; - + // Suggest possible initialization (if any). - QualType VariableTy = VD->getType().getCanonicalType(); const char *Init = S.getFixItZeroInitializerForType(VariableTy); if (!Init) return false; - SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd()); + S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName() << FixItHint::CreateInsertion(Loc, Init); return true; @@ -489,10 +496,15 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD, } } else { const BlockExpr *BE = cast(E); - S.Diag(BE->getLocStart(), - isAlwaysUninit ? diag::warn_uninit_var_captured_by_block - : diag::warn_maybe_uninit_var_captured_by_block) - << VD->getDeclName(); + if (VD->getType()->isBlockPointerType() && + !VD->hasAttr()) + S.Diag(BE->getLocStart(), diag::warn_uninit_byref_blockvar_captured_by_block) + << VD->getDeclName(); + else + S.Diag(BE->getLocStart(), + isAlwaysUninit ? diag::warn_uninit_var_captured_by_block + : diag::warn_maybe_uninit_var_captured_by_block) + << VD->getDeclName(); } // Report where the variable was declared when the use wasn't within diff --git a/test/FixIt/fixit-recursive-block.c b/test/FixIt/fixit-recursive-block.c new file mode 100644 index 0000000000..c1f69266b3 --- /dev/null +++ b/test/FixIt/fixit-recursive-block.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wuninitialized -fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wuninitialized -fblocks -verify %s + +// rdar://10817031 + +int main() { + void (^arc_fail)() = ^() { // expected-warning {{block pointer variable 'arc_fail' is uninitialized when captured by block}} \ + // expected-note {{consider using a '__block' variable 'arc_fail' to silence this warning}} + arc_fail(); // BOOM + }; +} +// CHECK: {7:12-7:12}:"__block "