llvm-project/clang/test/Analysis/trustnonnullchecker_test.m

198 lines
5.1 KiB
Objective-C

// Temporarily disabling the test, it failes the "system is over-constrained"
// assertion in *non* optimized builds.
// REQUIRES: rdar44992170
// RUN: %clang_analyze_cc1 -fblocks -analyze -analyzer-checker=core,nullability,apiModeling,debug.ExprInspection -verify %s
#include "Inputs/system-header-simulator-for-nullability.h"
void clang_analyzer_warnIfReached();
NSString* _Nonnull trust_nonnull_framework_annotation() {
NSString* out = [NSString generateString];
if (out) {}
return out; // no-warning
}
NSString* _Nonnull trust_instancemsg_annotation(NSString* _Nonnull param) {
NSString* out = [param stringByAppendingString:@"string"];
if (out) {}
return out; // no-warning
}
NSString* _Nonnull distrust_instancemsg_noannotation(NSString* param) {
if (param) {}
NSString* out = [param stringByAppendingString:@"string"];
if (out) {}
return out; // expected-warning{{}}
}
NSString* _Nonnull trust_analyzer_knowledge(NSString* param) {
if (!param)
return @"";
NSString* out = [param stringByAppendingString:@"string"];
if (out) {}
return out; // no-warning
}
NSString* _Nonnull trust_assume_nonnull_macro() {
NSString* out = [NSString generateImplicitlyNonnullString];
if (out) {}
return out; // no-warning
}
NSString* _Nonnull distrust_without_annotation() {
NSString* out = [NSString generatePossiblyNullString];
if (out) {}
return out; // expected-warning{{}}
}
NSString* _Nonnull nonnull_please_trust_me();
NSString* _Nonnull distrust_local_nonnull_annotation() {
NSString* out = nonnull_please_trust_me();
if (out) {}
return out; // expected-warning{{}}
}
NSString* _Nonnull trust_c_function() {
NSString* out = getString();
if (out) {};
return out; // no-warning
}
NSString* _Nonnull distrust_unannoted_function() {
NSString* out = getPossiblyNullString();
if (out) {};
return out; // expected-warning{{}}
}
NSString * _Nonnull distrustProtocol(id<MyProtocol> o) {
NSString* out = [o getString];
if (out) {};
return out; // expected-warning{{}}
}
// If the return value is non-nil, the index is non-nil.
NSString *_Nonnull retImpliesIndex(NSString *s,
NSDictionary *dic) {
id obj = dic[s];
if (s) {}
if (obj)
return s; // no-warning
return @"foo";
}
NSString *_Nonnull retImpliesIndexOtherMethod(NSString *s,
NSDictionary *dic) {
id obj = [dic objectForKey:s];
if (s) {}
if (obj)
return s; // no-warning
return @"foo";
}
NSString *_Nonnull retImpliesIndexOnRHS(NSString *s,
NSDictionary *dic) {
id obj = dic[s];
if (s) {}
if (nil != obj)
return s; // no-warning
return @"foo";
}
NSString *_Nonnull retImpliesIndexReverseCheck(NSString *s,
NSDictionary *dic) {
id obj = dic[s];
if (s) {}
if (!obj)
return @"foo";
return s; // no-warning
}
NSString *_Nonnull retImpliesIndexReverseCheckOnRHS(NSString *s,
NSDictionary *dic) {
id obj = dic[s];
if (s) {}
if (nil == obj)
return @"foo";
return s; // no-warning
}
NSString *_Nonnull retImpliesIndexWrongBranch(NSString *s,
NSDictionary *dic) {
id obj = dic[s];
if (s) {}
if (!obj)
return s; // expected-warning{{}}
return @"foo";
}
NSString *_Nonnull retImpliesIndexWrongBranchOnRHS(NSString *s,
NSDictionary *dic) {
id obj = dic[s];
if (s) {}
if (nil == obj)
return s; // expected-warning{{}}
return @"foo";
}
// The return value could still be nil for a non-nil index.
NSDictionary *_Nonnull indexDoesNotImplyRet(NSString *s,
NSDictionary *dic) {
id obj = dic[s];
if (obj) {}
if (s)
return obj; // expected-warning{{}}
return [[NSDictionary alloc] init];
}
// The return value could still be nil for a non-nil index.
NSDictionary *_Nonnull notIndexImpliesNotRet(NSString *s,
NSDictionary *dic) {
id obj = dic[s];
if (!s) {
if (obj != nil) {
clang_analyzer_warnIfReached(); // no-warning
}
}
return [[NSDictionary alloc] init];
}
NSString *_Nonnull checkAssumeOnMutableDictionary(NSMutableDictionary *d,
NSString *k,
NSString *val) {
d[k] = val;
if (k) {}
return k; // no-warning
}
NSString *_Nonnull checkAssumeOnMutableDictionaryOtherMethod(NSMutableDictionary *d,
NSString *k,
NSString *val) {
[d setObject:val forKey:k];
if (k) {}
return k; // no-warning
}
// Check that we don't crash when the added assumption is enough
// to make the state unfeasible.
@class DummyClass;
@interface DictionarySubclass : NSDictionary {
DummyClass *g;
DictionarySubclass *d;
}
@end
@implementation DictionarySubclass
- (id) objectForKey:(id)e {
if (e) {}
return d;
}
- (void) coder {
for (id e in g) {
id f = [self objectForKey:e];
if (f)
(void)e;
}
}
@end