1 /* PR c/88383 - ICE calling _builtin_has_attribute(r, aligned(N))) 2 on an overaligned reference r 3 PR c/89288 - ICE in tree_code_size, at tree.c:865 4 { dg-options "-Wall -ftrack-macro-expansion=0" } 5 { dg-options "-Wall -Wno-narrowing -Wno-unused -ftrack-macro-expansion=0" { target c++ } } */ 6 7 #define ATTR(...) __attribute__ ((__VA_ARGS__)) 8 9 #define A(expect, sym, attr) \ 10 typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)] 11 12 typedef ATTR (aligned (8)) int Int8; 13 14 /* The attribute applies to the array, not to the type of its elements. */ 15 extern ATTR (aligned (8)) char i8arr[]; 16 17 /* The attribute applies to the pointer, not to the type it points to. */ 18 extern ATTR (aligned (8)) int *ptr; 19 extern Int8 *i8ptr; 20 21 #if __cplusplus 22 23 /* Similarly here, the attribute applies to the reference, not to its type. */ 24 extern ATTR (aligned (8)) int &ref; 25 extern Int8 &i8ref; 26 27 #else 28 29 /* Fake references in C. */ 30 extern ATTR (aligned (8)) int ref; 31 Int8 i8ref; 32 33 #endif 34 35 void test (void) 36 { 37 /* Verify that the built-in detects the attribute on the array. */ 38 A (1, i8arr, aligned); 39 A (0, i8arr, aligned (1)); 40 A (0, i8arr, aligned (2)); 41 A (0, i8arr, aligned (4)); 42 A (1, i8arr, aligned (8)); 43 A (0, i8arr, aligned (16)); 44 45 A (0, i8arr + 1, aligned); 46 A (0, i8arr + 2, aligned (1)); 47 A (0, i8arr + 3, aligned (8)); 48 49 /* Verify the builtin detects the absence of the attribute on 50 the elements. */ 51 A (0, i8arr[0], aligned); 52 A (0, *i8arr, aligned); 53 54 /* Verify that the built-in doesn't confuse the attribute on 55 the pointer type with that to the pointed to type. This 56 also exercises PR c/89288. */ 57 A (0, (Int8*)0, aligned); 58 A (0, (int*)0, aligned); 59 A (0, (void*)0, aligned); 60 A (0, 0, aligned); 61 62 /* Verify that the built-in detects the attribute on the pointer 63 itself. */ 64 A (1, ptr, aligned); 65 A (0, ptr, aligned (1)); 66 A (0, ptr, aligned (2)); 67 A (0, ptr, aligned (4)); 68 A (1, ptr, aligned (8)); 69 A (0, ptr, aligned (16)); 70 71 A (0, ptr + 1, aligned); 72 A (0, ptr + 2, aligned (1)); 73 A (0, ptr + 3, aligned (8)); 74 75 /* The pointed to type is not declared with attribute aligned. */ 76 A (0, *ptr, aligned); 77 A (0, *ptr, aligned (1)); 78 A (0, *ptr, aligned (2)); 79 A (0, *ptr, aligned (4)); 80 A (0, *ptr, aligned (8)); 81 A (0, *ptr, aligned (16)); 82 83 A (0, *ptr + 1, aligned); 84 A (0, *ptr + 2, aligned (1)); 85 A (0, *ptr + 3, aligned (8)); 86 87 /* Verify that the built-in correctly detects the attribute on 88 the type of the lvalue referenced by the pointer. */ 89 A (0, i8ptr, aligned); 90 A (0, i8ptr, aligned (8)); 91 A (0, i8ptr + 1, aligned); 92 A (0, i8ptr + 3, aligned (8)); 93 A (1, *i8ptr, aligned); 94 A (0, *i8ptr, aligned (1)); 95 A (0, *i8ptr, aligned (2)); 96 A (0, *i8ptr, aligned (4)); 97 A (1, *i8ptr, aligned (8)); 98 A (0, *i8ptr, aligned (16)); 99 100 /* The reference itself is declared aligned, even though the type 101 it refers to isn't. But see PR c++/88362. */ 102 A (1, ref, aligned); 103 A (0, ref, aligned (1)); 104 A (0, ref, aligned (2)); 105 A (0, ref, aligned (4)); 106 A (1, ref, aligned (8)); 107 A (0, ref, aligned (16)); 108 109 /* Also verify that assignment expressions are accepted. */ 110 A (0, ref = 1, aligned); 111 A (0, ref += 2, aligned (1)); 112 A (0, ref /= 3, aligned (8)); 113 114 } 115