diff options
-rw-r--r-- | include/clang/Basic/LangOptions.def | 1 | ||||
-rw-r--r-- | include/clang/Driver/Options.td | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 5 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 9 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 8 | ||||
-rw-r--r-- | test/Driver/bounds-checking.c | 7 |
8 files changed, 35 insertions, 2 deletions
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index d2ce7c0df6..a795c57881 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -157,6 +157,7 @@ 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/Driver/Options.td b/include/clang/Driver/Options.td index 5d20e21dac..1868a70fae 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -315,6 +315,10 @@ def fblocks : Flag<"-fblocks">, Group<f_Group>, Flags<[CC1Option]>, def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>; def fborland_extensions : Flag<"-fborland-extensions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Accept non-standard constructs supported by the Borland compiler">; +def fbounds_checking : Flag<"-fbounds-checking">, Group<f_Group>, + HelpText<"Enable run-time bounds checks.">; +def fbounds_checking_EQ : Joined<"-fbounds-checking=">, Flags<[CC1Option]>, + Group<f_Group>; def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>; def fbuiltin_strcpy : Flag<"-fbuiltin-strcpy">, Group<f_Group>; def fbuiltin : Flag<"-fbuiltin">, Group<f_Group>; diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index f977f5531a..19ee42824f 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 (!CatchUndefined) + if (BoundsChecking <= 0) return; // This needs to be to the standard address space. diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index dfb04b42aa..5d108be273 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -41,6 +41,7 @@ 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/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index a25b02aac8..8d48a0b24e 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -591,6 +591,11 @@ public: /// we prefer to insert allocas. llvm::AssertingVH<llvm::Instruction> AllocaInsertPt; + /// BoundsChecking - Emit run-time bounds checks. Higher values mean + /// potentially higher performance penalties. + unsigned char BoundsChecking; + + /// CatchUndefined - Emit run-time checks to catch undefined behaviors. bool CatchUndefined; /// In ARC, whether we should autorelease the return value. diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 90a9f0cf94..1ccba75507 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -2025,6 +2025,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value } + if (Arg *A = Args.getLastArg(options::OPT_fbounds_checking, + options::OPT_fbounds_checking_EQ)) { + if (A->getNumValues()) { + StringRef val = A->getValue(Args); + CmdArgs.push_back(Args.MakeArgString("-fbounds-checking=" + val)); + } else + CmdArgs.push_back("-fbounds-checking=1"); + } + if (Args.hasArg(options::OPT__relocatable_pch)) CmdArgs.push_back("-relocatable-pch"); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 0635be6667..3a7efbcdab 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -675,6 +675,8 @@ 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) @@ -1953,7 +1955,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ObjCNonFragileABI2 = true; Opts.ObjCDefaultSynthProperties = Args.hasArg(OPT_fobjc_default_synthesize_properties); - Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior); + 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.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/Driver/bounds-checking.c b/test/Driver/bounds-checking.c new file mode 100644 index 0000000000..95bb8afd0d --- /dev/null +++ b/test/Driver/bounds-checking.c @@ -0,0 +1,7 @@ +// RUN: %clang -target x86_64-apple-darwin10 -fbounds-checking -### -fsyntax-only %s 2> %t +// RUN: FileCheck < %t %s +// RUN: %clang -target x86_64-apple-darwin10 -fbounds-checking=3 -### -fsyntax-only %s 2> %t +// RUN: FileCheck -check-prefix=CHECK2 < %t %s + +// CHECK: "-fbounds-checking=1" +// CHECK2: "-fbounds-checking=3" |