diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2012-03-08 00:22:50 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-03-08 00:22:50 +0000 |
commit | a34194f035096dd8dce10574e3a186da968aa211 (patch) | |
tree | 9bab5b692a8ef49d50856b3baac192f18dc4c829 | |
parent | 044e645605c6d75223e33d23e3c5701cb389969f (diff) |
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
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 26 | ||||
-rw-r--r-- | test/FixIt/fixit-recursive-block.c | 12 |
3 files changed, 36 insertions, 7 deletions
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<UninitializedMaybe>, DefaultIgnore; +def warn_uninit_byref_blockvar_captured_by_block : Warning< + "block pointer variable %0 is uninitialized when captured by block">, + InGroup<Uninitialized>, 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<BlocksAttr>()) { + 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<BlockExpr>(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<BlocksAttr>()) + 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 " |