@@ -43,10 +43,6 @@ STATISTIC(ChecksUnable, "Bounds checks unable to add");
43
43
44
44
using BuilderTy = IRBuilder<TargetFolder>;
45
45
46
- BoundsCheckingPass::BoundsCheckingOptions::BoundsCheckingOptions (
47
- ReportingMode Mode, bool Merge)
48
- : Mode(Mode), Merge(Merge) {}
49
-
50
46
// / Gets the conditions under which memory accessing instructions will overflow.
51
47
// /
52
48
// / \p Ptr is the pointer that will be read/written, and \p InstVal is either
@@ -166,42 +162,19 @@ static void insertBoundsCheck(Value *Or, BuilderTy &IRB, GetTrapBBT GetTrapBB) {
166
162
BranchInst::Create (TrapBB, Cont, Or, OldBB);
167
163
}
168
164
169
- struct ReportingOpts {
170
- bool MayReturn = false ;
171
- bool UseTrap = false ;
172
- bool MinRuntime = false ;
173
- bool MayMerge = true ;
174
- StringRef Name;
175
-
176
- ReportingOpts (BoundsCheckingPass::ReportingMode Mode, bool Merge) {
177
- switch (Mode) {
178
- case BoundsCheckingPass::ReportingMode::Trap:
179
- UseTrap = true ;
180
- break ;
181
- case BoundsCheckingPass::ReportingMode::MinRuntime:
182
- Name = " __ubsan_handle_local_out_of_bounds_minimal" ;
183
- MinRuntime = true ;
184
- MayReturn = true ;
185
- break ;
186
- case BoundsCheckingPass::ReportingMode::MinRuntimeAbort:
187
- Name = " __ubsan_handle_local_out_of_bounds_minimal_abort" ;
188
- MinRuntime = true ;
189
- break ;
190
- case BoundsCheckingPass::ReportingMode::FullRuntime:
191
- Name = " __ubsan_handle_local_out_of_bounds" ;
192
- MayReturn = true ;
193
- break ;
194
- case BoundsCheckingPass::ReportingMode::FullRuntimeAbort:
195
- Name = " __ubsan_handle_local_out_of_bounds_abort" ;
196
- break ;
197
- }
198
-
199
- MayMerge = Merge;
200
- }
201
- };
165
+ static std::string getRuntimeCallName (
166
+ const BoundsCheckingPass::BoundsCheckingOptions::Runtime &Opts) {
167
+ std::string Name = " __ubsan_handle_local_out_of_bounds" ;
168
+ if (Opts.MinRuntime )
169
+ Name += " _minimal" ;
170
+ if (!Opts.MayReturn )
171
+ Name += " _abort" ;
172
+ return Name;
173
+ }
202
174
203
- static bool addBoundsChecking (Function &F, TargetLibraryInfo &TLI,
204
- ScalarEvolution &SE, const ReportingOpts &Opts) {
175
+ static bool
176
+ addBoundsChecking (Function &F, TargetLibraryInfo &TLI, ScalarEvolution &SE,
177
+ const BoundsCheckingPass::BoundsCheckingOptions &Opts) {
205
178
if (F.hasFnAttribute (Attribute::NoSanitizeBounds))
206
179
return false ;
207
180
@@ -239,11 +212,16 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
239
212
TrapInfo.push_back (std::make_pair (&I, Or));
240
213
}
241
214
215
+ std::string Name;
216
+ if (Opts.Rt )
217
+ Name = getRuntimeCallName (*Opts.Rt );
218
+
242
219
// Create a trapping basic block on demand using a callback. Depending on
243
220
// flags, this will either create a single block for the entire function or
244
221
// will create a fresh block every time it is called.
245
222
BasicBlock *ReuseTrapBB = nullptr ;
246
- auto GetTrapBB = [&ReuseTrapBB, &Opts](BuilderTy &IRB, BasicBlock *Cont) {
223
+ auto GetTrapBB = [&ReuseTrapBB, &Opts, &Name](BuilderTy &IRB,
224
+ BasicBlock *Cont) {
247
225
Function *Fn = IRB.GetInsertBlock ()->getParent ();
248
226
auto DebugLoc = IRB.getCurrentDebugLocation ();
249
227
IRBuilder<>::InsertPointGuard Guard (IRB);
@@ -257,23 +235,24 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
257
235
BasicBlock *TrapBB = BasicBlock::Create (Fn->getContext (), " trap" , Fn);
258
236
IRB.SetInsertPoint (TrapBB);
259
237
260
- bool DebugTrapBB = !Opts.MayMerge ;
261
- CallInst *TrapCall = Opts.UseTrap
262
- ? InsertTrap (IRB, DebugTrapBB)
263
- : InsertCall (IRB, Opts.MayReturn , Opts.Name );
238
+ bool DebugTrapBB = !Opts.Merge ;
239
+ CallInst *TrapCall = Opts.Rt ? InsertCall (IRB, Opts.Rt ->MayReturn , Name)
240
+ : InsertTrap (IRB, DebugTrapBB);
264
241
if (DebugTrapBB)
265
242
TrapCall->addFnAttr (llvm::Attribute::NoMerge);
266
243
267
244
TrapCall->setDoesNotThrow ();
268
245
TrapCall->setDebugLoc (DebugLoc);
269
- if (Opts.MayReturn ) {
246
+
247
+ bool MayReturn = Opts.Rt && Opts.Rt ->MayReturn ;
248
+ if (MayReturn) {
270
249
IRB.CreateBr (Cont);
271
250
} else {
272
251
TrapCall->setDoesNotReturn ();
273
252
IRB.CreateUnreachable ();
274
253
}
275
254
276
- if (!Opts. MayReturn && SingleTrapBB && !DebugTrapBB)
255
+ if (!MayReturn && SingleTrapBB && !DebugTrapBB)
277
256
ReuseTrapBB = TrapBB;
278
257
279
258
return TrapBB;
@@ -292,8 +271,7 @@ PreservedAnalyses BoundsCheckingPass::run(Function &F, FunctionAnalysisManager &
292
271
auto &TLI = AM.getResult <TargetLibraryAnalysis>(F);
293
272
auto &SE = AM.getResult <ScalarEvolutionAnalysis>(F);
294
273
295
- if (!addBoundsChecking (F, TLI, SE,
296
- ReportingOpts (Options.Mode , Options.Merge )))
274
+ if (!addBoundsChecking (F, TLI, SE, Options))
297
275
return PreservedAnalyses::all ();
298
276
299
277
return PreservedAnalyses::none ();
@@ -303,22 +281,15 @@ void BoundsCheckingPass::printPipeline(
303
281
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
304
282
static_cast <PassInfoMixin<BoundsCheckingPass> *>(this )->printPipeline (
305
283
OS, MapClassName2PassName);
306
- switch (Options.Mode ) {
307
- case ReportingMode::Trap:
308
- OS << " <trap" ;
309
- break ;
310
- case ReportingMode::MinRuntime:
311
- OS << " <min-rt" ;
312
- break ;
313
- case ReportingMode::MinRuntimeAbort:
314
- OS << " <min-rt-abort" ;
315
- break ;
316
- case ReportingMode::FullRuntime:
317
- OS << " <rt" ;
318
- break ;
319
- case ReportingMode::FullRuntimeAbort:
320
- OS << " <rt-abort" ;
321
- break ;
284
+ OS << " <" ;
285
+ if (Options.Rt ) {
286
+ if (Options.Rt ->MinRuntime )
287
+ OS << " min-" ;
288
+ OS << " rt" ;
289
+ if (!Options.Rt ->MayReturn )
290
+ OS << " -abort" ;
291
+ } else {
292
+ OS << " trap" ;
322
293
}
323
294
if (Options.Merge )
324
295
OS << " ;merge" ;
0 commit comments