[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / Sema / builtin-counted-by-ref.c
blob5a7ecefcb789767aacbcc939bb1e868dd342a869
1 // RUN: %clang_cc1 -std=c99 -fsyntax-only -verify %s
3 typedef unsigned long int size_t;
5 int global_array[42];
6 int global_int;
8 struct fam_struct {
9 int x;
10 char count;
11 int array[] __attribute__((counted_by(count)));
14 void test1(struct fam_struct *ptr, int size, int idx) {
15 size_t size_of = sizeof(__builtin_counted_by_ref(ptr->array)); // ok
17 *__builtin_counted_by_ref(ptr->array) = size; // ok
20 size_t __ignored_assignment;
21 *_Generic(__builtin_counted_by_ref(ptr->array),
22 void *: &__ignored_assignment,
23 default: __builtin_counted_by_ref(ptr->array)) = 42; // ok
27 void test2(struct fam_struct *ptr, int idx) {
28 __builtin_counted_by_ref(); // expected-error {{too few arguments to function call, expected 1, have 0}}
29 __builtin_counted_by_ref(ptr->array, ptr->x, ptr->count); // expected-error {{too many arguments to function call, expected 1, have 3}}
32 void test3(struct fam_struct *ptr, int idx) {
33 __builtin_counted_by_ref(&ptr->array[0]); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
34 __builtin_counted_by_ref(&ptr->array[idx]); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
35 __builtin_counted_by_ref(&ptr->array); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
36 __builtin_counted_by_ref(ptr->x); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
37 __builtin_counted_by_ref(&ptr->x); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
38 __builtin_counted_by_ref(global_array); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
39 __builtin_counted_by_ref(global_int); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
40 __builtin_counted_by_ref(&global_int); // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
43 void test4(struct fam_struct *ptr, int idx) {
44 __builtin_counted_by_ref(ptr++->array); // expected-error {{'__builtin_counted_by_ref' argument cannot have side-effects}}
45 __builtin_counted_by_ref(&ptr->array[idx++]); // expected-error {{'__builtin_counted_by_ref' argument cannot have side-effects}}
48 void foo(char *);
50 void *test5(struct fam_struct *ptr, int size, int idx) {
51 char *ref = __builtin_counted_by_ref(ptr->array); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}}
53 ref = __builtin_counted_by_ref(ptr->array); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}}
54 ref = (char *)(int *)(42 + &*__builtin_counted_by_ref(ptr->array)); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}}
55 foo(__builtin_counted_by_ref(ptr->array)); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}}
56 foo(ref = __builtin_counted_by_ref(ptr->array)); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}}
58 if ((ref = __builtin_counted_by_ref(ptr->array))) // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}}
61 for (char *p = __builtin_counted_by_ref(ptr->array); p && *p; ++p) // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}}
64 return __builtin_counted_by_ref(ptr->array); // expected-error {{value returned by '__builtin_counted_by_ref' cannot be assigned to a variable, have its address taken, or passed into or returned from a function}}
67 void test6(struct fam_struct *ptr, int size, int idx) {
68 *(__builtin_counted_by_ref(ptr->array) + 4) = 37; // expected-error {{value returned by '__builtin_counted_by_ref' cannot be used in a binary expression}}
69 __builtin_counted_by_ref(ptr->array)[3] = 37; // expected-error {{value returned by '__builtin_counted_by_ref' cannot be used in an array subscript expression}}
72 struct non_fam_struct {
73 char x;
74 long *pointer;
75 int array[42];
76 short count;
79 void *test7(struct non_fam_struct *ptr, int size) {
80 *__builtin_counted_by_ref(ptr->array) = size // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
81 *__builtin_counted_by_ref(&ptr->array[0]) = size; // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
82 *__builtin_counted_by_ref(ptr->pointer) = size; // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
83 *__builtin_counted_by_ref(&ptr->pointer[0]) = size; // expected-error {{'__builtin_counted_by_ref' argument must reference a flexible array member}}
86 struct char_count {
87 char count;
88 int array[] __attribute__((counted_by(count)));
89 } *cp;
91 struct short_count {
92 short count;
93 int array[] __attribute__((counted_by(count)));
94 } *sp;
96 struct int_count {
97 int count;
98 int array[] __attribute__((counted_by(count)));
99 } *ip;
101 struct unsigned_count {
102 unsigned count;
103 int array[] __attribute__((counted_by(count)));
104 } *up;
106 struct long_count {
107 long count;
108 int array[] __attribute__((counted_by(count)));
109 } *lp;
111 struct unsigned_long_count {
112 unsigned long count;
113 int array[] __attribute__((counted_by(count)));
114 } *ulp;
116 void test8(void) {
117 _Static_assert(_Generic(__builtin_counted_by_ref(cp->array), char * : 1, default : 0) == 1, "wrong return type");
118 _Static_assert(_Generic(__builtin_counted_by_ref(sp->array), short * : 1, default : 0) == 1, "wrong return type");
119 _Static_assert(_Generic(__builtin_counted_by_ref(ip->array), int * : 1, default : 0) == 1, "wrong return type");
120 _Static_assert(_Generic(__builtin_counted_by_ref(up->array), unsigned int * : 1, default : 0) == 1, "wrong return type");
121 _Static_assert(_Generic(__builtin_counted_by_ref(lp->array), long * : 1, default : 0) == 1, "wrong return type");
122 _Static_assert(_Generic(__builtin_counted_by_ref(ulp->array), unsigned long * : 1, default : 0) == 1, "wrong return type");