From a425589feac540f1792d2e698c1cb0103ba1ec86 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Tue, 22 May 2012 17:19:45 +0000 Subject: [PATCH] wire -fbounds-checking to the new LLVM bounds checking pass llvm-svn: 157262 --- clang/include/clang/Basic/LangOptions.def | 1 - clang/include/clang/Frontend/CodeGenOptions.h | 4 ++++ clang/lib/CodeGen/BackendUtil.cpp | 14 ++++++++++++++ clang/lib/CodeGen/CGExpr.cpp | 2 +- clang/lib/CodeGen/CodeGenFunction.cpp | 1 - clang/lib/Frontend/CompilerInvocation.cpp | 12 +++++------- clang/test/CodeGen/bounds-checking.c | 21 +++++++++++---------- 7 files changed, 35 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index a795c57..d2ce7c0 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -157,7 +157,6 @@ BENIGN_LANGOPT(ConstexprCallDepth, 32, 512, "maximum constexpr call depth") BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0, "if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.") -BENIGN_LANGOPT(BoundsChecking , 8, 0, "if non-zero, add run-time bounds checking code") VALUE_LANGOPT(MSCVersion, 32, 0, "version of Microsoft Visual C/C++") diff --git a/clang/include/clang/Frontend/CodeGenOptions.h b/clang/include/clang/Frontend/CodeGenOptions.h index 3181c0a..be7f03f 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.h +++ b/clang/include/clang/Frontend/CodeGenOptions.h @@ -172,6 +172,9 @@ public: /// or 0 if unspecified. unsigned NumRegisterParameters; + /// The run-time penalty for bounds checking, or 0 to disable. + unsigned char BoundsChecking; + public: CodeGenOptions() { AsmVerbose = 0; @@ -224,6 +227,7 @@ public: VerifyModule = 1; StackRealignment = 0; StackAlignment = 0; + BoundsChecking = 0; DebugInfo = NoDebugInfo; Inlining = NoInlining; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 9633dec..f889606 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -121,6 +121,12 @@ static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase PM.add(createObjCARCOptPass()); } +static unsigned BoundsChecking; +static void addBoundsCheckingPass(const PassManagerBuilder &Builder, + PassManagerBase &PM) { + PM.add(createBoundsCheckingPass(BoundsChecking)); +} + static void addAddressSanitizerPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { PM.add(createAddressSanitizerPass()); @@ -160,6 +166,14 @@ void EmitAssemblyHelper::CreatePasses() { addObjCARCOptPass); } + if (CodeGenOpts.BoundsChecking > 0) { + BoundsChecking = CodeGenOpts.BoundsChecking; + PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, + addBoundsCheckingPass); + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, + addBoundsCheckingPass); + } + if (LangOpts.AddressSanitizer) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addAddressSanitizerPass); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 11b8ed2..190855d 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -517,7 +517,7 @@ unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx, } void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) { - if (BoundsChecking <= 0) + if (!CatchUndefined) return; // This needs to be to the standard address space. diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 5d108be..dfb04b4 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -41,7 +41,6 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) CXXVTTValue(0), OutermostConditional(0), TerminateLandingPad(0), TerminateHandler(0), TrapBB(0) { - BoundsChecking = getContext().getLangOpts().BoundsChecking; CatchUndefined = getContext().getLangOpts().CatchUndefined; CGM.getCXXABI().getMangleContext().startNewFunction(); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 3a7efbc..5a3732b 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -283,6 +283,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts, ToArgsList &Res) { Res.push_back("-fobjc-dispatch-method=non-legacy"); break; } + if (Opts.BoundsChecking > 0) + Res.push_back("-fbounds-checking=" + llvm::utostr(Opts.BoundsChecking)); if (Opts.NumRegisterParameters) Res.push_back("-mregparm", llvm::utostr(Opts.NumRegisterParameters)); if (Opts.NoGlobalMerge) @@ -675,8 +677,6 @@ static void LangOptsToArgs(const LangOptions &Opts, ToArgsList &Res) { Res.push_back("-fno-operator-names"); if (Opts.PascalStrings) Res.push_back("-fpascal-strings"); - if (Opts.BoundsChecking > 0) - Res.push_back("-fbounds-checking=" + llvm::utostr(Opts.BoundsChecking)); if (Opts.CatchUndefined) Res.push_back("-fcatch-undefined-behavior"); if (Opts.AddressSanitizer) @@ -1217,6 +1217,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic"); Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ); + Opts.BoundsChecking = Args.getLastArgIntValue(OPT_fbounds_checking_EQ, 0, + Diags); Opts.FunctionSections = Args.hasArg(OPT_ffunction_sections); Opts.DataSections = Args.hasArg(OPT_fdata_sections); @@ -1955,11 +1957,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ObjCNonFragileABI2 = true; Opts.ObjCDefaultSynthProperties = Args.hasArg(OPT_fobjc_default_synthesize_properties); - Opts.BoundsChecking = 0; - if ((Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior))) - Opts.BoundsChecking = 5; - Opts.BoundsChecking = Args.getLastArgIntValue(OPT_fbounds_checking_EQ, - Opts.BoundsChecking, Diags); + Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior); Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls); Opts.PackStruct = Args.getLastArgIntValue(OPT_fpack_struct_EQ, 0, Diags); Opts.PICLevel = Args.getLastArgIntValue(OPT_pic_level, 0, Diags); diff --git a/clang/test/CodeGen/bounds-checking.c b/clang/test/CodeGen/bounds-checking.c index 3271b76..e278620 100644 --- a/clang/test/CodeGen/bounds-checking.c +++ b/clang/test/CodeGen/bounds-checking.c @@ -3,23 +3,24 @@ // CHECK: @f double f(int b, int i) { double a[b]; + // CHECK: trap return a[i]; - // CHECK: objectsize.i64({{.*}}, i1 false) - // CHECK: icmp uge i64 {{.*}}, 8 } // CHECK: @f2 void f2() { + // everything is constant; no trap possible + // CHECK-NOT: trap int a[2]; - // CHECK: objectsize.i64({{.*}}, i1 false) - // CHECK: icmp uge i64 {{.*}}, 4 a[1] = 42; short *b = malloc(64); - // CHECK: objectsize.i64({{.*}}, i1 false) - // CHECK: icmp uge i64 {{.*}}, 4 - // CHECK: getelementptr {{.*}}, i64 5 - // CHECK: objectsize.i64({{.*}}, i1 false) - // CHECK: icmp uge i64 {{.*}}, 2 - b[5] = a[1]+2; + b[5] = *a + a[1] + 2; +} + +// CHECK: @f3 +void f3() { + int a[1]; + // CHECK: trap + a[2] = 1; } -- 2.7.4