@@ -43,10 +43,6 @@ STATISTIC(ChecksUnable, "Bounds checks unable to add");
4343
4444using BuilderTy = IRBuilder<TargetFolder>;
4545
46- BoundsCheckingPass::BoundsCheckingOptions::BoundsCheckingOptions (
47- ReportingMode Mode, bool Merge)
48- : Mode(Mode), Merge(Merge) {}
49-
5046// / Gets the conditions under which memory accessing instructions will overflow.
5147// /
5248// / \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) {
166162 BranchInst::Create (TrapBB, Cont, Or, OldBB);
167163}
168164
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+ }
202174
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) {
205178 if (F.hasFnAttribute (Attribute::NoSanitizeBounds))
206179 return false ;
207180
@@ -239,11 +212,16 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
239212 TrapInfo.push_back (std::make_pair (&I, Or));
240213 }
241214
215+ std::string Name;
216+ if (Opts.Rt )
217+ Name = getRuntimeCallName (*Opts.Rt );
218+
242219 // Create a trapping basic block on demand using a callback. Depending on
243220 // flags, this will either create a single block for the entire function or
244221 // will create a fresh block every time it is called.
245222 BasicBlock *ReuseTrapBB = nullptr ;
246- auto GetTrapBB = [&ReuseTrapBB, &Opts](BuilderTy &IRB, BasicBlock *Cont) {
223+ auto GetTrapBB = [&ReuseTrapBB, &Opts, &Name](BuilderTy &IRB,
224+ BasicBlock *Cont) {
247225 Function *Fn = IRB.GetInsertBlock ()->getParent ();
248226 auto DebugLoc = IRB.getCurrentDebugLocation ();
249227 IRBuilder<>::InsertPointGuard Guard (IRB);
@@ -257,23 +235,24 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
257235 BasicBlock *TrapBB = BasicBlock::Create (Fn->getContext (), " trap" , Fn);
258236 IRB.SetInsertPoint (TrapBB);
259237
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);
264241 if (DebugTrapBB)
265242 TrapCall->addFnAttr (llvm::Attribute::NoMerge);
266243
267244 TrapCall->setDoesNotThrow ();
268245 TrapCall->setDebugLoc (DebugLoc);
269- if (Opts.MayReturn ) {
246+
247+ bool MayReturn = Opts.Rt && Opts.Rt ->MayReturn ;
248+ if (MayReturn) {
270249 IRB.CreateBr (Cont);
271250 } else {
272251 TrapCall->setDoesNotReturn ();
273252 IRB.CreateUnreachable ();
274253 }
275254
276- if (!Opts. MayReturn && SingleTrapBB && !DebugTrapBB)
255+ if (!MayReturn && SingleTrapBB && !DebugTrapBB)
277256 ReuseTrapBB = TrapBB;
278257
279258 return TrapBB;
@@ -292,8 +271,7 @@ PreservedAnalyses BoundsCheckingPass::run(Function &F, FunctionAnalysisManager &
292271 auto &TLI = AM.getResult <TargetLibraryAnalysis>(F);
293272 auto &SE = AM.getResult <ScalarEvolutionAnalysis>(F);
294273
295- if (!addBoundsChecking (F, TLI, SE,
296- ReportingOpts (Options.Mode , Options.Merge )))
274+ if (!addBoundsChecking (F, TLI, SE, Options))
297275 return PreservedAnalyses::all ();
298276
299277 return PreservedAnalyses::none ();
@@ -303,22 +281,15 @@ void BoundsCheckingPass::printPipeline(
303281 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
304282 static_cast <PassInfoMixin<BoundsCheckingPass> *>(this )->printPipeline (
305283 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" ;
322293 }
323294 if (Options.Merge )
324295 OS << " ;merge" ;
0 commit comments