]> gcc.gnu.org Git - gcc.git/commitdiff
gcc.c (sanitize_spec_function): Handle SANITIZE_FLOAT_DIVIDE.
authorMarek Polacek <polacek@redhat.com>
Wed, 30 Apr 2014 07:34:43 +0000 (07:34 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 30 Apr 2014 07:34:43 +0000 (07:34 +0000)
* gcc.c (sanitize_spec_function): Handle SANITIZE_FLOAT_DIVIDE.
* builtins.def: Initialize builtins even for SANITIZE_FLOAT_DIVIDE.
* flag-types.h (enum sanitize_code): Add SANITIZE_FLOAT_DIVIDE.
* opts.c (common_handle_option): Add -fsanitize=float-divide-by-zero.
c-family/
* c-ubsan.c (ubsan_instrument_division): Handle REAL_TYPEs.  Perform
INT_MIN / -1 sanitization only for integer types.
c/
* c-typeck.c (build_binary_op): Call ubsan_instrument_division
also when SANITIZE_FLOAT_DIVIDE is on.
cp/
* typeck.c (cp_build_binary_op): Call ubsan_instrument_division
even when SANITIZE_FLOAT_DIVIDE is on.  Set doing_div_or_mod even
for non-integer types.
testsuite/
* c-c++-common/ubsan/div-by-zero-5.c: Fix formatting.
* c-c++-common/ubsan/float-div-by-zero-1.c: New test.

From-SVN: r209927

14 files changed:
gcc/ChangeLog
gcc/builtins.def
gcc/c-family/ChangeLog
gcc/c-family/c-ubsan.c
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/flag-types.h
gcc/gcc.c
gcc/opts.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c
gcc/testsuite/c-c++-common/ubsan/float-div-by-zero-1.c [new file with mode: 0644]

index 7b4bb549d8ab58c81cd2468aec2e765492f01a7a..1bec6e12fa8722ae203e9d4b314e45488508e982 100644 (file)
@@ -1,3 +1,10 @@
+2014-04-30  Marek Polacek  <polacek@redhat.com>
+
+       * gcc.c (sanitize_spec_function): Handle SANITIZE_FLOAT_DIVIDE.
+       * builtins.def: Initialize builtins even for SANITIZE_FLOAT_DIVIDE.
+       * flag-types.h (enum sanitize_code): Add SANITIZE_FLOAT_DIVIDE.
+       * opts.c (common_handle_option): Add -fsanitize=float-divide-by-zero.
+
 2014-04-29  Alan Lawrence  <alan.lawrence@arm.com>
 
        * config/aarch64/arm_neon.h (vzip1_f32, vzip1_p8, vzip1_p16, vzip1_s8,
index 5b902d8a938217c0f5bcbcd149c52e3a5e201e4a..d400ecb4e8fffaa898aa7f44617cacd32503a499 100644 (file)
@@ -176,7 +176,7 @@ along with GCC; see the file COPYING3.  If not see
   DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,    \
               true, true, true, ATTRS, true, \
              (flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_THREAD \
-                               | SANITIZE_UNDEFINED)))
+                               | SANITIZE_UNDEFINED | SANITIZE_FLOAT_DIVIDE)))
 
 #undef DEF_CILKPLUS_BUILTIN
 #define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS)  \
index fb0d102eac3351aa1117bf567f30920a9315b9e0..47bb11438ad997dbca72276e6f48c23b0e0b502c 100644 (file)
@@ -1,3 +1,8 @@
+2014-04-30  Marek Polacek  <polacek@redhat.com>
+
+       * c-ubsan.c (ubsan_instrument_division): Handle REAL_TYPEs.  Perform
+       INT_MIN / -1 sanitization only for integer types.
+
 2014-04-25  Marek Polacek  <polacek@redhat.com>
 
        PR c/18079
index e4f6f327277b69b61516978d67794c8b80f95692..a0397925fe7aa9db4427782a14740b3fbb5d1f05 100644 (file)
@@ -46,15 +46,21 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1)
   gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
              == TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
 
