diff options
-rw-r--r-- | include/clang/Basic/LangOptions.def | 1 | ||||
-rw-r--r-- | include/clang/Frontend/CodeGenOptions.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 12 | ||||
-rw-r--r-- | test/CodeGen/bounds-checking.c | 21 |
7 files changed, 35 insertions, 20 deletions
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index a795c57881..d2ce7c0df6 100644 --- a/include/clang/Basic/LangOptions.def +++ b/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/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index 3181c0affd..be7f03fe13 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/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/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index 9633dec1fe..f889606475 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/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/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 11b8ed254c..190855d3a0 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/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/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 5d108be273..dfb04b42aa 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/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/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 3a7efbcdab..5a3732bf43 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/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/test/CodeGen/bounds-checking.c b/test/CodeGen/bounds-checking.c index 3271b76dcb..e2786203e6 100644 --- a/test/CodeGen/bounds-checking.c +++ b/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; } |