1 // RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -fsyntax-only -verify
2 // RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -x c++ -fsyntax-only -verify
3 #include <stddef.h>
4 #include <arm_acle.h>
5
create_tag1(int a,unsigned b)6 int *create_tag1(int a, unsigned b) {
7 // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
8 return __arm_mte_create_random_tag(a,b);
9 }
10
create_tag2(int * a,unsigned * b)11 int *create_tag2(int *a, unsigned *b) {
12 // expected-error@+1 {{second argument of MTE builtin function must be an integer type ('unsigned int *' invalid)}}
13 return __arm_mte_create_random_tag(a,b);
14 }
15
create_tag3(const int * a,unsigned b)16 int *create_tag3(const int *a, unsigned b) {
17 #ifdef __cplusplus
18 // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
19 return __arm_mte_create_random_tag(a,b);
20 #else
21 // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
22 return __arm_mte_create_random_tag(a,b);
23 #endif
24 }
25
create_tag4(volatile int * a,unsigned b)26 int *create_tag4(volatile int *a, unsigned b) {
27 #ifdef __cplusplus
28 // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'volatile int *'}}
29 return __arm_mte_create_random_tag(a,b);
30 #else
31 // expected-warning@+1 {{returning 'volatile int *' from a function with result type 'int *' discards qualifiers}}
32 return __arm_mte_create_random_tag(a,b);
33 #endif
34 }
35
increment_tag1(int * a,unsigned b)36 int *increment_tag1(int *a, unsigned b) {
37 // expected-error@+1 {{argument to '__builtin_arm_addg' must be a constant integer}}
38 return __arm_mte_increment_tag(a,b);
39 }
40
increment_tag2(int * a)41 int *increment_tag2(int *a) {
42 // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}}
43 return __arm_mte_increment_tag(a,16);
44 }
45
increment_tag3(int * a)46 int *increment_tag3(int *a) {
47 // expected-error@+1 {{argument value -1 is outside the valid range [0, 15]}}
48 return __arm_mte_increment_tag(a,-1);
49 }
50
increment_tag4(const int * a)51 int *increment_tag4(const int *a) {
52 #ifdef __cplusplus
53 // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
54 return __arm_mte_increment_tag(a,5);
55 #else
56 // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
57 return __arm_mte_increment_tag(a,5);
58 #endif
59 }
60
increment_tag5(const volatile int * a)61 int *increment_tag5(const volatile int *a) {
62 #ifdef __cplusplus
63 // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const volatile int *'}}
64 return __arm_mte_increment_tag(a,5);
65 #else
66 // expected-warning@+1 {{returning 'const volatile int *' from a function with result type 'int *' discards qualifiers}}
67 return __arm_mte_increment_tag(a,5);
68 #endif
69 }
70
exclude_tag1(int * ptr,unsigned m)71 unsigned exclude_tag1(int *ptr, unsigned m) {
72 // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
73 return __arm_mte_exclude_tag(*ptr, m);
74 }
75
exclude_tag2(int * ptr,int * m)76 unsigned exclude_tag2(int *ptr, int *m) {
77 // expected-error@+1 {{second argument of MTE builtin function must be an integer type ('int *' invalid)}}
78 return __arm_mte_exclude_tag(ptr, m);
79 }
80
get_tag1()81 void get_tag1() {
82 // expected-error@+1 {{too few arguments to function call, expected 1, have 0}}
83 __arm_mte_get_tag();
84 }
85
get_tag2(int ptr)86 int *get_tag2(int ptr) {
87 // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
88 return __arm_mte_get_tag(ptr);
89 }
90
get_tag3(const volatile int * ptr)91 int *get_tag3(const volatile int *ptr) {
92 #ifdef __cplusplus
93 // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const volatile int *'}}
94 return __arm_mte_get_tag(ptr);
95 #else
96 // expected-warning@+1 {{returning 'const volatile int *' from a function with result type 'int *' discards qualifiers}}
97 return __arm_mte_get_tag(ptr);
98 #endif
99 }
100
set_tag1()101 void set_tag1() {
102 // expected-error@+1 {{too few arguments to function call, expected 1, have 0}}
103 __arm_mte_set_tag();
104 }
105
set_tag2(int ptr)106 void set_tag2(int ptr) {
107 // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
108 __arm_mte_set_tag(ptr);
109 }
110
subtract_pointers1(int a,int * b)111 ptrdiff_t subtract_pointers1(int a, int *b) {
112 // expected-error@+1 {{first argument of MTE builtin function must be a null or a pointer ('int' invalid)}}
113 return __arm_mte_ptrdiff(a, b);
114 }
115
subtract_pointers2(int * a,int b)116 ptrdiff_t subtract_pointers2(int *a, int b) {
117 // expected-error@+1 {{second argument of MTE builtin function must be a null or a pointer ('int' invalid)}}
118 return __arm_mte_ptrdiff(a, b);
119 }
120
subtract_pointers3(char * a,int * b)121 ptrdiff_t subtract_pointers3(char *a, int *b) {
122 // expected-error@+1 {{'char *' and 'int *' are not pointers to compatible types}}
123 return __arm_mte_ptrdiff(a, b);
124 }
125
subtract_pointers4(int * a,char * b)126 ptrdiff_t subtract_pointers4(int *a, char *b) {
127 // expected-error@+1 {{'int *' and 'char *' are not pointers to compatible types}}
128 return __arm_mte_ptrdiff(a, b);
129 }
130
131 #ifdef __cplusplus
subtract_pointers5()132 ptrdiff_t subtract_pointers5() {
133 // expected-error@+1 {{at least one argument of MTE builtin function must be a pointer ('nullptr_t', 'nullptr_t' invalid)}}
134 return __arm_mte_ptrdiff(nullptr, nullptr);
135 }
136 #endif
137