aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-convert.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-01-06 11:37:02 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2011-01-06 11:37:02 +0100
commitdfe776dd95beeff5e8d5bcd53d07f8c62ae69999 (patch)
treee01fb2e7447c61db75f8096bc82cb4f7c48a43d8 /gcc/c-convert.c
parent4192922c749ba0e0ca94b734ccabca8245520f9d (diff)
downloadgcc-dfe776dd95beeff5e8d5bcd53d07f8c62ae69999.zip
gcc-dfe776dd95beeff5e8d5bcd53d07f8c62ae69999.tar.gz
gcc-dfe776dd95beeff5e8d5bcd53d07f8c62ae69999.tar.bz2
re PR c/47150 (ICE in gimplify_expr at gimplify.c)
PR c/47150 * c-convert.c (convert): When converting a complex expression other than COMPLEX_EXPR to a different complex type, ensure c_save_expr is called instead of save_expr, unless in_late_binary_op. * c-typeck.c (convert_for_assignment): Set in_late_binary_op also when converting COMPLEX_TYPE. * gcc.c-torture/compile/pr47150.c: New test. From-SVN: r168537
Diffstat (limited to 'gcc/c-convert.c')
-rw-r--r--gcc/c-convert.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/gcc/c-convert.c b/gcc/c-convert.c
index f67aecf..f4583c5 100644
--- a/gcc/c-convert.c
+++ b/gcc/c-convert.c
@@ -130,6 +130,32 @@ convert (tree type, tree expr)
goto maybe_fold;
case COMPLEX_TYPE:
+ /* If converting from COMPLEX_TYPE to a different COMPLEX_TYPE
+ and e is not COMPLEX_EXPR, convert_to_complex uses save_expr,
+ but for the C FE c_save_expr needs to be called instead. */
+ if (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE)
+ {
+ tree subtype = TREE_TYPE (type);
+ tree elt_type = TREE_TYPE (TREE_TYPE (e));
+
+ if (TYPE_MAIN_VARIANT (elt_type) != TYPE_MAIN_VARIANT (subtype)
+ && TREE_CODE (e) != COMPLEX_EXPR)
+ {
+ if (in_late_binary_op)
+ e = save_expr (e);
+ else
+ e = c_save_expr (e);
+ ret
+ = fold_build2 (COMPLEX_EXPR, type,
+ convert (subtype,
+ fold_build1 (REALPART_EXPR,
+ elt_type, e)),
+ convert (subtype,
+ fold_build1 (IMAGPART_EXPR,
+ elt_type, e)));
+ goto maybe_fold;
+ }
+ }
ret = convert_to_complex (type, e);
goto maybe_fold;