aboutsummaryrefslogtreecommitdiff
path: root/clang/test/Modules/safe_buffers_optout.cpp
blob: 8c3d6a235d399048e021ea0963c4e960fa446f35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t

// 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\
// RUN:            -o %t/safe_buffers_test_base.pcm -Wunsafe-buffer-usage
// 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\
// RUN:            -o %t/safe_buffers_test_textual.pcm -Wunsafe-buffer-usage
// 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\
// RUN:            -fmodule-file=%t/safe_buffers_test_base.pcm -fmodule-file=%t/safe_buffers_test_textual.pcm \
// RUN:            -o %t/safe_buffers_test_optout.pcm -Wunsafe-buffer-usage
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodule-file=%t/safe_buffers_test_optout.pcm -I %t -std=c++20 -Wunsafe-buffer-usage\
// RUN:            -verify %t/safe_buffers_optout-explicit.cpp


// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -fmodule-map-file=%t/safe_buffers_test.modulemap -I%t\
// RUN:            -x c++ -std=c++20 -Wunsafe-buffer-usage %t/safe_buffers_optout-implicit.cpp

//--- safe_buffers_test.modulemap
module safe_buffers_test_base {
 header "base.h"
}

module safe_buffers_test_textual {
 textual header "textual.h"
}

module safe_buffers_test_optout {
  explicit module test_sub1 {  header "test_sub1.h" }
  explicit module test_sub2 {  header "test_sub2.h" }
  use safe_buffers_test_base
}

//--- base.h
#ifdef __cplusplus
int base(int *p) {
  int x = p[5];
#pragma clang unsafe_buffer_usage begin
  int y = p[5];
#pragma clang unsafe_buffer_usage end
  return x + y;
}
#endif

//--- test_sub1.h
#include "base.h"

#ifdef __cplusplus
int sub1(int *p) {
  int x = p[5];
#pragma clang unsafe_buffer_usage begin
  int y = p[5];
#pragma clang unsafe_buffer_usage end
  return x + y + base(p);
}

template <typename T>
T sub1_T(T *p) {
  T x = p[5];
#pragma clang unsafe_buffer_usage begin
  T y = p[5];
#pragma clang unsafe_buffer_usage end
  return x + y;
}
#endif

//--- test_sub2.h
#include "base.h"

#ifdef __cplusplus
int sub2(int *p) {
  int x = p[5];
#pragma clang unsafe_buffer_usage begin
  int y = p[5];
#pragma clang unsafe_buffer_usage end
  return x + y + base(p);
}
#endif

//--- textual.h
#ifdef __cplusplus
int textual(int *p) {
  int x = p[5];
  int y = p[5];
  return x + y;
}
#endif

//--- safe_buffers_optout-explicit.cpp
#include "test_sub1.h"
#include "test_sub2.h"

// Testing safe buffers opt-out region serialization with modules: this
// file loads 2 submodules from top-level module
// `safe_buffers_test_optout`, which uses another top-level module
// `safe_buffers_test_base`. (So the module dependencies form a DAG.)

// No expected warnings from base.h, test_sub1, or test_sub2 because they are
// in seperate modules, and the explicit commands that builds them have no
// `-Wunsafe-buffer-usage`.

int foo(int * p) {
  int x = p[5]; // expected-warning{{unsafe buffer access}} expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
#pragma clang unsafe_buffer_usage begin
  int y = p[5];
#pragma clang unsafe_buffer_usage end
  sub1_T(p); // instantiate template
  return sub1(p) + sub2(p);
}

#pragma clang unsafe_buffer_usage begin
#include "textual.h"         // This header is textually included (i.e., it is in the same TU as %s), so warnings are suppressed
#pragma clang unsafe_buffer_usage end

//--- safe_buffers_optout-implicit.cpp
#include "test_sub1.h"
#include "test_sub2.h"

// Testing safe buffers opt-out region serialization with modules: this
// file loads 2 submodules from top-level module
// `safe_buffers_test_optout`, which uses another top-level module
// `safe_buffers_test_base`. (So the module dependencies form a DAG.)

// No expected warnings from base.h, test_sub1, or test_sub2 because they are
// in seperate modules, and the explicit commands that builds them have no
// `-Wunsafe-buffer-usage`.

int foo(int * p) {
  int x = p[5]; // expected-warning{{unsafe buffer access}} expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
#pragma clang unsafe_buffer_usage begin
  int y = p[5];
#pragma clang unsafe_buffer_usage end
  sub1_T(p); // instantiate template
  return sub1(p) + sub2(p);
}

#pragma clang unsafe_buffer_usage begin
#include "textual.h"         // This header is textually included (i.e., it is in the same TU as %s), so warnings are suppressed
#pragma clang unsafe_buffer_usage end