@@ -6802,77 +6802,103 @@ def UnsafeBufferUsageDocs : Documentation {
6802
6802
let Category = DocCatFunction;
6803
6803
let Content = [{
6804
6804
The attribute ``[[clang::unsafe_buffer_usage]]`` should be placed on functions
6805
- that need to be avoided as they are prone to buffer overflows. It is designed to
6806
- work together with the off-by-default compiler warning ``-Wunsafe-buffer-usage``
6807
- to help codebases transition away from raw pointer based buffer management,
6808
- in favor of safer abstractions such as C++20 ``std::span``. The attribute causes
6809
- ``-Wunsafe-buffer-usage`` to warn on every use of the function, and it may
6810
- enable ``-Wunsafe-buffer-usage`` to emit automatic fix-it hints
6811
- which would help the user replace such unsafe functions with safe
6805
+ that need to be avoided as they are prone to buffer overflows or unsafe buffer
6806
+ struct fields. It is designed to work together with the off-by-default compiler
6807
+ warning ``-Wunsafe-buffer-usage`` to help codebases transition away from raw pointer
6808
+ based buffer management, in favor of safer abstractions such as C++20 ``std::span``.
6809
+ The attribute causes ``-Wunsafe-buffer-usage`` to warn on every use of the function or
6810
+ the field it is attached to, and it may also lead to emission of automatic fix-it
6811
+ hints which would help the user replace the use of unsafe functions(/fields) with safe
6812
6812
alternatives, though the attribute can be used even when the fix can't be automated.
6813
6813
6814
- The attribute does not suppress ``-Wunsafe-buffer-usage`` inside the function
6815
- to which it is attached. These warnings still need to be addressed.
6814
+ * Attribute attached to functions: The attribute does not suppress
6815
+ ``-Wunsafe-buffer-usage`` inside the function to which it is attached.
6816
+ These warnings still need to be addressed.
6816
6817
6817
- The attribute is warranted even if the only way a function can overflow
6818
- the buffer is by violating the function's preconditions. For example, it
6819
- would make sense to put the attribute on function ``foo()`` below because
6820
- passing an incorrect size parameter would cause a buffer overflow:
6818
+ The attribute is warranted even if the only way a function can overflow
6819
+ the buffer is by violating the function's preconditions. For example, it
6820
+ would make sense to put the attribute on function ``foo()`` below because
6821
+ passing an incorrect size parameter would cause a buffer overflow:
6821
6822
6822
- .. code-block:: c++
6823
+ .. code-block:: c++
6823
6824
6824
- [[clang::unsafe_buffer_usage]]
6825
- void foo(int *buf, size_t size) {
6826
- for (size_t i = 0; i < size; ++i) {
6827
- buf[i] = i;
6825
+ [[clang::unsafe_buffer_usage]]
6826
+ void foo(int *buf, size_t size) {
6827
+ for (size_t i = 0; i < size; ++i) {
6828
+ buf[i] = i;
6829
+ }
6828
6830
}
6829
- }
6830
6831
6831
- The attribute is NOT warranted when the function uses safe abstractions,
6832
- assuming that these abstractions weren't misused outside the function.
6833
- For example, function ``bar()`` below doesn't need the attribute,
6834
- because assuming that the container ``buf`` is well-formed (has size that
6835
- fits the original buffer it refers to), overflow cannot occur:
6832
+ The attribute is NOT warranted when the function uses safe abstractions,
6833
+ assuming that these abstractions weren't misused outside the function.
6834
+ For example, function ``bar()`` below doesn't need the attribute,
6835
+ because assuming that the container ``buf`` is well-formed (has size that
6836
+ fits the original buffer it refers to), overflow cannot occur:
6836
6837
6837
- .. code-block:: c++
6838
+ .. code-block:: c++
6838
6839
6839
- void bar(std::span<int> buf) {
6840
- for (size_t i = 0; i < buf.size(); ++i) {
6841
- buf[i] = i;
6840
+ void bar(std::span<int> buf) {
6841
+ for (size_t i = 0; i < buf.size(); ++i) {
6842
+ buf[i] = i;
6843
+ }
6842
6844
}
6843
- }
6844
6845
6845
- In this case function ``bar()`` enables the user to keep the buffer
6846
- "containerized" in a span for as long as possible. On the other hand,
6847
- Function ``foo()`` in the previous example may have internal
6848
- consistency, but by accepting a raw buffer it requires the user to unwrap
6849
- their span, which is undesirable according to the programming model
6850
- behind ``-Wunsafe-buffer-usage``.
6846
+ In this case function ``bar()`` enables the user to keep the buffer
6847
+ "containerized" in a span for as long as possible. On the other hand,
6848
+ Function ``foo()`` in the previous example may have internal
6849
+ consistency, but by accepting a raw buffer it requires the user to unwrap
6850
+ their span, which is undesirable according to the programming model
6851
+ behind ``-Wunsafe-buffer-usage``.
6851
6852
6852
- The attribute is warranted when a function accepts a raw buffer only to
6853
- immediately put it into a span:
6853
+ The attribute is warranted when a function accepts a raw buffer only to
6854
+ immediately put it into a span:
6854
6855
6855
- .. code-block:: c++
6856
+ .. code-block:: c++
6856
6857
6857
- [[clang::unsafe_buffer_usage]]
6858
- void baz(int *buf, size_t size) {
6859
- std::span<int> sp{ buf, size };
6860
- for (size_t i = 0; i < sp.size(); ++i) {
6861
- sp[i] = i;
6858
+ [[clang::unsafe_buffer_usage]]
6859
+ void baz(int *buf, size_t size) {
6860
+ std::span<int> sp{ buf, size };
6861
+ for (size_t i = 0; i < sp.size(); ++i) {
6862
+ sp[i] = i;
6863
+ }
6862
6864
}
6863
- }
6864
6865
6865
- In this case ``baz()`` does not contain any unsafe operations, but the awkward
6866
- parameter type causes the caller to unwrap the span unnecessarily.
6867
- Note that regardless of the attribute, code inside ``baz()`` isn't flagged
6868
- by ``-Wunsafe-buffer-usage`` as unsafe. It is definitely undesirable,
6869
- but if ``baz()`` is on an API surface, there is no way to improve it
6870
- to make it as safe as ``bar()`` without breaking the source and binary
6871
- compatibility with existing users of the function. In such cases
6872
- the proper solution would be to create a different function (possibly
6873
- an overload of ``baz()``) that accepts a safe container like ``bar()``,
6874
- and then use the attribute on the original ``baz()`` to help the users
6875
- update their code to use the new function.
6866
+ In this case ``baz()`` does not contain any unsafe operations, but the awkward
6867
+ parameter type causes the caller to unwrap the span unnecessarily.
6868
+ Note that regardless of the attribute, code inside ``baz()`` isn't flagged
6869
+ by ``-Wunsafe-buffer-usage`` as unsafe. It is definitely undesirable,
6870
+ but if ``baz()`` is on an API surface, there is no way to improve it
6871
+ to make it as safe as ``bar()`` without breaking the source and binary
6872
+ compatibility with existing users of the function. In such cases
6873
+ the proper solution would be to create a different function (possibly
6874
+ an overload of ``baz()``) that accepts a safe container like ``bar()``,
6875
+ and then use the attribute on the original ``baz()`` to help the users
6876
+ update their code to use the new function.
6877
+
6878
+ * Attribute attached to fields: The attribute should only be attached to
6879
+ struct fields, if the fields can not be updated to a safe type with bounds
6880
+ check, such as std::span. In other words, the buffers prone to unsafe accesses
6881
+ should always be updated to use safe containers/views and attaching the attribute
6882
+ must be last resort when such an update is infeasible.
6883
+
6884
+ The attribute can be placed on individual fields or a set of them as shown below.
6885
+
6886
+ .. code-block:: c++
6887
+
6888
+ struct A {
6889
+ [[clang::unsafe_buffer_usage]]
6890
+ int *ptr1;
6891
+
6892
+ [[clang::unsafe_buffer_usage]]
6893
+ int *ptr2, buf[10];
6894
+
6895
+ [[clang::unsafe_buffer_usage]]
6896
+ size_t sz;
6897
+ };
6898
+
6899
+ Here, every read/write to the fields ptr1, ptr2, buf and sz will trigger a warning
6900
+ that the field has been explcitly marked as unsafe due to unsafe-buffer operations.
6901
+
6876
6902
}];
6877
6903
}
6878
6904
0 commit comments