diff options
author | janis <janis@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-23 21:17:53 +0000 |
---|---|---|
committer | janis <janis@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-23 21:17:53 +0000 |
commit | e5d0ba064e4b160d9a8821adbabbab2ef44da7c2 (patch) | |
tree | 37c4db6e4704c909e6788fed55acb58ba4c4c1a2 | |
parent | b0cb894aa9cb7df0bf2de25acd96748e30652f43 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/c-typeck.c | 23 | ||||
-rw-r--r-- | gcc/convert.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c | 50 | ||||
-rw-r--r-- | gcc/tree.h | 5 |
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. */ |