Skip to content

Commit ff063ea

Browse files
committed
add case for __counted_by__, __counted_by_or_null__
Also adds a test case checking the source ranges and fix-its.
1 parent aef6bc4 commit ff063ea

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed

clang/lib/Sema/SemaBoundsSafety.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,10 @@ static void EmitIncompleteCountedByPointeeNotes(Sema &S,
340340
llvm::StringSwitch<StringRef>(Spelling)
341341
.Case("__counted_by", "__sized_by")
342342
.Case("counted_by", "sized_by")
343+
.Case("__counted_by__", "__sized_by__")
343344
.Case("__counted_by_or_null", "__sized_by_or_null")
344345
.Case("counted_by_or_null", "sized_by_or_null")
346+
.Case("__counted_by_or_null__", "__sized_by_or_null__")
345347
.Default("");
346348
FixItHint Fix;
347349
if (!FixedSpelling.empty())
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info -fdiagnostics-parseable-fixits %s 2>%t.txt
2+
// RUN: FileCheck %s --implicit-check-not error --implicit-check-not note --implicit-check-not fix --implicit-check-not warning < %t.txt
3+
4+
#define __counted_by(f) __attribute__((counted_by(f)))
5+
6+
struct IncompleteTy;
7+
typedef struct IncompleteTy Incomplete_t;
8+
9+
struct Container__cb {
10+
int count;
11+
struct IncompleteTy* buf __counted_by(count);
12+
Incomplete_t* buf_typedef __counted_by(count);
13+
};
14+
15+
void consume_struct_IncompleteTy(struct IncompleteTy* buf);
16+
int idx(void);
17+
18+
void test_Container__cb(struct Container__cb* ptr) {
19+
struct Container__cb uninit;
20+
uninit.count = 0;
21+
22+
uninit.buf = 0x0;
23+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:14:{[[@LINE-1]]:16-[[@LINE-1]]:19}: error: cannot assign to 'Container__cb::buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
24+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
25+
// CHECK: bounds-safety-source-ranges.c:11:28:{11:28-11:40}: note: consider using '__sized_by' instead of '__counted_by'
26+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{11:28-11:40}:"__sized_by"
27+
28+
struct IncompleteTy* addr_elt_zero_ptr = &ptr->buf[0];
29+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:45:{[[@LINE-1]]:45-[[@LINE-1]]:53}: error: cannot use 'ptr->buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
30+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
31+
// CHECK: bounds-safety-source-ranges.c:11:28:{11:28-11:40}: note: consider using '__sized_by' instead of '__counted_by'
32+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{11:28-11:40}:"__sized_by"
33+
34+
struct IncompleteTy* addr_elt_idx_ptr = &ptr->buf[idx()];
35+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:44:{[[@LINE-1]]:44-[[@LINE-1]]:52}: error: cannot use 'ptr->buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
36+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
37+
// CHECK: bounds-safety-source-ranges.c:11:28:{11:28-11:40}: note: consider using '__sized_by' instead of '__counted_by'
38+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{11:28-11:40}:"__sized_by"
39+
40+
consume_struct_IncompleteTy(uninit.buf);
41+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:31:{[[@LINE-1]]:31-[[@LINE-1]]:41}: error: cannot use 'uninit.buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
42+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
43+
// CHECK: bounds-safety-source-ranges.c:11:28:{11:28-11:40}: note: consider using '__sized_by' instead of '__counted_by'
44+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{11:28-11:40}:"__sized_by"
45+
46+
consume_struct_IncompleteTy(ptr->buf);
47+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:31:{[[@LINE-1]]:31-[[@LINE-1]]:39}: error: cannot use 'ptr->buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
48+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
49+
// CHECK: bounds-safety-source-ranges.c:11:28:{11:28-11:40}: note: consider using '__sized_by' instead of '__counted_by'
50+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{11:28-11:40}:"__sized_by"
51+
52+
uninit.buf[0] = uninit.buf[1];
53+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:3:{[[@LINE-1]]:3-[[@LINE-1]]:13}: error: cannot use 'uninit.buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
54+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
55+
// CHECK: bounds-safety-source-ranges.c:11:28:{11:28-11:40}: note: consider using '__sized_by' instead of '__counted_by'
56+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{11:28-11:40}:"__sized_by"
57+
58+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-6]]:19:{[[@LINE-6]]:19-[[@LINE-6]]:29}: error: cannot use 'uninit.buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
59+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
60+
// CHECK: bounds-safety-source-ranges.c:11:28:{11:28-11:40}: note: consider using '__sized_by' instead of '__counted_by'
61+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{11:28-11:40}:"__sized_by"
62+
63+
ptr->buf[0] = ptr->buf[1];
64+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:3:{[[@LINE-1]]:3-[[@LINE-1]]:11}: error: cannot use 'ptr->buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
65+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
66+
// CHECK: bounds-safety-source-ranges.c:11:28:{11:28-11:40}: note: consider using '__sized_by' instead of '__counted_by'
67+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{11:28-11:40}:"__sized_by"
68+
69+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-6]]:17:{[[@LINE-6]]:17-[[@LINE-6]]:25}: error: cannot use 'ptr->buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
70+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
71+
// CHECK: bounds-safety-source-ranges.c:11:28:{11:28-11:40}: note: consider using '__sized_by' instead of '__counted_by'
72+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{11:28-11:40}:"__sized_by"
73+
}
74+
75+
76+
struct Container__cb___nomacro {
77+
int count;
78+
struct IncompleteTy* buf __attribute__((__counted_by__(count)));
79+
};
80+
81+
void test_Container__cb___nomacro(struct Container__cb___nomacro* ptr) {
82+
struct Container__cb___nomacro local;
83+
local.count = 0;
84+
local.buf = 0x0;
85+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:13:{[[@LINE-1]]:15-[[@LINE-1]]:18}: error: cannot assign to 'Container__cb___nomacro::buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
86+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
87+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-9]]:43:{[[@LINE-9]]:43-[[@LINE-9]]:57}: note: consider using '__sized_by' instead of '__counted_by'
88+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{[[@LINE-10]]:43-[[@LINE-10]]:57}:"__sized_by__"
89+
}
90+
91+
92+
struct Containercb_nomacro {
93+
int count;
94+
struct IncompleteTy* buf __attribute__((counted_by(count)));
95+
};
96+
97+
void test_Containercb_nomacro(struct Containercb_nomacro* ptr) {
98+
struct Containercb_nomacro local;
99+
local.count = 0;
100+
local.buf = 0x0;
101+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:13:{[[@LINE-1]]:15-[[@LINE-1]]:18}: error: cannot assign to 'Containercb_nomacro::buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
102+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
103+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-9]]:43:{[[@LINE-9]]:43-[[@LINE-9]]:53}: note: consider using '__sized_by' instead of '__counted_by'
104+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{[[@LINE-10]]:43-[[@LINE-10]]:53}:"sized_by"
105+
}
106+
107+
108+
#define aaaaaaaa(x) __attribute__((counted_by(x)))
109+
struct Container_aaaaaaaa {
110+
int count;
111+
struct IncompleteTy* buf aaaaaaaa(count);
112+
};
113+
114+
void test_Container_aaaaaaaa(struct Container_aaaaaaaa* ptr) {
115+
struct Container_aaaaaaaa local;
116+
local.count = 0;
117+
local.buf = 0x0;
118+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:13:{[[@LINE-1]]:15-[[@LINE-1]]:18}: error: cannot assign to 'Container_aaaaaaaa::buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
119+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
120+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-9]]:28:{[[@LINE-9]]:28-[[@LINE-9]]:36}: note: consider using '__sized_by' instead of '__counted_by'
121+
// no fix-it
122+
}
123+
124+
125+
struct Container_macro1 {
126+
int count;
127+
struct IncompleteTy* buf __attribute__((counted_by(count)));
128+
};
129+
130+
#define A() \
131+
void test_Contain_macro1(struct Container_macro1* ptr) { \
132+
struct Container_macro1 local; \
133+
local.count = 0; \
134+
local.buf = 0x0; \
135+
}
136+
137+
A()
138+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:1:{[[@LINE-1]]:1-[[@LINE-1]]:4}: error: cannot assign to 'Container_macro1::buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
139+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-5]]:13:{[[@LINE-5]]:15-[[@LINE-5]]:18}: note: expanded from macro 'A'
140+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
141+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-14]]:43:{[[@LINE-14]]:43-[[@LINE-14]]:53}: note: consider using '__sized_by' instead of '__counted_by'
142+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{[[@LINE-15]]:43-[[@LINE-15]]:53}:"sized_by"
143+
144+
145+
#define B() \
146+
struct Container_macro2 { \
147+
int count; \
148+
struct IncompleteTy* buf __attribute__((counted_by(count))); \
149+
};
150+
B()
151+
152+
void test_Contain_macro2(struct Container_macro2* ptr) {
153+
struct Container_macro2 local;
154+
local.count = 0;
155+
local.buf = 0x0;
156+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:13:{[[@LINE-1]]:15-[[@LINE-1]]:18}: error: cannot assign to 'Container_macro2::buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
157+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
158+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-8]]:1:{[[@LINE-8]]:1-[[@LINE-8]]:2}: note: consider using '__sized_by' instead of '__counted_by'
159+
// no fix-it
160+
}
161+
162+
163+
#define counted_by(x) __attribute__((counted_by(x)))
164+
165+
struct Containercb {
166+
int count;
167+
struct IncompleteTy* buf counted_by(count);
168+
};
169+
170+
void test_Containercb(struct Containercb* ptr) {
171+
struct Containercb local;
172+
local.count = 0;
173+
local.buf = 0x0;
174+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:13:{[[@LINE-1]]:15-[[@LINE-1]]:18}: error: cannot assign to 'Containercb::buf' with '__counted_by' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
175+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
176+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-9]]:28:{[[@LINE-9]]:28-[[@LINE-9]]:38}: note: consider using '__sized_by' instead of '__counted_by'
177+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{[[@LINE-10]]:28-[[@LINE-10]]:38}:"sized_by"
178+
}
179+
180+
181+
struct Containercbon {
182+
int count;
183+
struct IncompleteTy* buf __attribute__((counted_by_or_null(count)));
184+
};
185+
186+
void test_Containercbon(struct Containercbon* ptr) {
187+
struct Containercbon local;
188+
local.count = 0;
189+
local.buf = 0x0;
190+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-1]]:13:{[[@LINE-1]]:15-[[@LINE-1]]:18}: error: cannot assign to 'Containercbon::buf' with '__counted_by_or_null' {{.*}} because the pointee type 'struct IncompleteTy' is incomplete
191+
// CHECK: bounds-safety-source-ranges.c:6:1: note: consider providing a complete definition for 'struct IncompleteTy'
192+
// CHECK: bounds-safety-source-ranges.c:[[@LINE-9]]:43:{[[@LINE-9]]:43-[[@LINE-9]]:61}: note: consider using '__sized_by_or_null' instead of '__counted_by_or_null'
193+
// CHECK: fix-it:"{{.*}}bounds-safety-source-ranges.c":{[[@LINE-10]]:43-[[@LINE-10]]:61}:"sized_by_or_null"
194+
}
195+
196+
// prevent 'error' from being unmatched
197+
// CHECK: errors generated

0 commit comments

Comments
 (0)