-  /* TODO: REAL_TYPE is not supported yet.  */
-  if (TREE_CODE (type) != INTEGER_TYPE)
+  if (TREE_CODE (type) == INTEGER_TYPE
+      && (flag_sanitize & SANITIZE_DIVIDE))
+    t = fold_build2 (EQ_EXPR, boolean_type_node,
+                    op1, build_int_cst (type, 0));
+  else if (TREE_CODE (type) == REAL_TYPE
+          && (flag_sanitize & SANITIZE_FLOAT_DIVIDE))
+    t = fold_build2 (EQ_EXPR, boolean_type_node,
+                    op1, build_real (type, dconst0));
+  else
     return NULL_TREE;
 
-  t = fold_build2 (EQ_EXPR, boolean_type_node,
-                   op1, build_int_cst (type, 0));
-
   /* We check INT_MIN / -1 only for signed types.  */
-  if (!TYPE_UNSIGNED (type))
+  if (TREE_CODE (type) == INTEGER_TYPE
+      && (flag_sanitize & SANITIZE_DIVIDE)
+      && !TYPE_UNSIGNED (type))
     {
       tree x;
       tt = fold_build2 (EQ_EXPR, boolean_type_node, op1,
index d54b62e11ea86c469af90bd672217a4cf2f9b748..bf61610e37cb2c7a7ecef29700186734f41d75c7 100644 (file)
@@ -1,3 +1,8 @@
+2014-04-30  Marek Polacek  <polacek@redhat.com>
+
+       * c-typeck.c (build_binary_op): Call ubsan_instrument_division
+       also when SANITIZE_FLOAT_DIVIDE is on.
+
 2014-04-30  Marek Polacek  <polacek@redhat.com>
 
        PR c/60139
index 6e56b69ab5f9051951a52b24ea16a75f9186e9dc..cb8ae44e3632cf613d49aaf183ebf8c9fedaa003 100644 (file)
@@ -10997,7 +10997,8 @@ build_binary_op (location_t location, enum tree_code code,
        return error_mark_node;
     }
 
-  if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE))
+  if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE
+                       | SANITIZE_FLOAT_DIVIDE))
       && current_function_decl != 0
       && !lookup_attribute ("no_sanitize_undefined",
                            DECL_ATTRIBUTES (current_function_decl))
@@ -11008,7 +11009,8 @@ build_binary_op (location_t location, enum tree_code code,
       op1 = c_save_expr (op1);
       op0 = c_fully_fold (op0, false, NULL);
       op1 = c_fully_fold (op1, false, NULL);
-      if (doing_div_or_mod && (flag_sanitize & SANITIZE_DIVIDE))
+      if (doing_div_or_mod && (flag_sanitize & (SANITIZE_DIVIDE
+                                               | SANITIZE_FLOAT_DIVIDE)))
        instrument_expr = ubsan_instrument_division (location, op0, op1);
       else if (doing_shift && (flag_sanitize & SANITIZE_SHIFT))
        instrument_expr = ubsan_instrument_shift (location, code, op0, op1);
index b2018255b1830816b13b891c4f46b36f296be5c4..c4be5bdde6c51be38291fd68cf654c6dc2c7565e 100644 (file)
@@ -1,3 +1,9 @@
+2014-04-30  Marek Polacek  <polacek@redhat.com>
+
+       * typeck.c (cp_build_binary_op): Call ubsan_instrument_division
+       even when SANITIZE_FLOAT_DIVIDE is on.  Set doing_div_or_mod even
+       for non-integer types.
+
 2014-04-29  Jason Merrill  <jason@redhat.com>
 
        DR 1351
index ae7fa776eb84023811b6ef4651bc9b9b5ba3ebf7..729e22eadc57dc262759fbcd9880df4424acc008 100644 (file)
@@ -4110,10 +4110,7 @@ cp_build_binary_op (location_t location,
          enum tree_code tcode0 = code0, tcode1 = code1;
          tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
          cop1 = maybe_constant_value (cop1);
-
-         if (tcode0 == INTEGER_TYPE)
-           doing_div_or_mod = true;
-
+         doing_div_or_mod = true;
          warn_for_div_by_zero (location, cop1);
 
          if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
@@ -4153,9 +4150,7 @@ cp_build_binary_op (location_t location,
       {
        tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
        cop1 = maybe_constant_value (cop1);
-
-       if (code0 == INTEGER_TYPE)
-         doing_div_or_mod = true;
+       doing_div_or_mod = true;
        warn_for_div_by_zero (location, cop1);
       }
 
@@ -4902,7 +4897,8 @@ cp_build_binary_op (location_t location,
   if (build_type == NULL_TREE)
     build_type = result_type;
 
-  if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE))
+  if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE
+                       | SANITIZE_FLOAT_DIVIDE))
       && !processing_template_decl
       && current_function_decl != 0
       && !lookup_attribute ("no_sanitize_undefined",
@@ -4916,7 +4912,8 @@ cp_build_binary_op (location_t location,
                                                                  tf_none));
       op1 = maybe_constant_value (fold_non_dependent_expr_sfinae (op1,
                                                                  tf_none));
