| 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
| 2 | |
| 3 | template<int z> |
| 4 | int test9(int *a) { |
| 5 | a = (int *) __builtin_assume_aligned(a, z + 1); // expected-error {{requested alignment is not a power of 2}} |
| 6 | return a[0]; |
| 7 | } |
| 8 | |
| 9 | void test9i(int *a) { |
| 10 | test9<42>(a); // expected-note {{in instantiation of function template specialization 'test9<42>' requested here}} |
| 11 | } |
| 12 | |
| 13 | template<typename T> |
| 14 | int test10(int *a, T z) { |
| 15 | a = (int *) __builtin_assume_aligned(a, z + 1); // expected-error {{must be a constant integer}} |
| 16 | return a[0]; |
| 17 | } |
| 18 | |
| 19 | int test10i(int *a) { |
| 20 | return test10(a, 42); // expected-note {{in instantiation of function template specialization 'test10<int>' requested here}} |
| 21 | } |
| 22 | |
| 23 | template <int q> |
| 24 | void *atest() __attribute__((assume_aligned(q))); // expected-error {{requested alignment is not a power of 2}} |
| 25 | |
| 26 | template <int q, int o> |
| 27 | void *atest2() __attribute__((assume_aligned(q, o))); // expected-error {{requested alignment is not a power of 2}} |
| 28 | |
| 29 | void test20() { |
| 30 | atest<31>(); // expected-note {{in instantiation of function template specialization 'atest<31>' requested here}} |
| 31 | atest<32>(); |
| 32 | |
| 33 | atest2<31, 5>(); // expected-note {{in instantiation of function template specialization 'atest2<31, 5>' requested here}} |
| 34 | atest2<32, 4>(); |
| 35 | } |
| 36 | |
| 37 | // expected-error@+1 {{invalid application of 'sizeof' to a function type}} |
| 38 | template<typename T> __attribute__((assume_aligned(sizeof(int(T()))))) T *f(); |
| 39 | void test21() { |
| 40 | void *p = f<void>(); // expected-note {{in instantiation of function template specialization 'f<void>' requested here}} |
| 41 | } |
| 42 | |
| 43 | // expected-error@+1 {{functional-style cast from 'void' to 'int' is not allowed}} |
| 44 | template<typename T> __attribute__((assume_aligned(sizeof((int(T())))))) T *g(); |
| 45 | void test23() { |
| 46 | void *p = g<void>(); // expected-note {{in instantiation of function template specialization 'g<void>' requested here}} |
| 47 | } |
| 48 | |
| 49 | template <typename T, int o> |
| 50 | T *atest3() __attribute__((assume_aligned(31, o))); // expected-error {{requested alignment is not a power of 2}} |
| 51 | |
| 52 | template <typename T, int o> |
| 53 | T *atest4() __attribute__((assume_aligned(32, o))); |
| 54 | |
| 55 | void test22() { |
| 56 | atest3<int, 5>(); |
| 57 | atest4<int, 5>(); |
| 58 | } |
| 59 | |
| 60 | // expected-warning@+1 {{'assume_aligned' attribute only applies to Objective-C methods and functions}} |
| 61 | class __attribute__((assume_aligned(32))) x { |
| 62 | int y; |
| 63 | }; |
| 64 | |
| 65 | // expected-warning@+1 {{'assume_aligned' attribute only applies to return values that are pointers or references}} |
| 66 | x foo() __attribute__((assume_aligned(32))); |
| 67 | |
| 68 | struct s1 { |
| 69 | static const int x = 32; |
| 70 | }; |
| 71 | |
| 72 | struct s2 { |
| 73 | static const int x = 64; |
| 74 | }; |
| 75 | |
| 76 | struct s3 { |
| 77 | static const int x = 63; |
| 78 | }; |
| 79 | |
| 80 | template <typename X> |
| 81 | void *atest5() __attribute__((assume_aligned(X::x))); // expected-error {{requested alignment is not a power of 2}} |
| 82 | void test24() { |
| 83 | atest5<s1>(); |
| 84 | atest5<s2>(); |
| 85 | atest5<s3>(); // expected-note {{in instantiation of function template specialization 'atest5<s3>' requested here}} |
| 86 | } |
| 87 | |
| 88 | |