1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
3 #include "InlineObjCInstanceMethod.h"
5 void clang_analyzer_eval(int);
7 PublicSubClass2 *getObj(void);
9 @implementation PublicParent
10 - (int)getZeroOverridden {
18 @implementation PublicSubClass2
19 - (int)getZeroOverridden {
23 /* Test that we get the right type from call to alloc. */
24 + (void)testAllocSelf {
26 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}}
29 + (void)testAllocClass {
30 id a = [PublicSubClass2 alloc];
31 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}}
34 + (void)testAllocSuperOverriden {
36 // Evaluates to 1 in the parent.
37 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{FALSE}}
40 + (void)testAllocSuper {
42 clang_analyzer_eval([a getZero] == 0); // expected-warning{{TRUE}}
45 + (void)testAllocInit {
46 id a = [[self alloc] init];
47 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}}
52 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}}
55 // Casting to parent should not pessimize the dynamic type.
56 + (void)testCastToParent {
57 id a = [[self alloc] init];
59 clang_analyzer_eval([p getZeroOverridden] == 0); // expected-warning{{TRUE}}
62 // The type of parameter gets used.
63 + (void)testTypeFromParam:(PublicParent *)p {
64 clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}}
67 // Test implicit cast.
68 // Note, in this case, p could also be a subclass of MyParent.
69 + (void)testCastFromId:(id)a {
71 clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}}
75 // TODO: Would be nice to handle the case of dynamically obtained class info
76 // as well. We need a MemRegion for class types for this.
77 int testDynamicClass(BOOL coin) {
78 Class AllocClass = (coin ? [NSObject class] : [PublicSubClass2 class]);
79 id x = [[AllocClass alloc] init];
85 @interface UserClass : NSObject
86 - (PublicSubClass2 *)_newPublicSubClass2;
91 @implementation UserClass
92 - (PublicSubClass2 *)_newPublicSubClass2 {
93 return [[PublicSubClass2 alloc] init];
99 PublicSubClass2 *x = [self _newPublicSubClass2];
100 clang_analyzer_eval([x getZero] == 0); //expected-warning{{TRUE}}