summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>2006-06-23 21:17:53 +0000
committerjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>2006-06-23 21:17:53 +0000
commite5d0ba064e4b160d9a8821adbabbab2ef44da7c2 (patch)
tree37c4db6e4704c909e6788fed55acb58ba4c4c1a2
parentb0cb894aa9cb7df0bf2de25acd96748e30652f43 (diff)
downloadgcc-e5d0ba064e4b160d9a8821adbabbab2ef44da7c2.tar.gz
* 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. 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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/c-typeck.c23
-rw-r--r--gcc/convert.c8
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c50
-rw-r--r--gcc/tree.h5
6 files changed, 96 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 508ee05d8c1..e6b2d20cea0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index c2f62231412..c32ce95b99f 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -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.) */
diff --git a/gcc/convert.c b/gcc/convert.c
index 97977040755..ab780d8ebd3 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3cb91517102..615ef9d92b9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..e4033ca50f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c
@@ -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" } */
+}
diff --git a/gcc/tree.h b/gcc/tree.h
index 6d8ad6aac5c..06e6a96b1f9 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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. */