Add a pair of clang pragmas:
#pragma clang unsafe_buffer_usage begin
#pragma clang unsafe_buffer_usage end,
which specify the start and end of an (unsafe buffer checking) opt-out region.
Behaviors of opt-out regions conform to the following rules:
- No nested nor overlapped opt-out regions are allowed. One cannot start an opt-out region with ... unsafe_buffer_usage begin but never close it with ... unsafe_buffer_usage end. Mis-use of the pragmas will be warned.
- Warnings raised from unsafe buffer operations inside such an opt-out region will always be suppressed. This behavior CANNOT be changed by clang diagnostic pragmas or command-line flags.
- Warnings raised from unsafe operations outside of such opt-out regions may be reported on declarations inside opt-out regions. These warnings are NOT suppressed.
- An un-suppressed unsafe operation warning may be attached with notes. These notes are NOT suppressed as well regardless of whether they are in opt-out regions.
The implementation maintains a separate sequence of location pairs representing opt-out regions in Preprocessor.
The UnsafeBufferUsage analyzer reads the region sequence to check if an unsafe operation is in an opt-out region. If it is, discard the warning raised from the operation immediately.
Examples,
void f() { int * p = new int [10]; #pragma clang unsafe_buffer_usage begin p[5]; #pragma clang unsafe_buffer_usage end }
Nothing will be warned in the code above since the only unsafe operation p[5] is in an opt-out region.
void f() { #pragma clang unsafe_buffer_usage begin int * p = new int [10]; // expect a warning on `p` for the unsafe operation below #pragma clang unsafe_buffer_usage end p[5]; // may have a note here which is an attachment of the warning above }
In the example above, a warning triggered by p[5], which is not in an opt-out region, will be reported on the declaration. Although the declaration is in an opt-out region, the warning is NOT suppressed.
Ok, now I no longer see why this data should live in DiagnosticEngine. It's mostly about analysis, right? The pragma simply makes our analysis produce different results, regardless of whether these results are used for producing diagnostics or something else. Maybe let's keep it all in Preprocessor?