Skip to content

Commit

Permalink
[analyzer] Fix a crash when an ObjC object is constructed in AllocaRe…
Browse files Browse the repository at this point in the history
…gion.

Memory region allocated by alloca() carries no implicit type information.
Don't crash when resolving the init message for an Objective-C object
that is being constructed in such region.

rdar://problem/32517077

Differential Revision: https://reviews.llvm.org/D33828

llvm-svn: 305211
  • Loading branch information
haoNoQ committed Jun 12, 2017
1 parent 30a49d1 commit 11150c0
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
6 changes: 6 additions & 0 deletions clang/lib/StaticAnalyzer/Core/CallEvent.cpp
Expand Up @@ -957,6 +957,12 @@ RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
return RuntimeDefinition();

DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
if (!DTI.isValid()) {
assert(isa<AllocaRegion>(Receiver) &&
"Unhandled untyped region class!");
return RuntimeDefinition();
}

QualType DynType = DTI.getType();
CanBeSubClassed = DTI.canBeASubClass();
ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
Expand Down
12 changes: 12 additions & 0 deletions clang/test/Analysis/DynamicTypePropagation.m
Expand Up @@ -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;
Expand All @@ -21,6 +24,7 @@ - (void) myFunction:(int*)p myParam:(int) n;
@end

@interface NSArray<ObjectType> : NSObject
- (void) init;
- (BOOL)contains:(ObjectType)obj;
- (ObjectType)getObjAtIndex:(NSUInteger)idx;
- (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx;
Expand Down Expand Up @@ -55,3 +59,11 @@ void testArgument(NSArray<MyType *> *arr, id element) {
// 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
}

0 comments on commit 11150c0

Please sign in to comment.