-      if (doing_div_or_mod && (flag_sanitize & SANITIZE_DIVIDE))
+      if (doing_div_or_mod && (flag_sanitize & (SANITIZE_DIVIDE
+                                               | SANITIZE_FLOAT_DIVIDE)))
        {
          /* For diagnostics we want to use the promoted types without
             shorten_binary_op.  So convert the arguments to the
index fc3261bbbb72b2d1f98386d6ba7cd13efb541811..caf4039f9df03c8cf9f5654299f08b39ac975d0b 100644 (file)
@@ -228,6 +228,7 @@ enum sanitize_code {
   SANITIZE_SI_OVERFLOW = 1 << 9,
   SANITIZE_BOOL = 1 << 10,
   SANITIZE_ENUM = 1 << 11,
+  SANITIZE_FLOAT_DIVIDE = 1 << 12,
   SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
                       | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN
                       | SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM
index e5130d13535604a1e852434925fbe734440d2996..7bea6d79ac2753a30cb7ed53ca04de9c7d28a2f7 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -8170,7 +8170,7 @@ sanitize_spec_function (int argc, const char **argv)
   if (strcmp (argv[0], "thread") == 0)
     return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
   if (strcmp (argv[0], "undefined") == 0)
-    return ((flag_sanitize & SANITIZE_UNDEFINED)
+    return ((flag_sanitize & (SANITIZE_UNDEFINED | SANITIZE_FLOAT_DIVIDE))
            && !flag_sanitize_undefined_trap_on_error) ? "" : NULL;
   if (strcmp (argv[0], "leak") == 0)
     return ((flag_sanitize
index 1873b96a028d7326540b48ac9829a28ed58e7c24..3c214f09701f7f39d6cc96318d80a232809b6421 100644 (file)
@@ -1461,6 +1461,8 @@ common_handle_option (struct gcc_options *opts,
                sizeof "signed-integer-overflow" -1 },
              { "bool", SANITIZE_BOOL, sizeof "bool" - 1 },
              { "enum", SANITIZE_ENUM, sizeof "enum" - 1 },
+             { "float-divide-by-zero", SANITIZE_FLOAT_DIVIDE,
+               sizeof "float-divide-by-zero" - 1 },
              { NULL, 0, 0 }
            };
            const char *comma;
index de105037daf126c6506bea7be40bebda5dda107e..f07c90a754612647dfd2c9b9467a1d1385e9c759 100644 (file)
@@ -1,3 +1,8 @@
+2014-04-30  Marek Polacek  <polacek@redhat.com>
+
+       * c-c++-common/ubsan/div-by-zero-5.c: Fix formatting.
+       * c-c++-common/ubsan/float-div-by-zero-1.c: New test.
+
 2014-04-30  Marek Polacek  <polacek@redhat.com>
 
        PR c/60139
index 7a28bacd14ba743cf070fa1c8e7f3f1f73bad753..bb391c5b36df0f2bdc863ff149295e462ae633e9 100644 (file)
@@ -1,4 +1,4 @@
-/* { dg-do compile} */
+/* { dg-do compile } */
 /* { dg-options "-fsanitize=integer-divide-by-zero" } */
 
 void
diff --git a/gcc/testsuite/c-c++-common/ubsan/float-div-by-zero-1.c b/gcc/testsuite/c-c++-common/ubsan/float-div-by-zero-1.c
new file mode 100644 (file)
index 0000000..2271ea9
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=float-divide-by-zero" } */
+
+int
+main (void)
+{
+  volatile float a = 1.3f;
+  volatile double b = 0.0;
+  volatile int c = 4;
+  volatile float res;
+
+  res = a / b;
+  res = a / 0.0;
+  res = 2.7f / b;
+  res = 3.6 / (b = 0.0, b);
+  res = c / b;
+  res = b / c;
+
+  return 0;
+}
+
+/* { dg-output "division by zero\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*" } */
This page took 0.10008 seconds and 5 git commands to generate.