Another issue with default initialization (used for testing only). Affects versions 5, 6 and 7, at -Og, -Os, -O1 or higher. $ cat z1.f90 program p bind(c) :: x call s(x) end $ /home/gst/gcc/gcc-7-20160918-oyd/bin/gfortran -O2 -finit-real=zero -c z1.f90 z1.f90:4:0: end internal compiler error: in ctor_for_folding, at varpool.c:419 0xf18192 ctor_for_folding(tree_node*) ../../gcc/varpool.c:419 0xdd4842 fully_constant_vn_reference_p(vn_reference_s*) ../../gcc/tree-ssa-sccvn.c:1377 0xdd998f vn_reference_lookup(tree_node*, tree_node*, vn_lookup_kind, vn_reference_s**, bool) ../../gcc/tree-ssa-sccvn.c:2431 0xddcec6 visit_reference_op_store ../../gcc/tree-ssa-sccvn.c:3583 0xddcec6 visit_use ../../gcc/tree-ssa-sccvn.c:3831 0xddeb6b process_scc ../../gcc/tree-ssa-sccvn.c:4073 0xddeb6b extract_and_process_scc_for_name ../../gcc/tree-ssa-sccvn.c:4160 0xddeb6b DFS ../../gcc/tree-ssa-sccvn.c:4212 0xddf3dd sccvn_dom_walker::before_dom_children(basic_block_def*) ../../gcc/tree-ssa-sccvn.c:4678 0x1299da2 dom_walker::walk(basic_block_def*) ../../gcc/domwalk.c:265 0xde01f2 run_scc_vn(vn_lookup_kind) ../../gcc/tree-ssa-sccvn.c:4789 0xdb0b54 execute ../../gcc/tree-ssa-pre.c:5126
Confirmed.
415 /* Do not care about automatic variables. Those are never initialized 416 anyway, because gimplifier exapnds the code. */ 417 if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) 418 { 419 gcc_assert (!TREE_PUBLIC (decl)); 420 return error_mark_node; 421 } 422 423 gcc_assert (TREE_CODE (decl) == VAR_DECL); (gdb) p debug_tree (decl) <var_decl 0x7ffff7ff6990 x type <real_type 0x7ffff68a0540 real(kind=4) SF size <integer_cst 0x7ffff6887df8 constant 32> unit size <integer_cst 0x7ffff6887e10 constant 4> align 32 symtab 0 alias set -1 canonical type 0x7ffff68a0540 precision 32 pointer_to_this <pointer_type 0x7ffff68a0a80>> addressable used public common SF file t.f90 line 2 col 0 size <integer_cst 0x7ffff6887df8 32> unit size <integer_cst 0x7ffff6887e10 4> align 32 context <function_decl 0x7ffff6a5de00 p>> $1 = void so we have TREE_PUBLIC && DECL_COMMON, not sure if DECL_COMMON is supposed to have TREE_STATIC set. Honza? Thus looks like a FE issue to me. The bougs flags appear also without -finit-real=zero but we don't ICE (we optimize away the var I guess).
Indeed. Not sure what bind(c) should mean on automatic variables. Shall it force them to be non-automatic (SAVEd), or not? If not, I bet we want something like the following. Plus the question is if DECL_COMMON should be added for initialized variables, in C it is just uninitialized non-automatic variables that are common. Plus, shouldn't it also depend on -fcommon switch? --- gcc/fortran/trans-decl.c.jj 2016-10-31 13:28:11.000000000 +0100 +++ gcc/fortran/trans-decl.c 2016-11-09 17:50:33.695988616 +0100 @@ -588,26 +588,6 @@ gfc_finish_var_decl (tree decl, gfc_symb if (sym->attr.cray_pointee) return; - if(sym->attr.is_bind_c == 1 && sym->binding_label) - { - /* We need to put variables that are bind(c) into the common - segment of the object file, because this is what C would do. - gfortran would typically put them in either the BSS or - initialized data segments, and only mark them as common if - they were part of common blocks. However, if they are not put - into common space, then C cannot initialize global Fortran - variables that it interoperates with and the draft says that - either Fortran or C should be able to initialize it (but not - both, of course.) (J3/04-007, section 15.3). */ - TREE_PUBLIC(decl) = 1; - DECL_COMMON(decl) = 1; - if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used) - { - DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; - DECL_VISIBILITY_SPECIFIED (decl) = true; - } - } - /* If a variable is USE associated, it's always external. */ if (sym->attr.use_assoc || sym->attr.used_in_submodule) { @@ -635,10 +615,10 @@ gfc_finish_var_decl (tree decl, gfc_symb initialized variables are SAVE_IMPLICIT and explicitly saved are SAVE_EXPLICIT. */ if (!sym->attr.use_assoc - && (sym->attr.save != SAVE_NONE || sym->attr.data - || (sym->value && sym->ns->proc_name->attr.is_main_program) - || (flag_coarray == GFC_FCOARRAY_LIB - && sym->attr.codimension && !sym->attr.allocatable))) + && (sym->attr.save != SAVE_NONE || sym->attr.data + || (sym->value && sym->ns->proc_name->attr.is_main_program) + || (flag_coarray == GFC_FCOARRAY_LIB + && sym->attr.codimension && !sym->attr.allocatable))) TREE_STATIC (decl) = 1; /* If derived-type variables with DTIO procedures are not made static @@ -708,6 +688,27 @@ gfc_finish_var_decl (tree decl, gfc_symb } } + if ((sym->attr.is_bind_c == 1 && sym->binding_label) + && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) + { + /* We need to put variables that are bind(c) into the common + segment of the object file, because this is what C would do. + gfortran would typically put them in either the BSS or + initialized data segments, and only mark them as common if + they were part of common blocks. However, if they are not put + into common space, then C cannot initialize global Fortran + variables that it interoperates with and the draft says that + either Fortran or C should be able to initialize it (but not + both, of course.) (J3/04-007, section 15.3). */ + TREE_PUBLIC (decl) = 1; + DECL_COMMON (decl) = 1; + if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used) + { + DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; + DECL_VISIBILITY_SPECIFIED (decl) = true; + } + } + /* Handle threadprivate variables. */ if (sym->attr.threadprivate && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
This is now correctly rejected: ig25@flaemmli:/tmp> cat d.f90 program p bind(c) :: x call s(x) end ig25@flaemmli:/tmp> gfortran d.f90 d.f90:2:15: bind(c) :: x 1 Error: Variable ‘x’ at (1) cannot be BIND(C) because it is neither a COMMON block nor declared at the module level scope Closing.