1 /* PR middle-end/98166: bogus -Wmismatched-dealloc on user-defined allocator 2 and inlining 3 Verify that without inlining, both the allocator and the deallocator 4 can be declared inline without a warning and that mismatched calls are 5 detected, but that declaring them always_inline does trigger a warning. 6 { dg-do compile } 7 { dg-options "-Wall" } */ 8 9 __attribute__ ((malloc (__builtin_free))) 10 inline int* alloc_int(int n)11alloc_int (int n) 12 { 13 return (int*)__builtin_malloc (n + sizeof (int)); 14 } 15 test_nowarn_int(int n)16void test_nowarn_int (int n) 17 { 18 { 19 int *p = alloc_int (n); 20 __builtin_free (p); 21 } 22 23 { 24 int *p = alloc_int (n); 25 __builtin_free (p + 1); // { dg-warning "'__builtin_free|void __builtin_free\\(void\\*\\)' called on pointer 'p|<unknown>' with nonzero offset" } 26 } 27 } 28 29 30 inline void dealloc_long(long * p)31dealloc_long (long *p) { __builtin_free (p); } 32 33 __attribute__ ((malloc (dealloc_long))) 34 long* alloc_long (int); 35 test_nowarn_long(int n)36void test_nowarn_long (int n) 37 { 38 { 39 long *p = alloc_long (n); 40 dealloc_long (p); 41 } 42 43 { 44 long *p = alloc_long (n); 45 dealloc_long (p + 1); // { dg-warning "'dealloc_long' called on pointer 'p|<unknown>' with nonzero offset" } 46 } 47 } 48 49 50 inline __attribute__ ((always_inline)) void dealloc_float(float * p)51dealloc_float (float *p) // { dg-message "deallocation function declared here" } 52 { 53 __builtin_free (p); // { dg-warning "'__builtin_free|void __builtin_free\\(void\\*\\)' called on pointer 'p|<unknown>' with nonzero offset" } 54 } 55 56 __attribute__ ((malloc (dealloc_float))) 57 float* alloc_float (int); // { dg-warning "'malloc \\(dealloc_float\\)' attribute ignored with deallocation functions declared 'inline'" } 58 test_nowarn_float(int n)59void test_nowarn_float (int n) 60 { 61 { 62 float *p = alloc_float (n); 63 dealloc_float (p); 64 } 65 66 { 67 float *p = alloc_float (n); 68 dealloc_float (p + 2); 69 } 70 } 71