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