NoQ created this revision.
Herald added a subscriber: xazax.hun.

The analyzer crashes when the user tries to allocate stack memory through 
`alloca()` and then construct an Objective-C object in it. The `alloca()` 
function is handled in the analyzer by its own concrete untyped memory region, 
`AllocaRegion`, which doesn't contain any clues on what type it might carry 
(because there are none). `getDynamicTypeInfo()` therefore ignores it unless a 
specific type info is already available.

To think: maybe we could pickup some dynamic type info from the implicit cast. 
We don't always have an implicit cast though.


https://reviews.llvm.org/D33828

Files:
  lib/StaticAnalyzer/Core/CallEvent.cpp
  test/Analysis/DynamicTypePropagation.m


Index: test/Analysis/DynamicTypePropagation.m
===================================================================
--- test/Analysis/DynamicTypePropagation.m
+++ test/Analysis/DynamicTypePropagation.m
@@ -4,6 +4,9 @@
 #  error Compiler does not support Objective-C generics?
 #endif
 
+typedef __typeof(sizeof(int)) size_t;
+void *memset(void *, int, size_t);
+
 #define nil 0
 typedef unsigned long NSUInteger;
 typedef int BOOL;
@@ -21,6 +24,7 @@
 @end
 
 @interface NSArray<ObjectType> : NSObject
+- (void) init;
 - (BOOL)contains:(ObjectType)obj;
 - (ObjectType)getObjAtIndex:(NSUInteger)idx;
 - (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx;
@@ -55,3 +59,11 @@
   // MyType!
   [element myFunction:0 myParam:0 ];
 }
+
+// Do not try this at home! The analyzer shouldn't crash though when it
+// tries to figure out the dynamic type behind the alloca's return value.
+void testAlloca(size_t NSArrayClassSizeWeKnowSomehow) {
+  NSArray *arr = __builtin_alloca(NSArrayClassSizeWeKnowSomehow);
+  memset(arr, 0, NSArrayClassSizeWeKnowSomehow);
+  [arr init]; // no-crash
+}
Index: lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CallEvent.cpp
+++ lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -957,6 +957,9 @@
         return RuntimeDefinition();
 
       DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
+      if (!DTI.isValid()) // Might be AllocaRegion.
+        return RuntimeDefinition();
+
       QualType DynType = DTI.getType();
       CanBeSubClassed = DTI.canBeASubClass();
       ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());


Index: test/Analysis/DynamicTypePropagation.m
===================================================================
--- test/Analysis/DynamicTypePropagation.m
+++ test/Analysis/DynamicTypePropagation.m
@@ -4,6 +4,9 @@
 #  error Compiler does not support Objective-C generics?
 #endif
 
+typedef __typeof(sizeof(int)) size_t;
+void *memset(void *, int, size_t);
+
 #define nil 0
 typedef unsigned long NSUInteger;
 typedef int BOOL;
@@ -21,6 +24,7 @@
 @end
 
 @interface NSArray<ObjectType> : NSObject
+- (void) init;
 - (BOOL)contains:(ObjectType)obj;
 - (ObjectType)getObjAtIndex:(NSUInteger)idx;
 - (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx;
@@ -55,3 +59,11 @@
   // MyType!
   [element myFunction:0 myParam:0 ];
 }
+
+// Do not try this at home! The analyzer shouldn't crash though when it
+// tries to figure out the dynamic type behind the alloca's return value.
+void testAlloca(size_t NSArrayClassSizeWeKnowSomehow) {
+  NSArray *arr = __builtin_alloca(NSArrayClassSizeWeKnowSomehow);
+  memset(arr, 0, NSArrayClassSizeWeKnowSomehow);
+  [arr init]; // no-crash
+}
Index: lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CallEvent.cpp
+++ lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -957,6 +957,9 @@
         return RuntimeDefinition();
 
       DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
+      if (!DTI.isValid()) // Might be AllocaRegion.
+        return RuntimeDefinition();
+
       QualType DynType = DTI.getType();
       CanBeSubClassed = DTI.canBeASubClass();
       ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to