forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			198 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
			
		
		
	
	
			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
 |