Skip to content

Commit ee552f3

Browse files
[Cherry-pick][Wunsafe-buffer-usage] Turn off unsafe-buffer warning for methods annotated with clang::unsafe_buffer_usage attribute (llvm#125671)
[Cherry-pick][Wunsafe-buffer-usage] Turn off unsafe-buffer warning for methods annotated with clang::unsafe_buffer_usage attribute (llvm#125671)
2 parents 73714d9 + a7302b4 commit ee552f3

File tree

3 files changed

+75
-6
lines changed

3 files changed

+75
-6
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,9 @@ Removed Compiler Flags
561561

562562
Attribute Changes in Clang
563563
--------------------------
564+
- Adding [[clang::unsafe_buffer_usage]] attribute to a method definition now turns off all -Wunsafe-buffer-usage
565+
related warnings within the method body.
566+
564567
- Introduced a new function attribute ``__attribute__((amdgpu_max_num_work_groups(x, y, z)))`` or
565568
``[[clang::amdgpu_max_num_work_groups(x, y, z)]]`` for the AMDGPU target. This attribute can be
566569
attached to HIP or OpenCL kernel function definitions to provide an optimization hint. The parameters

clang/lib/Sema/AnalysisBasedWarnings.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,6 +3185,9 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
31853185

31863186
// The Callback function that performs analyses:
31873187
auto CallAnalyzers = [&](const Decl *Node) -> void {
3188+
if (Node->hasAttr<UnsafeBufferUsageAttr>())
3189+
return;
3190+
31883191
// Perform unsafe buffer usage analysis:
31893192
if (!Diags.isIgnored(diag::warn_unsafe_buffer_operation,
31903193
Node->getBeginLoc()) ||

clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,15 @@ struct HoldsUnsafeMembers {
119119

120120
[[clang::unsafe_buffer_usage]]
121121
HoldsUnsafeMembers(int i)
122-
: FromCtor(i), // expected-warning{{function introduces unsafe buffer manipulation}}
123-
FromCtor2{i} // expected-warning{{function introduces unsafe buffer manipulation}}
124-
{}
122+
: FromCtor(i),
123+
FromCtor2{i} {}
125124

126125
HoldsUnsafeMembers(float f)
127126
: HoldsUnsafeMembers(0) {} // expected-warning{{function introduces unsafe buffer manipulation}}
128127

129128
UnsafeMembers FromCtor;
130129
UnsafeMembers FromCtor2;
131-
UnsafeMembers FromField{3}; // expected-warning 2{{function introduces unsafe buffer manipulation}}
130+
UnsafeMembers FromField{3}; // expected-warning {{function introduces unsafe buffer manipulation}}
132131
};
133132

134133
struct SubclassUnsafeMembers : public UnsafeMembers {
@@ -138,8 +137,7 @@ struct SubclassUnsafeMembers : public UnsafeMembers {
138137

139138
[[clang::unsafe_buffer_usage]]
140139
SubclassUnsafeMembers(int i)
141-
: UnsafeMembers(i) // expected-warning{{function introduces unsafe buffer manipulation}}
142-
{}
140+
: UnsafeMembers(i){}
143141
};
144142

145143
// https://github.com/llvm/llvm-project/issues/80482
@@ -245,3 +243,68 @@ struct AggregateViaDefaultInit {
245243
void testAggregateViaDefaultInit() {
246244
AggregateViaDefaultInit A;
247245
};
246+
247+
struct A {
248+
int arr[2];
249+
250+
[[clang::unsafe_buffer_usage]]
251+
int *ptr;
252+
};
253+
254+
namespace std{
255+
template <typename T> class span {
256+
257+
T *elements;
258+
259+
public:
260+
261+
constexpr span(T *, unsigned){}
262+
263+
template<class Begin, class End>
264+
constexpr span(Begin first, End last){}
265+
266+
constexpr T* data() const noexcept {
267+
return elements;
268+
}
269+
};
270+
}
271+
272+
[[clang::unsafe_buffer_usage]]
273+
void check_no_warnings(unsigned idx) {
274+
int *arr = new int[20];
275+
276+
int k = arr[idx]; // no-warning
277+
278+
std::span<int> sp = {arr, 20}; // no-warning
279+
A *ptr = reinterpret_cast<A*> (sp.data()); // no-warning
280+
A a;
281+
a.ptr = arr; // no-warning
282+
}
283+
284+
[[clang::unsafe_buffer_usage]]
285+
void check_no_warning_variadic(unsigned idx, int arr[20], ...) {
286+
int k = arr[idx]; // no-warning
287+
288+
std::span<int> sp = {arr, 20}; // no-warning
289+
A *ptr = reinterpret_cast<A*> (sp.data()); // no-warning
290+
A a;
291+
a.ptr = arr; // no-warning
292+
}
293+
294+
template<typename T>
295+
[[clang::unsafe_buffer_usage]]
296+
void check_no_warnings_template(unsigned idx, T* arr) {
297+
int k = arr[idx]; // no-warning
298+
299+
std::span<int> sp = {arr, 20}; // no-warning
300+
A *ptr = reinterpret_cast<A*> (sp.data()); // no-warning
301+
A a;
302+
a.ptr = arr; // no-warning
303+
}
304+
305+
void invoke_methods() {
306+
int array[20];
307+
check_no_warnings(30); //expected-warning{{function introduces unsafe buffer manipulation}}
308+
check_no_warning_variadic(15, array); //expected-warning{{function introduces unsafe buffer manipulation}}
309+
check_no_warnings_template(10, array); //expected-warning{{function introduces unsafe buffer manipulation}}
310+
}

0 commit comments

Comments
 (0)