Files
clang-p2996/clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma.cpp
Artem Dergachev b7bdf1996f [-Wunsafe-buffer-usage] Hide fixits/suggestions behind an extra flag.
This patch implements a new clang driver flag -fsafe-buffer-usage-suggestions
which allows turning the smart suggestion machine on and off (defaults to off).
This is valuable for stability reasons, as the machine is being rapidly improved\
and we don't want accidental breakages to ruin the build for innocent users.
It is also arguably useful in general because it enables separation of concerns
between project contributors: some users will actively update the code to
conform to the programming model, while others simply want to make sure that
they aren't regressing it. Finally, there could be other valid reasons to
opt out of suggestions entirely on some codebases (while continuing to enforce
-Wunsafe-buffer-usage warnings), such as lack of access to hardened libc++
(or even to the C++ standard library in general) on the target platform.

When the flag is disabled, the unsafe buffer usage analysis is reduced to
an extremely minimal mode of operation that contains virtually no smarts:
not only it doesn't offer automatic fixits, but also textual suggestions
such as "change the type of this variable to std::span to preserve bounds
information" are not displayed, and in fact the machine doesn't even try
to blame specific variables in the first place, it simply warns on
the operations and leaves everything else to the user. So this flag turns off
a lot more of our complex machinery than what we already turn off in presence
of say -fno-diagnostic-fixit-info.

The flag is discoverable: when it's off, the warnings are accompanied by a note:
telling the user that there's a flag they can use.

Differential Revision: https://reviews.llvm.org/D146669
2023-05-18 17:20:27 -07:00

103 lines
3.4 KiB
C++

// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage \
// RUN: -fsafe-buffer-usage-suggestions \
// RUN: -Wno-unused-value -verify %s
void basic(int * x) { // expected-warning{{'x' is an unsafe pointer used for buffer access}}
int *p1 = new int[10]; // not to warn
int *p2 = new int[10]; // expected-warning{{'p2' is an unsafe pointer used for buffer access}}
#pragma clang unsafe_buffer_usage begin
p1[5]; // not to warn
#define _INCLUDE_NO_WARN
#include "warn-unsafe-buffer-usage-pragma.h" // increment p1 in header
int *p3 = new int[10]; // expected-warning{{'p3' is an unsafe pointer used for buffer access}}
#pragma clang unsafe_buffer_usage end
p2[5]; //expected-note{{used in buffer access here}}
p3[5]; //expected-note{{used in buffer access here}}
x++; //expected-note{{used in pointer arithmetic here}}
#define _INCLUDE_WARN
#include "warn-unsafe-buffer-usage-pragma.h" // increment p2 in header
}
void withDiagnosticWarning() {
int *p1 = new int[10]; // not to warn
int *p2 = new int[10]; // expected-warning{{'p2' is an unsafe pointer used for buffer access}}
// diagnostics in opt-out region
#pragma clang unsafe_buffer_usage begin
p1[5]; // not to warn
p2[5]; // not to warn
#pragma clang diagnostic push
#pragma clang diagnostic warning "-Wunsafe-buffer-usage"
p1[5]; // not to warn
p2[5]; // not to warn
#pragma clang diagnostic warning "-Weverything"
p1[5]; // not to warn expected-warning{{expression result unused}}
p2[5]; // not to warn expected-warning{{expression result unused}}
#pragma clang diagnostic pop
#pragma clang unsafe_buffer_usage end
// opt-out region under diagnostic warning
#pragma clang diagnostic push
#pragma clang diagnostic warning "-Wunsafe-buffer-usage"
#pragma clang unsafe_buffer_usage begin
p1[5]; // not to warn
p2[5]; // not to warn
#pragma clang unsafe_buffer_usage end
#pragma clang diagnostic pop
p2[5]; // expected-note{{used in buffer access here}}
}
void withDiagnosticIgnore() {
int *p1 = new int[10]; // not to warn
int *p2 = new int[10]; // expected-warning{{'p2' is an unsafe pointer used for buffer access}}
int *p3 = new int[10]; // expected-warning{{'p3' is an unsafe pointer used for buffer access}}
#pragma clang unsafe_buffer_usage begin
p1[5]; // not to warn
p2[5]; // not to warn
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
p1[5]; // not to warn
p2[5]; // not to warn
#pragma clang diagnostic ignored "-Weverything"
p1[5]; // not to warn
p2[5]; // not to warn
#pragma clang diagnostic pop
#pragma clang unsafe_buffer_usage end
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#pragma clang unsafe_buffer_usage begin
p1[5]; // not to warn
p2[5]; // not to warn
#pragma clang unsafe_buffer_usage end
#pragma clang diagnostic pop
p2[5]; // expected-note{{used in buffer access here}}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#pragma clang unsafe_buffer_usage begin
p1[5]; // not to warn
p2[5]; // not to warn
#pragma clang unsafe_buffer_usage end
p3[5]; // expected-note{{used in buffer access here}}
#pragma clang diagnostic pop
}
void noteGoesWithVarDeclWarning() {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
int *p = new int[10]; // not to warn
#pragma clang diagnostic pop
p[5]; // not to note since the associated warning is suppressed
}