Now with the patch, sorry..
Nuno

Citando Nuno Lopes <[email protected]>:

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
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.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to