]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR sanitizer/69099 (ICE when compiling gcc.dg/atomic/c11-atomic-exec-2.c with...
authorMarek Polacek <polacek@redhat.com>
Wed, 6 Jan 2016 10:24:15 +0000 (10:24 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 6 Jan 2016 10:24:15 +0000 (10:24 +0000)
PR sanitizer/69099
* c-convert.c (convert) [INTEGER_TYPE]: Drop ARG.  Don't pass ARG to
ubsan_instrument_float_cast.  Fold EXPR.  Use NULL_TREE instead of
NULL.

* convert.c (convert_to_integer_1): Adjust call to
ubsan_instrument_float_cast.  Use NULL_TREE instead of NULL.
* ubsan.c (ubsan_instrument_float_cast): Drop the ARG parameter.  Use
EXPR instead of ARG.
* ubsan.h (ubsan_instrument_float_cast): Adjust declaration.

* gcc.dg/ubsan/float-cast-overflow-atomic.c: New test.

From-SVN: r232099

gcc/ChangeLog
gcc/c/ChangeLog
gcc/c/c-convert.c
gcc/convert.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ubsan/float-cast-overflow-atomic.c [new file with mode: 0644]
gcc/ubsan.c
gcc/ubsan.h

index d909693f5c27370ea02b4a66461a9bf5f3022694..e5b31af4893c0c56e21cefdddbabebaa1660456e 100644 (file)
@@ -1,3 +1,12 @@
+2016-01-06  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/69099
+       * convert.c (convert_to_integer_1): Adjust call to
+       ubsan_instrument_float_cast.  Use NULL_TREE instead of NULL.
+       * ubsan.c (ubsan_instrument_float_cast): Drop the ARG parameter.  Use
+       EXPR instead of ARG.
+       * ubsan.h (ubsan_instrument_float_cast): Adjust declaration.
+
 2016-01-05  Sandra Loosemore <sandra@codesourcery.com>
 
        PR 1078
index ccb73469d166edd1149cb5093343f189ec88b95d..379f00219f4adf3c98da4c4d4e013f15c6c757b9 100644 (file)
@@ -1,3 +1,10 @@
+2016-01-06  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/69099
+       * c-convert.c (convert) [INTEGER_TYPE]: Drop ARG.  Don't pass ARG to
+       ubsan_instrument_float_cast.  Fold EXPR.  Use NULL_TREE instead of
+       NULL.
+
 2016-01-04  Jakub Jelinek  <jakub@redhat.com>
 
        Update copyright years.
index 5ee52eb46d343b03014072dc5b9f014215012cc4..4167c3461f3fa55b19449da6ccfdc0510ffbb005 100644 (file)
@@ -111,20 +111,16 @@ convert (tree type, tree expr)
          && COMPLETE_TYPE_P (type)
          && do_ubsan_in_current_function ())
        {
-         tree arg;
          if (in_late_binary_op)
-           {
-             expr = save_expr (expr);
-             arg = expr;
-           }
+           expr = save_expr (expr);
          else
            {
              expr = c_save_expr (expr);
-             arg = c_fully_fold (expr, false, NULL);
+             expr = c_fully_fold (expr, false, NULL);
            }
-         tree check = ubsan_instrument_float_cast (loc, type, expr, arg);
+         tree check = ubsan_instrument_float_cast (loc, type, expr);
          expr = fold_build1 (FIX_TRUNC_EXPR, type, expr);
-         if (check == NULL)
+         if (check == NULL_TREE)
            return expr;
          return fold_build2 (COMPOUND_EXPR, TREE_TYPE (expr), check, expr);
        }
index 4b1e1f17760f991d08f310fcdca5c711693983e1..dd7d818b67bf1012db80dd37a8ceecec15232012 100644 (file)
@@ -920,9 +920,9 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
          && do_ubsan_in_current_function ())
        {
          expr = save_expr (expr);
-         tree check = ubsan_instrument_float_cast (loc, type, expr, expr);
+         tree check = ubsan_instrument_float_cast (loc, type, expr);
          expr = build1 (FIX_TRUNC_EXPR, type, expr);
-         if (check == NULL)
+         if (check == NULL_TREE)
            return expr;
          return maybe_fold_build2_loc (dofold, loc, COMPOUND_EXPR,
                                        TREE_TYPE (expr), check, expr);
index 53219fea924808d9da48acbedff4c49e4f4b4d4c..85d630b0b7f28e345188c8988b202375fff160b0 100644 (file)
@@ -1,3 +1,8 @@
+2016-01-06  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/69099
+       * gcc.dg/ubsan/float-cast-overflow-atomic.c: New test.
+
 2016-01-05  Marek Polacek  <polacek@redhat.com>
 
        PR c/69104
diff --git a/gcc/testsuite/gcc.dg/ubsan/float-cast-overflow-atomic.c b/gcc/testsuite/gcc.dg/ubsan/float-cast-overflow-atomic.c
new file mode 100644 (file)
index 0000000..0a4fa01
--- /dev/null
@@ -0,0 +1,171 @@
+/* PR sanitizer/69099 */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors -fsanitize=float-cast-overflow" } */
+/* This is gcc.dg/atomic/c11-atomic-exec-2.c.  */
+
+extern void abort (void);
+extern void exit (int);
+
+#define CMPLX(X, Y) __builtin_complex ((X), (Y))
+
+#define TEST_COMPOUND(TYPE, LHSVAL, RHSVAL, OP)                                \
+  do                                                                   \
+    {                                                                  \
+      static volatile _Atomic (TYPE) a = (TYPE) (LHSVAL);              \
+      if ((a OP##= (RHSVAL)) != (TYPE) ((TYPE) (LHSVAL) OP (RHSVAL)))  \
+       abort ();                                                       \
+      if (a != (TYPE) ((TYPE) (LHSVAL) OP (RHSVAL)))                   \
+       abort ();                                                       \
+    }                                                                  \
+  while (0)
+
+#define TEST_COMPOUND_ARITH(LHSVAL, RHSVAL, OP)                                \
+  do                                                                   \
+    {                                                                  \
+      TEST_COMPOUND (_Bool, (LHSVAL), (RHSVAL), OP);                   \
+      TEST_COMPOUND (char, (LHSVAL), (RHSVAL), OP);                    \
+      TEST_COMPOUND (signed char, (LHSVAL), (RHSVAL), OP);             \
+      TEST_COMPOUND (unsigned char, (LHSVAL), (RHSVAL), OP);           \
+      TEST_COMPOUND (signed short, (LHSVAL), (RHSVAL), OP);            \
+      TEST_COMPOUND (unsigned short, (LHSVAL), (RHSVAL), OP);          \
+      TEST_COMPOUND (signed int, (LHSVAL), (RHSVAL), OP);              \
+      TEST_COMPOUND (unsigned int, (LHSVAL), (RHSVAL), OP);            \
+      TEST_COMPOUND (signed long, (LHSVAL), (RHSVAL), OP);             \
+      TEST_COMPOUND (unsigned long, (LHSVAL), (RHSVAL), OP);           \
+      TEST_COMPOUND (signed long long, (LHSVAL), (RHSVAL), OP);                \
+      TEST_COMPOUND (unsigned long long, (LHSVAL), (RHSVAL), OP);      \
+      TEST_COMPOUND (float, (LHSVAL), (RHSVAL), OP);                   \
+      TEST_COMPOUND (double, (LHSVAL), (RHSVAL), OP);                  \
+      TEST_COMPOUND (long double, (LHSVAL), (RHSVAL), OP);             \
+      TEST_COMPOUND (_Complex float, (LHSVAL), (RHSVAL), OP);          \
+      TEST_COMPOUND (_Complex double, (LHSVAL), (RHSVAL), OP);         \
+      TEST_COMPOUND (_Complex long double, (LHSVAL), (RHSVAL), OP);    \
+    }                                                                  \
+  while (0)
+
+#define TEST_COMPOUND_INT(LHSVAL, RHSVAL, OP)                          \
+  do                                                                   \
+    {                                                                  \
+      TEST_COMPOUND (_Bool, (LHSVAL), (RHSVAL), OP);                   \
+      TEST_COMPOUND (char, (LHSVAL), (RHSVAL), OP);                    \
+      TEST_COMPOUND (signed char, (LHSVAL), (RHSVAL), OP);             \
+      TEST_COMPOUND (unsigned char, (LHSVAL), (RHSVAL), OP);           \
+      TEST_COMPOUND (signed short, (LHSVAL), (RHSVAL), OP);            \
+      TEST_COMPOUND (unsigned short, (LHSVAL), (RHSVAL), OP);          \
+      TEST_COMPOUND (signed int, (LHSVAL), (RHSVAL), OP);              \
+      TEST_COMPOUND (unsigned int, (LHSVAL), (RHSVAL), OP);            \
+      TEST_COMPOUND (signed long, (LHSVAL), (RHSVAL), OP);             \
+      TEST_COMPOUND (unsigned long, (LHSVAL), (RHSVAL), OP);           \
+      TEST_COMPOUND (signed long long, (LHSVAL), (RHSVAL), OP);                \
+      TEST_COMPOUND (unsigned long long, (LHSVAL), (RHSVAL), OP);      \
+    }                                                                  \
+  while (0)
+
+static void
+test_mult (void)
+{
+  TEST_COMPOUND_ARITH (1, 2, *);
+  TEST_COMPOUND_ARITH (-3, 5, *);
+  TEST_COMPOUND_ARITH (-7, -20, *);
+  TEST_COMPOUND_ARITH (1.25, 3.5, *);
+  TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), CMPLX (3.5, 4.5), *);
+  TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), 2, *);
+}
+
+static void
+test_div (void)
+{
+  TEST_COMPOUND_ARITH (1, 2, /);
+  TEST_COMPOUND_ARITH (-6, 3, /);
+  TEST_COMPOUND_ARITH (-70, -10, /);
+  TEST_COMPOUND_ARITH (1.25, 2.5, /);
+  TEST_COMPOUND_ARITH (CMPLX (1.0, 1.0), CMPLX (0.5, 0.5), /);
+  TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), 2, /);
+}
+
+static void
+test_mod (void)
+{
+  TEST_COMPOUND_INT (1, 2, %);
+  TEST_COMPOUND_INT (-3, 5, %);
+  TEST_COMPOUND_INT (-7, -2, %);
+}
+
+static void
+test_plus (void)
+{
+  TEST_COMPOUND_ARITH (1, 2, +);
+  TEST_COMPOUND_ARITH (-3, 5, +);
+  TEST_COMPOUND_ARITH (-7, -20, +);
+  TEST_COMPOUND_ARITH (1.25, 3.5, +);
+  TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), CMPLX (3.5, 4.5), +);
+  TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), 2, +);
+  static int ia[2];
+  TEST_COMPOUND (int *, &ia[1], 1, +);
+  TEST_COMPOUND (int *, &ia[1], -1, +);
+}
+
+static void
+test_minus (void)
+{
+  TEST_COMPOUND_ARITH (1, 2, -);
+  TEST_COMPOUND_ARITH (-3, 5, -);
+  TEST_COMPOUND_ARITH (-7, -20, -);
+  TEST_COMPOUND_ARITH (3.5, 1.25, -);
+  TEST_COMPOUND_ARITH (CMPLX (3.5, 4.5), CMPLX (1.5, 2.5), -);
+  TEST_COMPOUND_ARITH (CMPLX (3.5, 2.5), 2, -);
+  static int ia[2];
+  TEST_COMPOUND (int *, &ia[1], 1, -);
+  TEST_COMPOUND (int *, &ia[1], -1, -);
+}
+
+static void
+test_lshift (void)
+{
+  TEST_COMPOUND_INT (1, 7, <<);
+  TEST_COMPOUND_INT (15, 3, <<);
+}
+
+static void
+test_rshift (void)
+{
+  TEST_COMPOUND_INT (1, 1, >>);
+  TEST_COMPOUND_INT (127, 4, >>);
+}
+
+static void
+test_and (void)
+{
+  TEST_COMPOUND_INT (0x1234, 0x7856, &);
+  TEST_COMPOUND_INT (-1, 0x12345678, &);
+}
+
+static void
+test_xor (void)
+{
+  TEST_COMPOUND_INT (0x1234, 0x7856, ^);
+  TEST_COMPOUND_INT (-1, 0x12345678, ^);
+}
+
+static void
+test_or (void)
+{
+  TEST_COMPOUND_INT (0x1234, 0x7856, |);
+  TEST_COMPOUND_INT (-12345, 0x12345678, |);
+}
+
+int
+main (void)
+{
+  test_mult ();
+  test_div ();
+  test_mod ();
+  test_plus ();
+  test_minus ();
+  test_lshift ();
+  test_rshift ();
+  test_and ();
+  test_xor ();
+  test_or ();
+  exit (0);
+}
index e5b49b2b4225c29960fd51519175b0fdc5040d06..d3fbfd177e6896443f9f6d20e0087727bf24e4f9 100644 (file)
@@ -1478,18 +1478,18 @@ ubsan_use_new_style_p (location_t loc)
 }
 
 /* Instrument float point-to-integer conversion.  TYPE is an integer type of
-   destination, EXPR is floating-point expression.  ARG is what to pass
-   the libubsan call as value, often EXPR itself.  */
+   destination, EXPR is floating-point expression.  */
 
 tree
-ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
+ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
 {
   tree expr_type = TREE_TYPE (expr);
   tree t, tt, fn, min, max;
   machine_mode mode = TYPE_MODE (expr_type);
   int prec = TYPE_PRECISION (type);
   bool uns_p = TYPE_UNSIGNED (type);
-  if (!loc) loc = input_location;
+  if (loc == UNKNOWN_LOCATION)
+    loc = input_location;
 
   /* Float to integer conversion first truncates toward zero, so
      even signed char c = 127.875f; is not problematic.
@@ -1609,7 +1609,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
       fn = builtin_decl_explicit (bcode);
       fn = build_call_expr_loc (loc, fn, 2,
                                build_fold_addr_expr_loc (loc, data),
-                               ubsan_encode_value (arg, false));
+                               ubsan_encode_value (expr, false));
     }
 
   return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
index d272d62adeb1ec90e6ababa09b5c94c9ab9b909b..c66d0afab884db3716545c65cbc23c0caf88b222 100644 (file)
@@ -53,7 +53,7 @@ extern tree ubsan_type_descriptor (tree, enum ubsan_print_style = UBSAN_PRINT_NO
 extern tree ubsan_encode_value (tree, bool = false);
 extern bool is_ubsan_builtin_p (tree);
 extern tree ubsan_build_overflow_builtin (tree_code, location_t, tree, tree, tree);
-extern tree ubsan_instrument_float_cast (location_t, tree, tree, tree);
+extern tree ubsan_instrument_float_cast (location_t, tree, tree);
 extern tree ubsan_get_source_location_type (void);
 
 #endif  /* GCC_UBSAN_H  */