[cfe-commits] -fbounds-checking

Nuno Lopes nunoplopes at sapo.pt
Mon May 7 13:01:19 PDT 2012


Now with the patch, sorry..
Nuno

Citando Nuno Lopes <nunoplopes at sapo.pt>:

> Hi,
>
> I would like to add a new option to clang: -fbounds-checking. It emits
> run-time bounds checks for array/pointers dereferencing based on
> LLVM's object size built-in. The code to emit the checks is already in
> clang; it's just a matter of wiring the flag.
> The other change is to make -fcatch-undefined-behavior imply
> -fbounds-checking (so that it keeps doing these kinds of checks).
>
> This flag supports an additional integer parameter to control the
> amount of run-time performance penalty you're willing to afford. For
> example, -fbounds-checking=1 will only resolve stuff at compile-time,
> while at level 2 it can defer some stuff to run-time. This will come
> in a separate patch to LLVM.
>
> Comments, ideas, etc?
>
> Thanks,
> Nuno
-------------- next part --------------
Index: include/clang/Basic/LangOptions.def
===================================================================
--- include/clang/Basic/LangOptions.def	(revision 156311)
+++ include/clang/Basic/LangOptions.def	(working copy)
@@ -157,6 +157,7 @@
                "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++")
 
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td	(revision 156311)
+++ include/clang/Driver/Options.td	(working copy)
@@ -315,6 +315,9 @@
 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">,
+  HelpText<"Enable run-time bounds checks.">, Group<f_Group>;
+def Wbounds_checking_EQ : Joined<"-fbounds-checking=">, 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>;
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp	(revision 156311)
+++ lib/Frontend/CompilerInvocation.cpp	(working copy)
@@ -675,6 +675,8 @@
     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,9 @@
     Opts.ObjCNonFragileABI2 = true;
   Opts.ObjCDefaultSynthProperties =
     Args.hasArg(OPT_fobjc_default_synthesize_properties);
-  Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
+  Opts.BoundsChecking = Args.getLastArgIntValue(OPT_fbounds_checking, 0, Diags);
+  if ((Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior)))
+    Opts.BoundsChecking = 5;
   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);
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp	(revision 156311)
+++ lib/CodeGen/CodeGenFunction.cpp	(working copy)
@@ -41,6 +41,7 @@
     CXXVTTValue(0), OutermostConditional(0), TerminateLandingPad(0),
     TerminateHandler(0), TrapBB(0) {
 
+  BoundsChecking = getContext().getLangOpts().BoundsChecking;
   CatchUndefined = getContext().getLangOpts().CatchUndefined;
   CGM.getCXXABI().getMangleContext().startNewFunction();
 }
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp	(revision 156311)
+++ lib/CodeGen/CGExpr.cpp	(working copy)
@@ -517,7 +517,7 @@
 }
 
 void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {
-  if (!CatchUndefined)
+  if (BoundsChecking <= 0)
     return;
 
   // This needs to be to the standard address space.
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h	(revision 156311)
+++ lib/CodeGen/CodeGenFunction.h	(working copy)
@@ -591,6 +591,11 @@
   /// 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.


More information about the cfe-commits mailing list