r182497 - [analyzer] Don't crash if a block doesn't have a type signature.

Jordan Rose jordan_rose at apple.com
Wed May 22 11:09:44 PDT 2013


Author: jrose
Date: Wed May 22 13:09:44 2013
New Revision: 182497

URL: http://llvm.org/viewvc/llvm-project?rev=182497&view=rev
Log:
[analyzer] Don't crash if a block doesn't have a type signature.

Currently, blocks instantiated in templates lose their "signature as
written"; it's not clear if this is intentional. Change the analyzer's
use of BlockDecl::getSignatureAsWritten to check whether or not the
signature is actually there.

<rdar://problem/13954714>

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp
    cfe/trunk/test/Analysis/templates.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=182497&r1=182496&r2=182497&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Wed May 22 13:09:44 2013
@@ -245,10 +245,13 @@ QualType CallEvent::getDeclaredResultTyp
     // 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>())
+    // FIXME: All blocks should have signatures-as-written, even if the return
+    // type is inferred. (That's signified is with a dependent result type.)
+    if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) {
+      const FunctionType *FT = TSI->getType()->castAs<FunctionType>();
       if (!FT->getResultType()->isDependentType())
         return FT->getResultType();
+    }
 
     return QualType();
   }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp?rev=182497&r1=182496&r2=182497&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp Wed May 22 13:09:44 2013
@@ -806,10 +806,19 @@ const VarRegion* MemRegionManager::getVa
           sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
                                   getFunctionTextRegion(cast<NamedDecl>(STCD)));
         else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
+          // FIXME: The fallback type here is totally bogus -- though it should
+          // never be queried, it will prevent uniquing with the real
+          // BlockTextRegion. Ideally we'd fix the AST so that we always had a
+          // signature.
+          QualType T;
+          if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
+            T = TSI->getType();
+          else
+            T = getContext().getFunctionNoProtoType(getContext().VoidTy);
+          
           const BlockTextRegion *BTR =
-            getBlockTextRegion(BD,
-                     C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
-                     STC->getAnalysisDeclContext());
+            getBlockTextRegion(BD, C.getCanonicalType(T),
+                               STC->getAnalysisDeclContext());
           sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
                                   BTR);
         }

Modified: cfe/trunk/test/Analysis/templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/templates.cpp?rev=182497&r1=182496&r2=182497&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/templates.cpp (original)
+++ cfe/trunk/test/Analysis/templates.cpp Wed May 22 13:09:44 2013
@@ -48,3 +48,25 @@ void testNonTypeTemplateInstantiation()
 #endif
 }
 
+namespace rdar13954714 {
+  template <bool VALUE>
+  bool blockInTemplate() {
+    return (^() {
+      return VALUE;
+    })();
+  }
+
+  // force instantiation
+  template bool blockInTemplate<true>();
+
+  template <bool VALUE>
+  void blockWithStatic() {
+    (void)^() {
+      static int x;
+      return ++x;
+    };
+  }
+
+  // force instantiation
+  template void blockWithStatic<true>();
+}





More information about the cfe-commits mailing list