1 // RUN: %clang_cc1 -std=c99 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -x c++ -std=c++98 -fsyntax-only -verify %s
3 // RUN: %clang_cc1 -std=c99 -fno-signed-char -fsyntax-only -verify %s
7 typedef struct A
*MPI_Datatype
;
9 int wrong1(void *buf
, MPI_Datatype datatype
)
10 __attribute__(( pointer_with_type_tag
)); // expected-error {{'pointer_with_type_tag' attribute requires exactly 3 arguments}}
12 int wrong2(void *buf
, MPI_Datatype datatype
)
13 __attribute__(( pointer_with_type_tag(mpi
,0,7) )); // expected-error {{attribute parameter 2 is out of bounds}}
15 int wrong3(void *buf
, MPI_Datatype datatype
)
16 __attribute__(( pointer_with_type_tag(mpi
,3,7) )); // expected-error {{attribute parameter 2 is out of bounds}}
18 int wrong4(void *buf
, MPI_Datatype datatype
)
19 __attribute__(( pointer_with_type_tag(mpi
,1,0) )); // expected-error {{attribute parameter 3 is out of bounds}}
21 int wrong5(void *buf
, MPI_Datatype datatype
)
22 __attribute__(( pointer_with_type_tag(mpi
,1,3) )); // expected-error {{attribute parameter 3 is out of bounds}}
24 int wrong6(void *buf
, MPI_Datatype datatype
)
25 __attribute__(( pointer_with_type_tag(mpi
,0x8000000000000001ULL
,1) )); // expected-error {{attribute parameter 2 is out of bounds}}
29 int wrong7(void *buf
, MPI_Datatype datatype
)
30 __attribute__(( pointer_with_type_tag(mpi
,x
,2) )); // expected-error {{attribute requires parameter 2 to be an integer constant}}
32 int wrong8(void *buf
, MPI_Datatype datatype
)
33 __attribute__(( pointer_with_type_tag(mpi
,1,x
) )); // expected-error {{attribute requires parameter 3 to be an integer constant}}
35 int wrong9
__attribute__(( pointer_with_type_tag(mpi
,1,2) )); // expected-error {{'pointer_with_type_tag' attribute only applies to non-K&R-style functions}}
37 int wrong10(double buf
, MPI_Datatype type
)
38 __attribute__(( pointer_with_type_tag(mpi
,1,2) )); // expected-error {{'pointer_with_type_tag' attribute only applies to pointer arguments}}
41 __attribute__(( pointer_with_type_tag(mpi
,1,2) ));
42 int wrong11(void *, ...)
43 __attribute__(( pointer_with_type_tag(mpi
,2,3) )); // expected-error {{'pointer_with_type_tag' attribute only applies to pointer arguments}}
45 extern struct A datatype_wrong1
46 __attribute__(( type_tag_for_datatype
)); // expected-error {{'type_tag_for_datatype' attribute requires parameter 1 to be an identifier}}
48 extern struct A datatype_wrong2
49 __attribute__(( type_tag_for_datatype(mpi
,1,2) )); // expected-error {{expected a type}}
51 extern struct A datatype_wrong3
52 __attribute__(( type_tag_for_datatype(mpi
,not_a_type
) )); // expected-error {{unknown type name 'not_a_type'}}
54 extern struct A datatype_wrong4
55 __attribute__(( type_tag_for_datatype(mpi
,int,int) )); // expected-error {{expected identifier}}
57 extern struct A datatype_wrong5
58 __attribute__(( type_tag_for_datatype(mpi
,int,not_a_flag
) )); // expected-error {{invalid comparison flag 'not_a_flag'}}
60 extern struct A datatype_wrong6
61 __attribute__(( type_tag_for_datatype(mpi
,int,layout_compatible
,not_a_flag
) )); // expected-error {{invalid comparison flag 'not_a_flag'}}
64 void datatype_wrong7(void) __attribute__((type_tag_for_datatype(datatype_wrong7
, int))); // expected-error {{'type_tag_for_datatype' attribute only applies to variables}}
66 // Using a tag with kind A in a place where the function requires kind B should
69 void A_func(void *ptr
, void *tag
) __attribute__(( pointer_with_type_tag(a
,1,2) ));
71 extern struct A A_tag
__attribute__(( type_tag_for_datatype(a
,int) ));
72 extern struct A B_tag
__attribute__(( type_tag_for_datatype(b
,int) ));
74 void C_func(void *ptr
, int tag
) __attribute__(( pointer_with_type_tag(c
,1,2) ));
76 static const int C_tag
__attribute__(( type_tag_for_datatype(c
,int) )) = 10;
77 static const int D_tag
__attribute__(( type_tag_for_datatype(d
,int) )) = 20;
79 void test_tag_mismatch(int *ptr
)
81 A_func(ptr
, &A_tag
); // no-warning
82 A_func(ptr
, &B_tag
); // expected-warning {{this type tag was not designed to be used with this function}}
83 C_func(ptr
, C_tag
); // no-warning
84 C_func(ptr
, D_tag
); // expected-warning {{this type tag was not designed to be used with this function}}
85 C_func(ptr
, 10); // no-warning
86 C_func(ptr
, 20); // should warn, but may cause false positives
89 void test_null_pointer(void)
91 C_func(0, C_tag
); // no-warning
92 C_func((void *) 0, C_tag
); // no-warning
93 C_func((int *) 0, C_tag
); // no-warning
94 C_func((long *) 0, C_tag
); // expected-warning {{argument type 'long *' doesn't match specified 'c' type tag that requires 'int *'}}
97 // Check that we look through typedefs in the special case of allowing 'char'
98 // to be matched with 'signed char' or 'unsigned char'.
99 void E_func(void *ptr
, int tag
) __attribute__(( pointer_with_type_tag(e
,1,2) ));
102 typedef char E_char_2
;
103 typedef signed char E_char_signed
;
104 typedef unsigned char E_char_unsigned
;
106 static const int E_tag
__attribute__(( type_tag_for_datatype(e
,E_char
) )) = 10;
108 void test_char_typedef(char *char_buf
,
109 E_char_2
*e_char_buf
,
110 E_char_signed
*e_char_signed_buf
,
111 E_char_unsigned
*e_char_unsigned_buf
)
113 E_func(char_buf
, E_tag
);
114 E_func(e_char_buf
, E_tag
);
115 #ifdef __CHAR_UNSIGNED__
116 E_func(e_char_signed_buf
, E_tag
); // expected-warning {{argument type 'E_char_signed *' (aka 'signed char *') doesn't match specified 'e' type tag that requires 'E_char *' (aka 'char *')}}
117 E_func(e_char_unsigned_buf
, E_tag
);
119 E_func(e_char_signed_buf
, E_tag
);
120 E_func(e_char_unsigned_buf
, E_tag
); // expected-warning {{argument type 'E_char_unsigned *' (aka 'unsigned char *') doesn't match specified 'e' type tag that requires 'E_char *' (aka 'char *')}}
124 // Tests for argument_with_type_tag.
131 static const int F_DUPFD_tag
__attribute__(( type_tag_for_datatype(fcntl
,int) )) = F_DUPFD
;
132 static const int F_SETLK_tag
__attribute__(( type_tag_for_datatype(fcntl
,struct flock
*) )) = F_SETLK
;
134 int fcntl(int fd
, int cmd
, ...) __attribute__(( argument_with_type_tag(fcntl
,3,2) ));
136 void test_argument_with_type_tag(struct flock
*f
)
138 fcntl(0, F_DUPFD
, 10); // no-warning
139 fcntl(0, F_SETLK
, f
); // no-warning
141 fcntl(0, F_SETLK
, 10); // expected-warning {{argument type 'int' doesn't match specified 'fcntl' type tag that requires 'struct flock *'}}
142 fcntl(0, F_DUPFD
, f
); // expected-warning {{argument type 'struct flock *' doesn't match specified 'fcntl' type tag that requires 'int'}}
145 void test_tag_expresssion(int b
) {
146 fcntl(0, b
? F_DUPFD
: F_SETLK
, 10); // no-warning
147 fcntl(0, b
+ F_DUPFD
, 10); // no-warning
148 fcntl(0, (b
, F_DUPFD
), 10); // expected-warning {{left operand of comma operator has no effect}}
151 // Check that using 64-bit magic values as tags works and tag values do not
152 // overflow internally.
153 void F_func(void *ptr
, unsigned long long tag
) __attribute__((pointer_with_type_tag(f
,1,2) ));
155 static const unsigned long long F_tag1
__attribute__(( type_tag_for_datatype(f
,int) )) = 0xFFFFFFFFFFFFFFFFULL
;
156 static const unsigned long long F_tag2
__attribute__(( type_tag_for_datatype(f
,float) )) = 0xFFFFFFFFULL
;
158 void test_64bit_magic(int *int_ptr
, float *float_ptr
)
160 F_func(int_ptr
, 0xFFFFFFFFFFFFFFFFULL
);
161 F_func(int_ptr
, 0xFFFFFFFFULL
); // expected-warning {{argument type 'int *' doesn't match specified 'f' type tag that requires 'float *'}}
162 F_func(float_ptr
, 0xFFFFFFFFFFFFFFFFULL
); // expected-warning {{argument type 'float *' doesn't match specified 'f' type tag that requires 'int *'}}
163 F_func(float_ptr
, 0xFFFFFFFFULL
);