r179699 - [analyzer] Don't warn for returning void expressions in void blocks.

Jordan Rose jordan_rose at apple.com
Wed Apr 17 11:03:48 PDT 2013


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}}
+  }();
+}





More information about the cfe-commits mailing list