22// RUN: mkdir -p %t
33// RUN: split-file %s %t
44
5- // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=safe_buffers_test_base -x c++ %t/safe_buffers_test.modulemap -std=c++20\
6- // RUN: -o %t/safe_buffers_test_base.pcm -Wunsafe-buffer-usage
7- // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=safe_buffers_test_textual -x c++ %t/safe_buffers_test.modulemap -std=c++20\
8- // RUN: -o %t/safe_buffers_test_textual.pcm -Wunsafe-buffer-usage
9- // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=safe_buffers_test_optout -x c++ %t/safe_buffers_test.modulemap -std=c++20\
10- // RUN: -fmodule-file=%t/safe_buffers_test_base.pcm -fmodule-file=%t/safe_buffers_test_textual.pcm \
11- // RUN: -o %t/safe_buffers_test_optout.pcm -Wunsafe-buffer-usage
12- // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodule-file=%t/safe_buffers_test_optout.pcm -I %t -std=c++20 -Wunsafe-buffer-usage\
13- // RUN: -verify %t/safe_buffers_optout-explicit.cpp
14-
15-
16- // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -fmodule-map-file=%t/safe_buffers_test.modulemap -I%t\
17- // RUN: -x c++ -std=c++20 -Wunsafe-buffer-usage %t/safe_buffers_optout-implicit.cpp
185
6+ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=safe_buffers_test_base -x c++\
7+ // RUN: %t/safe_buffers_test.modulemap -std=c++20 -o %t/safe_buffers_test_base.pcm -Wunsafe-buffer-usage -verify
198// --- safe_buffers_test.modulemap
209module safe_buffers_test_base {
2110 header " base.h"
2211}
2312
13+ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=safe_buffers_test_textual -x c++ \
14+ // RUN: %t/safe_buffers_test.modulemap -std=c++20 -o %t/safe_buffers_test_textual.pcm \
15+ // RUN: -Wunsafe-buffer-usage
2416module safe_buffers_test_textual {
2517 textual header " textual.h"
2618}
2719
20+ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=safe_buffers_test_optout -x c++ \
21+ // RUN: %t/safe_buffers_test.modulemap -std=c++20 -fmodule-file=%t/safe_buffers_test_base.pcm \
22+ // RUN: -fmodule-file=%t/safe_buffers_test_textual.pcm -o %t/safe_buffers_test_optout.pcm -Wunsafe-buffer-usage\
23+ // RUN: -verify
2824module safe_buffers_test_optout {
2925 explicit module test_sub1 { header " test_sub1.h" }
3026 explicit module test_sub2 { header " test_sub2.h" }
3127 use safe_buffers_test_base
3228}
3329
30+
3431// --- base.h
3532#ifdef __cplusplus
3633int base (int *p) {
37- int x = p[5 ];
34+ int x = p[5 ]; // expected-warning{{unsafe buffer access}}\
35+ expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
3836#pragma clang unsafe_buffer_usage begin
3937 int y = p[5 ];
4038#pragma clang unsafe_buffer_usage end
@@ -47,7 +45,8 @@ int base(int *p) {
4745
4846#ifdef __cplusplus
4947int sub1 (int *p) {
50- int x = p[5 ];
48+ int x = p[5 ]; // expected-warning{{unsafe buffer access}}\
49+ expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
5150#pragma clang unsafe_buffer_usage begin
5251 int y = p[5 ];
5352#pragma clang unsafe_buffer_usage end
@@ -69,7 +68,8 @@ T sub1_T(T *p) {
6968
7069#ifdef __cplusplus
7170int sub2 (int *p) {
72- int x = p[5 ];
71+ int x = p[5 ]; // expected-warning{{unsafe buffer access}}\
72+ expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
7373#pragma clang unsafe_buffer_usage begin
7474 int y = p[5 ];
7575#pragma clang unsafe_buffer_usage end
@@ -86,33 +86,25 @@ int textual(int *p) {
8686}
8787#endif
8888
89- // --- safe_buffers_optout-explicit.cpp
90- # include " test_sub1.h "
91- # include " test_sub2.h "
89+ // Specify modules explicitly:
90+ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodule-file=%t/safe_buffers_test_optout.pcm -I %t \
91+ // RUN: -std=c++20 -Wunsafe-buffer-usage -verify=main %t/safe_buffers_optout_main.cpp
9292
93- // Testing safe buffers opt-out region serialization with modules: this
94- // file loads 2 submodules from top-level module
95- // `safe_buffers_test_optout`, which uses another top-level module
96- // `safe_buffers_test_base`. (So the module dependencies form a DAG.)
93+ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodule-file=%t/safe_buffers_test_optout.pcm -I %t \
94+ // RUN: -std=c++20 -Wunsafe-buffer-usage -verify=main-fixit %t/safe_buffers_optout_main.cpp \
95+ // RUN: -fsafe-buffer-usage-suggestions
9796
98- // No expected warnings from base.h, test_sub1, or test_sub2 because they are
99- // in separate modules, and the explicit commands that builds them have no
100- // `-Wunsafe-buffer-usage`.
97+ // Specify modules implicitly:
98+ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify=main -fmodules-cache-path=%t \
99+ // RUN: -fmodule-map-file=%t/safe_buffers_test.modulemap -I%t\
100+ // RUN: -x c++ -std=c++20 -Wunsafe-buffer-usage %t/safe_buffers_optout_main.cpp
101101
102- int foo (int * p) {
103- int x = p[5 ]; // expected-warning{{unsafe buffer access}} expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
104- #pragma clang unsafe_buffer_usage begin
105- int y = p[5 ];
106- #pragma clang unsafe_buffer_usage end
107- sub1_T (p); // instantiate template
108- return sub1 (p) + sub2 (p);
109- }
102+ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify=main-fixit -fmodules-cache-path=%t \
103+ // RUN: -fmodule-map-file=%t/safe_buffers_test.modulemap -I%t\
104+ // RUN: -x c++ -std=c++20 -Wunsafe-buffer-usage %t/safe_buffers_optout_main.cpp \
105+ // RUN: -fsafe-buffer-usage-suggestions
110106
111- #pragma clang unsafe_buffer_usage begin
112- #include " textual.h" // This header is textually included (i.e., it is in the same TU as %s), so warnings are suppressed
113- #pragma clang unsafe_buffer_usage end
114-
115- // --- safe_buffers_optout-implicit.cpp
107+ // --- safe_buffers_optout_main.cpp
116108#include " test_sub1.h"
117109#include " test_sub2.h"
118110
@@ -121,18 +113,20 @@ int foo(int * p) {
121113// `safe_buffers_test_optout`, which uses another top-level module
122114// `safe_buffers_test_base`. (So the module dependencies form a DAG.)
123115
124- // No expected warnings from base.h, test_sub1, or test_sub2 because they are
125- // in separate modules, and the explicit commands that builds them have no
126- // `-Wunsafe-buffer-usage`.
127-
128- int foo (int * p) {
129- int x = p[5 ]; // expected-warning{{unsafe buffer access}} expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
116+ int foo (int * p) { // main-fixit-warning{{'p' is an unsafe pointer used for buffer access}} \
117+ main-fixit-note{{change type of 'p' to 'std::span' to preserve bounds information}}
118+ int x = p[5 ]; // main-warning{{unsafe buffer access}} \
119+ main-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}} \
120+ main-fixit-note{{used in buffer access here}}
130121#pragma clang unsafe_buffer_usage begin
131122 int y = p[5 ];
132123#pragma clang unsafe_buffer_usage end
133124 sub1_T (p); // instantiate template
134125 return sub1 (p) + sub2 (p);
135126}
127+ // main-warning@test_sub1.h:15 {{unsafe buffer access}}
128+ // main-note@test_sub1.h:15 {{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
129+ // main-note@-5{{in instantiation of function template specialization 'sub1_T<int>' requested here}}
136130
137131#pragma clang unsafe_buffer_usage begin
138132#include " textual.h" // This header is textually included (i.e., it is in the same TU as %s), so warnings are suppressed
0 commit comments