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