brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · bf9a892 Raw
134 lines · c
1// RUN: %clang_cc1 -triple x86_64-linux-gnu -DALIGN_BUILTIN=__builtin_align_down -DRETURNS_BOOL=0 %s -fsyntax-only -verify -Wpedantic2// RUN: %clang_cc1 -triple x86_64-linux-gnu -DALIGN_BUILTIN=__builtin_align_up   -DRETURNS_BOOL=0 %s -fsyntax-only -verify -Wpedantic3// RUN: %clang_cc1 -triple x86_64-linux-gnu -DALIGN_BUILTIN=__builtin_is_aligned -DRETURNS_BOOL=1 %s -fsyntax-only -verify -Wpedantic4 5struct Aggregate {6  int i;7  int j;8};9enum Enum { EnumValue1,10            EnumValue2 };11typedef __SIZE_TYPE__ size_t;12 13void test_parameter_types(char *ptr, size_t size) {14  struct Aggregate agg;15  enum Enum e = EnumValue2;16  _Bool b = 0;17 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 fine26  (void)ALIGN_BUILTIN((int)b, 2); // but with a cast it is fine27 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 fine35  (void)ALIGN_BUILTIN(ptr, (int)b); // but with a cast booleans are fine36 37  (void)ALIGN_BUILTIN(ptr, size);38  (void)ALIGN_BUILTIN(size, size);39}40 41void 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 here48}49 50#define check_same_type(type1, type2) __builtin_types_compatible_p(type1, type2) && __builtin_types_compatible_p(type1 *, type2 *)51 52void test_return_type(void *ptr, int i, long l) {53  char array[32];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;58#if RETURNS_BOOL59  _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");63#else64  _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");70#endif71}72 73void test_invalid_alignment_values(char *ptr, long *longptr, size_t align) {74  int x = 1;75  (void)ALIGN_BUILTIN(ptr, 2);76  (void)ALIGN_BUILTIN(longptr, 1024);77  (void)ALIGN_BUILTIN(x, 32);78 79  (void)ALIGN_BUILTIN(ptr, 0); // expected-error {{requested alignment must be 1 or greater}}80  (void)ALIGN_BUILTIN(ptr, 1);81#if RETURNS_BOOL82  // expected-warning@-2 {{checking whether a value is aligned to 1 byte is always true}}83#else84  // expected-warning@-4 {{aligning a value to 1 byte is a no-op}}85#endif86  (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}}88 89  // check the maximum range for smaller types:90  __UINT8_TYPE__ c = ' ';91 92  (void)ALIGN_BUILTIN(c, 128);        // this is fine93  (void)ALIGN_BUILTIN(c, 256);        // expected-error {{requested alignment must be 128 or smaller}}94  (void)ALIGN_BUILTIN(x, 1ULL << 31); // this is also fine95  (void)ALIGN_BUILTIN(x, 1LL << 31);  // this is also fine96  __INT32_TYPE__ i32 = 3;97  __UINT32_TYPE__ u32 = 3;98  // Maximum is the same for int32 and uint3299  (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}}103 104  const int bad_align = 8 + 1;105  (void)ALIGN_BUILTIN(ptr, bad_align); // expected-error {{requested alignment is not a power of 2}}106}107 108// Check that it can be used in constant expressions:109void 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, "");114 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}}118}119 120// Check that it is a constant expression that can be assigned to globals:121int global1 = __builtin_align_down(33, 8);122int global2 = __builtin_align_up(33, 8);123_Bool global3 = __builtin_is_aligned(33, 8);124 125extern void test_ptr(char *c);126char *test_array_and_fnptr(void) {127  char buf[1024];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}}133}134