From 35f1e9f475d9be3da62e99c2891e0abdbfd444a4 Mon Sep 17 00:00:00 2001 From: Richard Guenther <rguenther@suse.de> Date: Fri, 16 Oct 2009 14:23:22 +0000 Subject: [PATCH] re PR lto/41715 (VIEW_CONVERT_EXPR use for mismatched prevailing decl replacement doesn't work) 2009-10-16 Richard Guenther <rguenther@suse.de> PR lto/41715 * lto-streamer-in.c (lto_input_tree_ref): Revert last change. (maybe_fixup_handled_component): New function. (input_gimple_stmt): Fixup mismatched decl replacements. lto/ * lto.c (lto_fixup_tree): Revert last change. * gfortran.dg/lto/20091015-1_0.f: New testcase. * gfortran.dg/lto/20091015-1_1.f: Likewise. * gfortran.dg/lto/20091015-1_2.f: Likewise. From-SVN: r152903 --- gcc/ChangeLog | 7 + gcc/lto-streamer-in.c | 137 +++++++++++++++++-- gcc/lto/ChangeLog | 5 + gcc/lto/lto.c | 10 +- gcc/testsuite/ChangeLog | 7 + gcc/testsuite/gfortran.dg/lto/20091015-1_0.f | 8 ++ gcc/testsuite/gfortran.dg/lto/20091015-1_1.f | 4 + gcc/testsuite/gfortran.dg/lto/20091015-1_2.f | 5 + 8 files changed, 164 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/lto/20091015-1_0.f create mode 100644 gcc/testsuite/gfortran.dg/lto/20091015-1_1.f create mode 100644 gcc/testsuite/gfortran.dg/lto/20091015-1_2.f diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 13e3e2fc3fed..3377560960aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-10-16 Richard Guenther <rguenther@suse.de> + + PR lto/41715 + * lto-streamer-in.c (lto_input_tree_ref): Revert last change. + (maybe_fixup_handled_component): New function. + (input_gimple_stmt): Fixup mismatched decl replacements. + 2009-10-16 Richard Guenther <rguenther@suse.de> PR lto/41713 diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 14b0c137f185..71faf0f39f65 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -353,16 +353,7 @@ lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in, ix_u = lto_input_uleb128 (ib); result = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u); if (tag == LTO_global_decl_ref) - { - if (TREE_CODE (result) == VIEW_CONVERT_EXPR) - { - tree decl = TREE_OPERAND (result, 0); - varpool_mark_needed_node (varpool_node (decl)); - result = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (result), decl); - } - else - varpool_mark_needed_node (varpool_node (result)); - } + varpool_mark_needed_node (varpool_node (result)); break; default: @@ -877,6 +868,128 @@ input_ssa_names (struct lto_input_block *ib, struct data_in *data_in, } +/* Fixup the reference tree OP for replaced VAR_DECLs with mismatched + types. */ + +static void +maybe_fixup_handled_component (tree op) +{ + tree decl_type; + tree wanted_type; + + while (handled_component_p (TREE_OPERAND (op, 0))) + op = TREE_OPERAND (op, 0); + if (TREE_CODE (TREE_OPERAND (op, 0)) != VAR_DECL) + return; + + decl_type = TREE_TYPE (TREE_OPERAND (op, 0)); + + switch (TREE_CODE (op)) + { + case COMPONENT_REF: + /* The DECL_CONTEXT of the field-decl is the record type we look for. */ + wanted_type = DECL_CONTEXT (TREE_OPERAND (op, 1)); + break; + + case ARRAY_REF: + if (TREE_CODE (decl_type) == ARRAY_TYPE + && (TREE_TYPE (decl_type) == TREE_TYPE (op) + || useless_type_conversion_p (TREE_TYPE (op), + TREE_TYPE (decl_type)))) + return; + /* An unknown size array type should be ok. But we do not + lower the lower bound in all cases - ugh. */ + wanted_type = build_array_type (TREE_TYPE (op), NULL_TREE); + break; + + case ARRAY_RANGE_REF: + if (TREE_CODE (decl_type) == ARRAY_TYPE + && (TREE_TYPE (decl_type) == TREE_TYPE (TREE_TYPE (op)) + || useless_type_conversion_p (TREE_TYPE (TREE_TYPE (op)), + TREE_TYPE (decl_type)))) + return; + /* An unknown size array type should be ok. But we do not + lower the lower bound in all cases - ugh. */ + wanted_type = build_array_type (TREE_TYPE (TREE_TYPE (op)), NULL_TREE); + break; + + case BIT_FIELD_REF: + case VIEW_CONVERT_EXPR: + /* Very nice - nothing to do. */ + return; + + case REALPART_EXPR: + case IMAGPART_EXPR: + if (TREE_CODE (decl_type) == COMPLEX_TYPE + && (TREE_TYPE (decl_type) == TREE_TYPE (op) + || useless_type_conversion_p (TREE_TYPE (op), + TREE_TYPE (decl_type)))) + return; + wanted_type = build_complex_type (TREE_TYPE (op)); + break; + + default: + gcc_unreachable (); + } + + if (!useless_type_conversion_p (wanted_type, decl_type)) + TREE_OPERAND (op, 0) = build1 (VIEW_CONVERT_EXPR, wanted_type, + TREE_OPERAND (op, 0)); +} + +/* Fixup reference tree operands for substituted prevailing decls + with mismatched types in STMT. */ + +static void +maybe_fixup_decls (gimple stmt) +{ + /* We have to fixup replaced decls here in case there were + inter-TU type mismatches. Catch the most common cases + for now - this way we'll get testcases for the rest as + the type verifier will complain. */ + if (gimple_assign_single_p (stmt)) + { + tree lhs = gimple_assign_lhs (stmt); + tree rhs = gimple_assign_rhs1 (stmt); + + /* First catch loads and aggregate copies by adjusting the rhs. */ + if (TREE_CODE (rhs) == VAR_DECL) + { + if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) + gimple_assign_set_rhs1 (stmt, build1 (VIEW_CONVERT_EXPR, + TREE_TYPE (lhs), rhs)); + } + else if (handled_component_p (rhs)) + maybe_fixup_handled_component (rhs); + /* Then catch scalar stores. */ + else if (TREE_CODE (lhs) == VAR_DECL) + { + if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) + gimple_assign_set_lhs (stmt, build1 (VIEW_CONVERT_EXPR, + TREE_TYPE (rhs), lhs)); + } + else if (handled_component_p (lhs)) + maybe_fixup_handled_component (lhs); + } + else if (is_gimple_call (stmt)) + { + tree lhs = gimple_call_lhs (stmt); + + if (lhs && TREE_CODE (lhs) == VAR_DECL) + { + if (!useless_type_conversion_p (TREE_TYPE (lhs), + gimple_call_return_type (stmt))) + gimple_call_set_lhs (stmt, build1 (VIEW_CONVERT_EXPR, + gimple_call_return_type (stmt), + lhs)); + } + else if (lhs && handled_component_p (lhs)) + maybe_fixup_handled_component (lhs); + + /* Arguments, especially for varargs functions will be funny... */ + } +} + /* Read a statement with tag TAG in function FN from block IB using descriptors in DATA_IN. */ @@ -983,6 +1096,10 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, } } + /* Fixup reference tree operands for substituted prevailing decls + with mismatched types. */ + maybe_fixup_decls (stmt); + /* Mark the statement modified so its operand vectors can be filled in. */ gimple_set_modified (stmt, true); diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index e6f3e3931514..938d32cb2ef5 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,8 @@ +2009-10-16 Richard Guenther <rguenther@suse.de> + + PR lto/41715 + * lto.c (lto_fixup_tree): Revert last change. + 2009-10-14 Richard Guenther <rguenther@suse.de> * lto.c (lto_fixup_tree): In case the prevailing decl is not diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index daca784b0bbd..2b674c176aca 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -1530,18 +1530,10 @@ lto_fixup_tree (tree *tp, int *walk_subtrees, void *data) pointer_set_insert (fixup_data->free_list, t); - /* Replace the decl. If it is a not compatible VAR_DECL wrap - it inside a VIEW_CONVERT_EXPR. */ - if (TREE_CODE (*tp) == VAR_DECL - && !useless_type_conversion_p (TREE_TYPE (*tp), - TREE_TYPE (prevailing))) - *tp = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), prevailing); - else - *tp = prevailing; - /* Also replace t with prevailing defintion. We don't want to insert the other defintion in the seen set as we want to replace all instances of it. */ + *tp = prevailing; t = prevailing; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d55be035dfcf..e21a4e217727 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-10-16 Richard Guenther <rguenther@suse.de> + + PR lto/41715 + * gfortran.dg/lto/20091015-1_0.f: New testcase. + * gfortran.dg/lto/20091015-1_1.f: Likewise. + * gfortran.dg/lto/20091015-1_2.f: Likewise. + 2009-10-16 Richard Guenther <rguenther@suse.de> PR lto/41713 diff --git a/gcc/testsuite/gfortran.dg/lto/20091015-1_0.f b/gcc/testsuite/gfortran.dg/lto/20091015-1_0.f new file mode 100644 index 000000000000..f47e1a4ac6cc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/20091015-1_0.f @@ -0,0 +1,8 @@ +! { dg-lto-do link } +! We expect some warnings about mismatched symbol types +! { dg-extra-ld-options "-w" } + + subroutine dalie6s(iqmod6,nz,wx,cor6d) + common/dascr/iscrda(100),rscrri(100),iscrri(100),idao + call daall(iscrda,100,'$$IS ',no,nv) + end diff --git a/gcc/testsuite/gfortran.dg/lto/20091015-1_1.f b/gcc/testsuite/gfortran.dg/lto/20091015-1_1.f new file mode 100644 index 000000000000..7a64ffa67868 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/20091015-1_1.f @@ -0,0 +1,4 @@ + SUBROUTINE DAALL(IC,L,CCC,NO,NV) + COMMON /main1/ eps + END + diff --git a/gcc/testsuite/gfortran.dg/lto/20091015-1_2.f b/gcc/testsuite/gfortran.dg/lto/20091015-1_2.f new file mode 100644 index 000000000000..5bfd02227fa2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/20091015-1_2.f @@ -0,0 +1,5 @@ + program test + common/main1/ eps(2) + dimension cor6d(2,2) + call dalie6s(iqmod6,1,wx,cor6d) + end -- GitLab