102 lines · c
1// RUN: %clang_cc1 -fsyntax-only -verify=expected-nowarn %s2// RUN: %clang_cc1 -Wpointer-arith -fsyntax-only -verify=expected-warn %s3// RUN: %clang_cc1 -fexperimental-bounds-safety -fsyntax-only -verify=expected-bounds %s4 5// expected-nowarn-no-diagnostics6// expected-bounds-no-diagnostics7 8#define NULL (void*)09#define __counted_by(f) __attribute__((counted_by(f)))10#define __counted_by_or_null(f) __attribute__((counted_by_or_null(f)))11#define __sized_by(f) __attribute__((sized_by(f)))12 13//==============================================================================14// Test: counted_by on void* is allowed (warns with -Wpointer-arith)15//==============================================================================16 17struct test_void_ptr_gnu {18 int count;19 // expected-warn-warning@+2{{'counted_by' on a pointer to void is a GNU extension, treated as 'sized_by'}}20 // expected-warn-note@+1{{use '__sized_by' to suppress this warning}}21 void* buf __counted_by(count);22};23 24struct test_const_void_ptr_gnu {25 int count;26 // expected-warn-warning@+2{{'counted_by' on a pointer to void is a GNU extension, treated as 'sized_by'}}27 // expected-warn-note@+1{{use '__sized_by' to suppress this warning}}28 const void* buf __counted_by(count);29};30 31struct test_volatile_void_ptr_gnu {32 int count;33 // expected-warn-warning@+2{{'counted_by' on a pointer to void is a GNU extension, treated as 'sized_by'}}34 // expected-warn-note@+1{{use '__sized_by' to suppress this warning}}35 volatile void* buf __counted_by(count);36};37 38struct test_const_volatile_void_ptr_gnu {39 int count;40 // expected-warn-warning@+2{{'counted_by' on a pointer to void is a GNU extension, treated as 'sized_by'}}41 // expected-warn-note@+1{{use '__sized_by' to suppress this warning}}42 const volatile void* buf __counted_by(count);43};44 45// Verify sized_by still works the same way (always allowed, no warning)46struct test_sized_by_void_ptr {47 int size;48 void* buf __sized_by(size); // OK in both modes, no warning49};50 51//==============================================================================52// Test: counted_by_or_null on void* behaves the same53//==============================================================================54 55struct test_void_ptr_or_null_gnu {56 int count;57 // expected-warn-warning@+2{{'counted_by_or_null' on a pointer to void is a GNU extension, treated as 'sized_by_or_null'}}58 // expected-warn-note@+1{{use '__sized_by_or_null' to suppress this warning}}59 void* buf __counted_by_or_null(count);60};61 62struct test_const_void_ptr_or_null_gnu {63 int count;64 // expected-warn-warning@+2{{'counted_by_or_null' on a pointer to void is a GNU extension, treated as 'sized_by_or_null'}}65 // expected-warn-note@+1{{use '__sized_by_or_null' to suppress this warning}}66 const void* buf __counted_by_or_null(count);67};68 69//==============================================================================70// Test: Using void* __counted_by(...) pointers (not just declaring them)71//==============================================================================72 73// Verify that void* __counted_by pointers can be used as rvalues, assigned to,74// passed to functions, etc.75 76void* use_as_rvalue(struct test_void_ptr_gnu* t) {77 return t->buf;78}79 80void assign_to_pointer(struct test_void_ptr_gnu* t) {81 t->buf = NULL;82 t->count = 0;83}84 85extern void* my_allocator(unsigned long);86 87void assign_from_allocator(struct test_void_ptr_gnu* t) {88 t->buf = my_allocator(100);89 t->count = 100;90}91 92void takes_void_ptr(void* p);93 94void pass_to_function(struct test_void_ptr_gnu* t) {95 takes_void_ptr(t->buf);96}97 98void* pointer_arithmetic(struct test_void_ptr_gnu* t) {99 // expected-warn-warning@+1{{arithmetic on a pointer to void is a GNU extension}}100 return t->buf + 10;101}102