Open
Description
Given a file range0.cc:
int lookup(int *ptr, unsigned idx) {
return ptr[idx];
}
int* predecrement(int* ptr) {
return --ptr; // not actually useful, only for example
}
range0.cc:3:10:{3:10-3:13}: warning: unsafe buffer access [-Wunsafe-buffer-usage]
3 | return ptr[idx];
| ^~~
range0.cc:3:10: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
range0.cc:7:12:{7:12-7:15}: warning: unsafe pointer arithmetic [-Wunsafe-buffer-usage]
7 | return --ptr; // not actually useful, only for example
| ^~~
The returned range indicates only the unsafe operand rather than the range of the unsafe operation.
We seek to automate applying the _Pragma("clang unsafe_buffer_usage begin") / _Pragma("clang unsafe_buffer_usage end") form of suppression around the ranges as exactly indicated by the compiler,
and using some macro trickery, i.e.
#define UNSAFE_BUFFERS(...) \
_Pragma("clang unsafe_buffer_usage begin") \
__VA_ARGS__ \
_Pragma("clang unsafe_buffer_usage end")
int lookup(int *ptr, unsigned idx) {
return UNSAFE_BUFFERS(ptr)[idx];
}
int* predecrement2(int* ptr) {
return --UNSAFE_BUFFERS(ptr); // not actually useful, only for example
}
The ptr[idx] looks unusual but does suppress the error. The --ptr case, however gives
range1.cc:12:27: warning: unsafe pointer arithmetic [-Wunsafe-buffer-usage]
12 | return --UNSAFE_BUFFERS(ptr); // not actually useful, only for example
| ^~~
The returned range should cover the entire unsafe operation, not the unsafe argument allowing us to write
int lookup(int *ptr, unsigned idx) {
return UNSAFE_BUFFERS(ptr[idx]);
}
int* predecrement(int* ptr) {
return UNSAFE_BUFFERS(--ptr); // not actually useful, only for example
}
which compiles cleanly