Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ Removed Compiler Flags

Attribute Changes in Clang
--------------------------
Adding [[clang::unsafe_buffer_usage]] attribute to a method definition now turns off all -Wunsafe-buffer-usage
related warnings within the method body.

Improvements to Clang's diagnostics
-----------------------------------
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/AnalysisBasedWarnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2610,6 +2610,9 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(

// The Callback function that performs analyses:
auto CallAnalyzers = [&](const Decl *Node) -> void {
if (Node->hasAttr<UnsafeBufferUsageAttr>())
return;

// Perform unsafe buffer usage analysis:
if (!Diags.isIgnored(diag::warn_unsafe_buffer_operation,
Node->getBeginLoc()) ||
Expand Down
63 changes: 57 additions & 6 deletions clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,15 @@ struct HoldsUnsafeMembers {

[[clang::unsafe_buffer_usage]]
HoldsUnsafeMembers(int i)
: FromCtor(i), // expected-warning{{function introduces unsafe buffer manipulation}}
FromCtor2{i} // expected-warning{{function introduces unsafe buffer manipulation}}
{}
: FromCtor(i),
FromCtor2{i} {}

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

UnsafeMembers FromCtor;
UnsafeMembers FromCtor2;
UnsafeMembers FromField{3}; // expected-warning 2{{function introduces unsafe buffer manipulation}}
UnsafeMembers FromField{3}; // expected-warning {{function introduces unsafe buffer manipulation}}
};

struct SubclassUnsafeMembers : public UnsafeMembers {
Expand All @@ -138,8 +137,7 @@ struct SubclassUnsafeMembers : public UnsafeMembers {

[[clang::unsafe_buffer_usage]]
SubclassUnsafeMembers(int i)
: UnsafeMembers(i) // expected-warning{{function introduces unsafe buffer manipulation}}
{}
: UnsafeMembers(i){}
};

// https://github.com/llvm/llvm-project/issues/80482
Expand Down Expand Up @@ -245,3 +243,56 @@ struct AggregateViaDefaultInit {
void testAggregateViaDefaultInit() {
AggregateViaDefaultInit A;
};

struct A {
int arr[2];

[[clang::unsafe_buffer_usage]]
int *ptr;
};

namespace std{
template <typename T> class span {

T *elements;

public:

constexpr span(T *, unsigned){}

template<class Begin, class End>
constexpr span(Begin first, End last){}

constexpr T* data() const noexcept {
return elements;
}
};
}

[[clang::unsafe_buffer_usage]]
void check_no_warnings(unsigned idx) {
int *arr = new int[20];

int k = arr[idx]; // no-warning

std::span<int> sp = {arr, 20}; // no-warning
A *ptr = reinterpret_cast<A*> (sp.data()); // no-warning
A a;
a.ptr = arr; // no-warning
}

[[clang::unsafe_buffer_usage]]
void check_no_warning_variadic(unsigned idx, int arr[20], ...) {
int k = arr[idx]; // no-warning

std::span<int> sp = {arr, 20}; // no-warning
A *ptr = reinterpret_cast<A*> (sp.data()); // no-warning
A a;
a.ptr = arr; // no-warning
}

void invoke_methods() {
int array[20];
check_no_warnings(30); //expected-warning{{function introduces unsafe buffer manipulation}}
check_no_warning_variadic(20, array); //expected-warning{{function introduces unsafe buffer manipulation}}
}