Browse Source

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

Fariborz Jahanian 13 years ago
parent
commit
a34194f035

+ 5 - 0
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<
 def warn_maybe_uninit_var_captured_by_block : Warning<
   "variable %0 may be uninitialized when captured by block">,
   "variable %0 may be uninitialized when captured by block">,
   InGroup<UninitializedMaybe>, DefaultIgnore;
   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<
 def note_var_fixit_add_initialization : Note<
   "initialize the variable %0 to silence this warning">;
   "initialize the variable %0 to silence this warning">;
 def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
 def err_init_incomplete_type : Error<"initialization of incomplete type %0">;

+ 19 - 7
lib/Sema/AnalysisBasedWarnings.cpp

@@ -425,17 +425,24 @@ public:
 }
 }
 
 
 static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
 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.
   // Don't issue a fixit if there is already an initializer.
   if (VD->getInit())
   if (VD->getInit())
     return false;
     return false;
-
+  
   // Suggest possible initialization (if any).
   // Suggest possible initialization (if any).
-  QualType VariableTy = VD->getType().getCanonicalType();
   const char *Init = S.getFixItZeroInitializerForType(VariableTy);
   const char *Init = S.getFixItZeroInitializerForType(VariableTy);
   if (!Init)
   if (!Init)
     return false;
     return false;
-
   SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
   SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
+  
   S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
   S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
     << FixItHint::CreateInsertion(Loc, Init);
     << FixItHint::CreateInsertion(Loc, Init);
   return true;
   return true;
@@ -489,10 +496,15 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
     }
     }
   } else {
   } else {
     const BlockExpr *BE = cast<BlockExpr>(E);
     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
   // Report where the variable was declared when the use wasn't within

+ 12 - 0
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 "