* tree.h (DECIMAL_FLOAT_TYPE_P): New.
authorjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Jun 2006 21:17:53 +0000 (21:17 +0000)
committerjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Jun 2006 21:17:53 +0000 (21:17 +0000)
* c-typeck.c (c_common_type): Disallow operations on decimal float
types and other float types.
* convert.c (convert_to_real): Don't ignore conversions involving
decimal float types.

testsuite:
* gcc.dg/dfp/usual-arith-conv-bad.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114951 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-typeck.c
gcc/convert.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c [new file with mode: 0644]
gcc/tree.h

index 508ee05..e6b2d20 100644 (file)
@@ -1,3 +1,11 @@
+2006-06-23  Janis Johnson  <janis187@us.ibm.com>
+
+       * tree.h (DECIMAL_FLOAT_TYPE_P): New.
+       * c-typeck.c (c_common_type): Disallow operations on decimal float
+       types and other float types.
+       * convert.c (convert_to_real): Don't ignore conversions involving
+       decimal float types.
+
 2006-06-23  Olivier Hainque  <hainque@adacore.com>
 
        * tree.c (max_int_size_in_bytes): New function, inspired from
index c2f6223..c32ce95 100644 (file)
@@ -596,6 +596,29 @@ c_common_type (tree t1, tree t2)
   gcc_assert (code2 == VECTOR_TYPE || code2 == COMPLEX_TYPE
              || code2 == REAL_TYPE || code2 == INTEGER_TYPE);
 
+  /* When one operand is a decimal float type, the other operand cannot be
+     a generic float type or a complex type.  We also disallow vector types
+     here.  */
+  if ((DECIMAL_FLOAT_TYPE_P (t1) || DECIMAL_FLOAT_TYPE_P (t2))
+      && !(DECIMAL_FLOAT_TYPE_P (t1) && DECIMAL_FLOAT_TYPE_P (t2)))
+    {
+      if (code1 == VECTOR_TYPE || code2 == VECTOR_TYPE)
+       {
+         error ("can%'t mix operands of decimal float and vector types");
+         return error_mark_node;
+       }
+      if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
+       {
+         error ("can%'t mix operands of decimal float and complex types");
+         return error_mark_node;
+       }
+      if (code1 == REAL_TYPE && code2 == REAL_TYPE)
+       {
+         error ("can%'t mix operands of decimal float and other float types");
+         return error_mark_node;
+       }
+    }
+
   /* If one type is a vector type, return that type.  (How the usual
      arithmetic conversions apply to the vector types extension is not
      precisely specified.)  */
index 9797704..ab780d8 100644 (file)
@@ -315,8 +315,12 @@ convert_to_real (tree type, tree expr)
   switch (TREE_CODE (TREE_TYPE (expr)))
     {
     case REAL_TYPE:
-      return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
-                    type, expr);
+      /* Ignore the conversion if we don't need to store intermediate
+        results and neither type is a decimal float.  */
+      return build1 ((flag_float_store
+                    || DECIMAL_FLOAT_TYPE_P (type)
+                    || DECIMAL_FLOAT_TYPE_P (itype))
+                    ? CONVERT_EXPR : NOP_EXPR, type, expr);
 
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
index 3cb9151..615ef9d 100644 (file)
@@ -1,3 +1,7 @@
+2006-06-23  Janis Johnson  <janis187@us.ibm.com>
+
+       * gcc.dg/dfp/usual-arith-conv-bad.c: New test.
+
 2006-06-23  Steven G. Kargl  <kargls@comcast.net>
 
        PR fortran/27981
diff --git a/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c
new file mode 100644 (file)
index 0000000..e4033ca
--- /dev/null
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+/* N1150 5.4: Usual arithmetic conversions.
+   C99 6.3.1.8[1] (New).
+
+   Test arithmetic operators between decimal float types and generic
+   float types, which are not allowed.  */
+
+extern _Decimal32 d32a, d32b;
+extern _Decimal64 d64a, d64b;
+extern _Decimal128 d128a, d128b;
+extern float f;
+extern double d;
+extern long double ld;
+
+extern signed int __attribute__ ((vector_size (16))) vi;
+
+extern _Complex float cf;
+extern _Complex double cd;
+extern _Complex long double cld;
+extern _Complex int ci;
+
+void
+foo (void)
+{
+  /* Mixed operations with decimal and generic float operands.  */
+  d32a = d32b + f;     /* { dg-error "" "error.*mix operands of decimal float" } */
+  d32a = f * d32b;     /* { dg-error "" "error.* mix operands of decimal float" } */
+  d32a *= f;           /* { dg-error "" "error.* mix operands of decimal float" } */
+  f += d32b;           /* { dg-error "" "error.* mix operands of decimal float" } */
+  d64a = d32a + d;     /* { dg-error "" "error.* mix operands of decimal float" } */
+  d64a = d * d128a;    /* { dg-error "" "error.* mix operands of decimal float" } */
+  d64a -= d;           /* { dg-error "" "error.* mix operands of decimal float" } */
+  d128a = ld * d128b;  /* { dg-error "" "error.* mix operands of decimal float" } */
+  d128a = d64b + d;    /* { dg-error "" "error.* mix operands of decimal float" } */
+  d128a *= f;          /* { dg-error "" "error.* mix operands of decimal float" } */
+
+  /* Mixed operations with decimal float and a vector type.  */
+  d64a = d64b + vi;    /* { dg-error "" "error.* mix operands of decimal float" } */
+  d32a *= vi;          /* { dg-error "" "error.* mix operands of decimal float" } */
+  d128a = vi - d128b;  /* { dg-error "" "error.* mix operands of decimal float" } */
+
+  /* Mixed operations with decimal float and Complex types.  */
+  d32a += ci;          /* { dg-error "" "error.* mix operands of decimal float" } */
+  d64a = ci * d32a;    /* { dg-error "" "error.* mix operands of decimal float" } */
+  cd = d64a * cd;      /* { dg-error "" "error.* mix operands of decimal float" } */
+  d128b = cld * d128b; /* { dg-error "" "error.* mix operands of decimal float" } */
+  d32a = cf * d32b;    /* { dg-error "" "error.* mix operands of decimal float" } */
+}
index 6d8ad6a..06e6a96 100644 (file)
@@ -966,6 +966,11 @@ extern void omp_clause_range_check_failed (const tree, const char *, int,
         || TREE_CODE (TYPE) == VECTOR_TYPE)    \
        && SCALAR_FLOAT_TYPE_P (TREE_TYPE (TYPE))))
 
+/* Nonzero if TYPE represents a decimal floating-point type.  */
+#define DECIMAL_FLOAT_TYPE_P(TYPE)             \
+  (SCALAR_FLOAT_TYPE_P (TYPE)                  \
+   && DECIMAL_FLOAT_MODE_P (TYPE_MODE (TYPE)))
+
 /* Nonzero if TYPE represents an aggregate (multi-component) type.
    Keep these checks in ascending code order.  */