1 // RUN: %clang_cc1 -triple x86_64-linux-gnu -DALIGN_BUILTIN=__builtin_align_down -DRETURNS_BOOL=0 %s -fsyntax-only -verify -Wpedantic
2 // RUN: %clang_cc1 -triple x86_64-linux-gnu -DALIGN_BUILTIN=__builtin_align_up -DRETURNS_BOOL=0 %s -fsyntax-only -verify -Wpedantic
3 // RUN: %clang_cc1 -triple x86_64-linux-gnu -DALIGN_BUILTIN=__builtin_is_aligned -DRETURNS_BOOL=1 %s -fsyntax-only -verify -Wpedantic
9 enum Enum
{ EnumValue1
,
11 typedef __SIZE_TYPE__
size_t;
13 void test_parameter_types(char *ptr
, size_t size
) {
15 enum Enum e
= EnumValue2
;
18 // The first parameter can be any pointer or integer type:
19 (void)ALIGN_BUILTIN(ptr
, 4);
20 (void)ALIGN_BUILTIN(size
, 2);
21 (void)ALIGN_BUILTIN(12345, 2);
22 (void)ALIGN_BUILTIN(agg
, 2); // expected-error {{operand of type 'struct Aggregate' where arithmetic or pointer type is required}}
23 (void)ALIGN_BUILTIN(e
, 2); // expected-error {{operand of type 'enum Enum' where arithmetic or pointer type is required}}
24 (void)ALIGN_BUILTIN(b
, 2); // expected-error {{operand of type '_Bool' where arithmetic or pointer type is required}}
25 (void)ALIGN_BUILTIN((int)e
, 2); // but with a cast it is fine
26 (void)ALIGN_BUILTIN((int)b
, 2); // but with a cast it is fine
28 // The second parameter must be an integer type (but not enum or _Bool):
29 (void)ALIGN_BUILTIN(ptr
, size
);
30 (void)ALIGN_BUILTIN(ptr
, ptr
); // expected-error {{used type 'char *' where integer is required}}
31 (void)ALIGN_BUILTIN(ptr
, agg
); // expected-error {{used type 'struct Aggregate' where integer is required}}
32 (void)ALIGN_BUILTIN(ptr
, b
); // expected-error {{used type '_Bool' where integer is required}}
33 (void)ALIGN_BUILTIN(ptr
, e
); // expected-error {{used type 'enum Enum' where integer is required}}
34 (void)ALIGN_BUILTIN(ptr
, (int)e
); // but with a cast enums are fine
35 (void)ALIGN_BUILTIN(ptr
, (int)b
); // but with a cast booleans are fine
37 (void)ALIGN_BUILTIN(ptr
, size
);
38 (void)ALIGN_BUILTIN(size
, size
);
41 void test_result_unused(int i
, int align
) {
42 // -Wunused-result does not trigger for macros so we can't use ALIGN_BUILTIN()
43 // but need to explicitly call each function.
44 __builtin_align_up(i
, align
); // expected-warning{{ignoring return value of function declared with const attribute}}
45 __builtin_align_down(i
, align
); // expected-warning{{ignoring return value of function declared with const attribute}}
46 __builtin_is_aligned(i
, align
); // expected-warning{{ignoring return value of function declared with const attribute}}
47 ALIGN_BUILTIN(i
, align
); // no warning here
50 #define check_same_type(type1, type2) __builtin_types_compatible_p(type1, type2) && __builtin_types_compatible_p(type1 *, type2 *)
52 void test_return_type(void *ptr
, int i
, long l
) {
54 __extension__
typedef typeof(ALIGN_BUILTIN(ptr
, 4)) result_type_ptr
;
55 __extension__
typedef typeof(ALIGN_BUILTIN(i
, 4)) result_type_int
;
56 __extension__
typedef typeof(ALIGN_BUILTIN(l
, 4)) result_type_long
;
57 __extension__
typedef typeof(ALIGN_BUILTIN(array
, 4)) result_type_char_array
;
59 _Static_assert(check_same_type(_Bool
, result_type_ptr
), "Should return bool");
60 _Static_assert(check_same_type(_Bool
, result_type_int
), "Should return bool");
61 _Static_assert(check_same_type(_Bool
, result_type_long
), "Should return bool");
62 _Static_assert(check_same_type(_Bool
, result_type_char_array
), "Should return bool");
64 _Static_assert(check_same_type(void *, result_type_ptr
), "Should return void*");
65 _Static_assert(check_same_type(int, result_type_int
), "Should return int");
66 _Static_assert(check_same_type(long, result_type_long
), "Should return long");
67 // Check that we can use the alignment builtins on array types (result should decay)
68 _Static_assert(check_same_type(char *, result_type_char_array
),
69 "Using the builtins on an array should yield the decayed type");
73 void test_invalid_alignment_values(char *ptr
, long *longptr
, size_t align
) {
75 (void)ALIGN_BUILTIN(ptr
, 2);
76 (void)ALIGN_BUILTIN(longptr
, 1024);
77 (void)ALIGN_BUILTIN(x
, 32);
79 (void)ALIGN_BUILTIN(ptr
, 0); // expected-error {{requested alignment must be 1 or greater}}
80 (void)ALIGN_BUILTIN(ptr
, 1);
82 // expected-warning@-2 {{checking whether a value is aligned to 1 byte is always true}}
84 // expected-warning@-4 {{aligning a value to 1 byte is a no-op}}
86 (void)ALIGN_BUILTIN(ptr
, 3); // expected-error {{requested alignment is not a power of 2}}
87 (void)ALIGN_BUILTIN(x
, 7); // expected-error {{requested alignment is not a power of 2}}
89 // check the maximum range for smaller types:
90 __UINT8_TYPE__ c
= ' ';
92 (void)ALIGN_BUILTIN(c
, 128); // this is fine
93 (void)ALIGN_BUILTIN(c
, 256); // expected-error {{requested alignment must be 128 or smaller}}
94 (void)ALIGN_BUILTIN(x
, 1ULL << 31); // this is also fine
95 (void)ALIGN_BUILTIN(x
, 1LL << 31); // this is also fine
96 __INT32_TYPE__ i32
= 3;
97 __UINT32_TYPE__ u32
= 3;
98 // Maximum is the same for int32 and uint32
99 (void)ALIGN_BUILTIN(i32
, 1ULL << 32); // expected-error {{requested alignment must be 2147483648 or smaller}}
100 (void)ALIGN_BUILTIN(u32
, 1ULL << 32); // expected-error {{requested alignment must be 2147483648 or smaller}}
101 (void)ALIGN_BUILTIN(ptr
, ((__int128
)1) << 65); // expected-error {{requested alignment must be 9223372036854775808 or smaller}}
102 (void)ALIGN_BUILTIN(longptr
, ((__int128
)1) << 65); // expected-error {{requested alignment must be 9223372036854775808 or smaller}}
104 const int bad_align
= 8 + 1;
105 (void)ALIGN_BUILTIN(ptr
, bad_align
); // expected-error {{requested alignment is not a power of 2}}
108 // Check that it can be used in constant expressions:
109 void constant_expression(int x
) {
110 _Static_assert(__builtin_is_aligned(1024, 512), "");
111 _Static_assert(!__builtin_is_aligned(256, 512ULL), "");
112 _Static_assert(__builtin_align_up(33, 32) == 64, "");
113 _Static_assert(__builtin_align_down(33, 32) == 32, "");
115 // But not if one of the arguments isn't constant:
116 _Static_assert(ALIGN_BUILTIN(33, x
) != 100, ""); // expected-error {{static assertion expression is not an integral constant expression}}
117 _Static_assert(ALIGN_BUILTIN(x
, 4) != 100, ""); // expected-error {{static assertion expression is not an integral constant expression}}
120 // Check that it is a constant expression that can be assigned to globals:
121 int global1
= __builtin_align_down(33, 8);
122 int global2
= __builtin_align_up(33, 8);
123 _Bool global3
= __builtin_is_aligned(33, 8);
125 extern void test_ptr(char *c
);
126 char *test_array_and_fnptr(void) {
128 // The builtins should also work on arrays (decaying the return type)
129 (void)(ALIGN_BUILTIN(buf
, 16));
130 // But not on functions and function pointers:
131 (void)(ALIGN_BUILTIN(test_array_and_fnptr
, 16)); // expected-error{{operand of type 'char *(void)' where arithmetic or pointer type is required}}
132 (void)(ALIGN_BUILTIN(&test_array_and_fnptr
, 16)); // expected-error{{operand of type 'char *(*)(void)' where arithmetic or pointer type is required}}