forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			196 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
| // RUN: %clang_analyze_cc1 -analyzer-checker=core -w -verify %s
 | |
| 
 | |
| @interface MyObject
 | |
| - (void)takePointer:(void *)ptr __attribute__((nonnull(1)));
 | |
| - (void)takePointerArg:(void *)__attribute__((nonnull)) ptr;
 | |
| 
 | |
| @end
 | |
| 
 | |
| void testNonNullMethod(int *p, MyObject *obj) {
 | |
|   if (p)
 | |
|     return;
 | |
|   [obj takePointer:p]; // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| 
 | |
| @interface Subclass : MyObject
 | |
| // [[nonnull]] is an inherited attribute.
 | |
| - (void)takePointer:(void *)ptr;
 | |
| @end
 | |
| 
 | |
| void testSubclass(int *p, Subclass *obj) {
 | |
|   if (p)
 | |
|     return;
 | |
|   [obj takePointer:p]; // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testSubclassArg(int *p, Subclass *obj) {
 | |
|   if (p)
 | |
|     return;
 | |
|   [obj takePointerArg:p]; // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| 
 | |
| union rdar16153464_const_cp_t {
 | |
|   const struct rdar16153464_cczp *zp;
 | |
|   const struct rdar16153464_cczp_prime *prime;
 | |
| } __attribute__((transparent_union));
 | |
| 
 | |
| struct rdar16153464_header {
 | |
|   union rdar16153464_const_cp_t cp;
 | |
|   unsigned char pad[16 - sizeof(union rdar16153464_const_cp_t *)];
 | |
| } __attribute__((aligned(16)));
 | |
| 
 | |
| 
 | |
| struct rdar16153464_full_ctx {
 | |
|   struct rdar16153464_header hdr;
 | |
| } __attribute__((aligned(16)));
 | |
| 
 | |
| 
 | |
| struct rdar16153464_pub_ctx {
 | |
|   struct rdar16153464_header hdr;
 | |
| } __attribute__((aligned(16)));
 | |
| 
 | |
| 
 | |
| union rdar16153464_full_ctx_t {
 | |
|   struct rdar16153464_full_ctx *_full;
 | |
|   struct rdar16153464_header *hdr;
 | |
|   struct rdar16153464_body *body;
 | |
|   struct rdar16153464_public *pub;
 | |
| } __attribute__((transparent_union));
 | |
| 
 | |
| union rdar16153464_pub_ctx_t {
 | |
|   struct rdar16153464_pub_ctx *_pub;
 | |
|   struct rdar16153464_full_ctx *_full;
 | |
|   struct rdar16153464_header *hdr;
 | |
|   struct rdar16153464_body *body;
 | |
|   struct rdar16153464_public *pub;
 | |
|   union rdar16153464_full_ctx_t innert;
 | |
| } __attribute__((transparent_union));
 | |
| 
 | |
| int rdar16153464(union rdar16153464_full_ctx_t inner)
 | |
| {
 | |
|   extern void rdar16153464_check(union rdar16153464_pub_ctx_t outer) __attribute((nonnull(1)));
 | |
|   rdar16153464_check((union rdar16153464_pub_ctx_t){ .innert = inner }); // no-warning
 | |
|   rdar16153464_check(inner); // no-warning
 | |
|   rdar16153464_check(0); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| // Multiple attributes, the basic case
 | |
| void multipleAttributes_1(char *p, char *q) __attribute((nonnull(1))) __attribute((nonnull(2)));
 | |
| 
 | |
| void testMultiple_1(void) {
 | |
|   char c;
 | |
|   multipleAttributes_1(&c, &c); // no-warning
 | |
| }
 | |
| 
 | |
| void testMultiple_2(void) {
 | |
|   char c;
 | |
|   multipleAttributes_1(0, &c); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testMultiple_3(void) {
 | |
|   char c;
 | |
|   multipleAttributes_1(&c, 0); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testMultiple_4(void) {
 | |
|   multipleAttributes_1(0, 0);// expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| // Multiple attributes, multiple prototypes
 | |
| void multipleAttributes_2(char *p, char *q) __attribute((nonnull(1)));
 | |
| void multipleAttributes_2(char *p, char *q) __attribute((nonnull(2)));
 | |
| 
 | |
| void testMultiple_5(void) {
 | |
|   char c;
 | |
|   multipleAttributes_2(0, &c);// expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testMultiple_6(void) {
 | |
|   char c;
 | |
|   multipleAttributes_2(&c, 0);// expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testMultiple_7(void) {
 | |
|   multipleAttributes_2(0, 0);// expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| // Multiple attributes, same index
 | |
| void multipleAttributes_3(char *p, char *q) __attribute((nonnull(1))) __attribute((nonnull(1)));
 | |
| 
 | |
| void testMultiple_8(void) {
 | |
|   char c;
 | |
|   multipleAttributes_3(0, &c); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testMultiple_9(void) {
 | |
|   char c;
 | |
|   multipleAttributes_3(&c, 0); // no-warning
 | |
| }
 | |
| 
 | |
| // Multiple attributes, the middle argument is missing an attribute
 | |
| void multipleAttributes_4(char *p, char *q, char *r) __attribute((nonnull(1))) __attribute((nonnull(3)));
 | |
| 
 | |
| void testMultiple_10(void) {
 | |
|   char c;
 | |
|   multipleAttributes_4(0, &c, &c); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testMultiple_11(void) {
 | |
|   char c;
 | |
|   multipleAttributes_4(&c, 0, &c); // no-warning
 | |
| }
 | |
| 
 | |
| void testMultiple_12(void) {
 | |
|   char c;
 | |
|   multipleAttributes_4(&c, &c, 0); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| 
 | |
| // Multiple attributes, when the last is without index
 | |
| void multipleAttributes_all_1(char *p, char *q) __attribute((nonnull(1))) __attribute((nonnull));
 | |
| 
 | |
| void testMultiple_13(void) {
 | |
|   char c;
 | |
|   multipleAttributes_all_1(0, &c); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testMultiple_14(void) {
 | |
|   char c;
 | |
|   multipleAttributes_all_1(&c, 0); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| // Multiple attributes, when the first is without index
 | |
| void multipleAttributes_all_2(char *p, char *q) __attribute((nonnull)) __attribute((nonnull(2)));
 | |
| 
 | |
| void testMultiple_15(void) {
 | |
|   char c;
 | |
|   multipleAttributes_all_2(0, &c); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testMultiple_16(void) {
 | |
|   char c;
 | |
|   multipleAttributes_all_2(&c, 0); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testVararg(int k, void *p) {
 | |
|   extern void testVararg_check(int, ...) __attribute__((nonnull));
 | |
|   void *n = 0;
 | |
|   testVararg_check(0);
 | |
|   testVararg_check(1, p);
 | |
|   if (k == 1)
 | |
|     testVararg_check(1, n); // expected-warning{{nonnull}}
 | |
|   testVararg_check(2, p, p);
 | |
|   if (k == 2)
 | |
|     testVararg_check(2, n, p); // expected-warning{{nonnull}}
 | |
|   if (k == 3)
 | |
|     testVararg_check(2, p, n); // expected-warning{{nonnull}}
 | |
| }
 | |
| 
 | |
| void testNotPtr() {
 | |
|   struct S { int a; int b; int c; } s = {};
 | |
|   extern void testNotPtr_check(struct S, int) __attribute__((nonnull(1, 2)));
 | |
|   testNotPtr_check(s, 0);
 | |
| }
 |