Author: jrose
Date: Wed Apr 17 13:03:48 2013
New Revision: 179699

URL: http://llvm.org/viewvc/llvm-project?rev=179699&view=rev
Log:
[analyzer] Don't warn for returning void expressions in void blocks.

This was slightly tricky because BlockDecls don't currently store an
inferred return type. However, we can rely on the fact that blocks with
inferred return types will have return statements that match the inferred
type.

<rdar://problem/13665798>

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
    cfe/trunk/test/Analysis/uninit-vals-ps.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp?rev=179699&r1=179698&r2=179699&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp Wed Apr 17 
13:03:48 2013
@@ -55,8 +55,17 @@ void ReturnUndefChecker::checkPreStmt(co
     //   void test() {
     //     return foo();
     //   }
-    if (RT.isNull() || !RT->isVoidType())
-      emitUndef(C, RetE);
+    if (!RT.isNull() && RT->isVoidType())
+      return;
+
+    // Not all blocks have explicitly-specified return types; if the return 
type
+    // is not available, but the return value expression has 'void' type, 
assume
+    // Sema already checked it.
+    if (RT.isNull() && isa<BlockDecl>(SFC->getDecl()) &&
+        RetE->getType()->isVoidType())
+      return;
+
+    emitUndef(C, RetE);
     return;
   }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=179699&r1=179698&r2=179699&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Wed Apr 17 13:03:48 2013
@@ -239,8 +239,20 @@ QualType CallEvent::getDeclaredResultTyp
   assert(D);
   if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D))
     return FD->getResultType();
-  else if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D))
+  if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D))
     return MD->getResultType();
+  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
+    // Blocks are difficult because the return type may not be stored in the
+    // BlockDecl itself. The AST should probably be enhanced, but for now we
+    // just do what we can.
+    QualType Ty = BD->getSignatureAsWritten()->getType();
+    if (const FunctionType *FT = Ty->getAs<FunctionType>())
+      if (!FT->getResultType()->isDependentType())
+        return FT->getResultType();
+
+    return QualType();
+  }
+  
   return QualType();
 }
 

Modified: cfe/trunk/test/Analysis/uninit-vals-ps.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-vals-ps.c?rev=179699&r1=179698&r2=179699&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/uninit-vals-ps.c (original)
+++ cfe/trunk/test/Analysis/uninit-vals-ps.c Wed Apr 17 13:03:48 2013
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region 
-verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region 
-fblocks -verify %s
 
 struct FPRec {
   void (*my_func)(int * x);  
@@ -122,6 +122,8 @@ int pr4631_f1_b(void)
   return x;  // no-warning
 }
 
+// <rdar://problem/12278788> - FP when returning a void-valued expression from
+// a void function...or block.
 void foo_radar12278788() { return; }
 void test_radar12278788() {
   return foo_radar12278788(); // no-warning
@@ -134,3 +136,16 @@ int test_radar12278788_FP() {
   RetVoidFuncType f = foo_radar12278788_fp;
   return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage 
value returned to caller}}
 }
+
+void rdar13665798() {
+  ^() {
+    return foo_radar12278788(); // no-warning
+  }();
+  ^void() {
+    return foo_radar12278788(); // no-warning
+  }();
+  ^int() {
+    RetVoidFuncType f = foo_radar12278788_fp;
+    return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage 
value returned to caller}}
+  }();
+}


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to