xref: /llvm-project/clang/test/Modules/safe_buffers_optout.cpp (revision 2e7b95e4c080426e5085c38cec01176b56798534)
1 // RUN: rm -rf %t
2 // RUN: mkdir -p %t
3 // RUN: split-file %s %t
4 
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
18 
19 //--- safe_buffers_test.modulemap
20 module safe_buffers_test_base {
21  header "base.h"
22 }
23 
24 module safe_buffers_test_textual {
25  textual header "textual.h"
26 }
27 
28 module safe_buffers_test_optout {
29   explicit module test_sub1 {  header "test_sub1.h" }
30   explicit module test_sub2 {  header "test_sub2.h" }
31   use safe_buffers_test_base
32 }
33 
34 //--- base.h
35 #ifdef __cplusplus
36 int base(int *p) {
37   int x = p[5];
38 #pragma clang unsafe_buffer_usage begin
39   int y = p[5];
40 #pragma clang unsafe_buffer_usage end
41   return x + y;
42 }
43 #endif
44 
45 //--- test_sub1.h
46 #include "base.h"
47 
48 #ifdef __cplusplus
49 int sub1(int *p) {
50   int x = p[5];
51 #pragma clang unsafe_buffer_usage begin
52   int y = p[5];
53 #pragma clang unsafe_buffer_usage end
54   return x + y + base(p);
55 }
56 
57 template <typename T>
58 T sub1_T(T *p) {
59   T x = p[5];
60 #pragma clang unsafe_buffer_usage begin
61   T y = p[5];
62 #pragma clang unsafe_buffer_usage end
63   return x + y;
64 }
65 #endif
66 
67 //--- test_sub2.h
68 #include "base.h"
69 
70 #ifdef __cplusplus
71 int sub2(int *p) {
72   int x = p[5];
73 #pragma clang unsafe_buffer_usage begin
74   int y = p[5];
75 #pragma clang unsafe_buffer_usage end
76   return x + y + base(p);
77 }
78 #endif
79 
80 //--- textual.h
81 #ifdef __cplusplus
82 int textual(int *p) {
83   int x = p[5];
84   int y = p[5];
85   return x + y;
86 }
87 #endif
88 
89 //--- safe_buffers_optout-explicit.cpp
90 #include "test_sub1.h"
91 #include "test_sub2.h"
92 
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.)
97 
98 // No expected warnings from base.h because base.h is a separate
99 // module and in a separate TU that is not textually included.  The
100 // explicit command that builds base.h has no `-Wunsafe-buffer-usage`.
101 
102 // expected-warning@base.h:3{{unsafe buffer access}}
103 // expected-note@base.h:3{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
104 // expected-warning@test_sub1.h:5{{unsafe buffer access}}
105 // expected-note@test_sub1.h:5{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
106 // expected-warning@test_sub1.h:14{{unsafe buffer access}}
107 // expected-note@test_sub1.h:14{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
108 // expected-warning@test_sub2.h:5{{unsafe buffer access}}
109 // expected-note@test_sub2.h:5{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
110 int foo(int * p) {
111   int x = p[5]; // expected-warning{{unsafe buffer access}} expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
112 #pragma clang unsafe_buffer_usage begin
113   int y = p[5];
114 #pragma clang unsafe_buffer_usage end
115   sub1_T(p); // instantiate template
116   return sub1(p) + sub2(p);
117 }
118 
119 #pragma clang unsafe_buffer_usage begin
120 #include "textual.h"         // This header is textually included (i.e., it is in the same TU as %s), so warnings are suppressed
121 #pragma clang unsafe_buffer_usage end
122 
123 //--- safe_buffers_optout-implicit.cpp
124 #include "test_sub1.h"
125 #include "test_sub2.h"
126 
127 // Testing safe buffers opt-out region serialization with modules: this
128 // file loads 2 submodules from top-level module
129 // `safe_buffers_test_optout`, which uses another top-level module
130 // `safe_buffers_test_base`. (So the module dependencies form a DAG.)
131 
132 // expected-warning@base.h:3{{unsafe buffer access}}
133 // expected-note@base.h:3{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
134 // expected-warning@test_sub1.h:5{{unsafe buffer access}}
135 // expected-note@test_sub1.h:5{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
136 // expected-warning@test_sub1.h:14{{unsafe buffer access}}
137 // expected-note@test_sub1.h:14{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
138 // expected-warning@test_sub2.h:5{{unsafe buffer access}}
139 // expected-note@test_sub2.h:5{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
140 int foo(int * p) {
141   int x = p[5]; // expected-warning{{unsafe buffer access}} expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
142 #pragma clang unsafe_buffer_usage begin
143   int y = p[5];
144 #pragma clang unsafe_buffer_usage end
145   sub1_T(p); // instantiate template
146   return sub1(p) + sub2(p);
147 }
148 
149 #pragma clang unsafe_buffer_usage begin
150 #include "textual.h"         // This header is textually included (i.e., it is in the same TU as %s), so warnings are suppressed
151 #pragma clang unsafe_buffer_usage end
152