https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77390
Bug ID: 77390 Summary: generates INDIRECT_REF of void type Product: gcc Version: 6.2.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org Target Milestone: --- At trans-expr.c:5523 we have if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS) { /* The derived type is passed to gfc_deallocate_alloc_comp. Therefore, class actuals can handled correctly but derived types passed to class formals need the _data component. */ tmp = gfc_class_data_get (tmp); if (!CLASS_DATA (fsym)->attr.dimension) tmp = build_fold_indirect_ref_loc (input_location, tmp); where the build_fold_indirect_ref_loc, for the testcase gfortran.dg/submodule_6.f08 at least ends up building an INDIRECT_REF of void type as tmp is a generic pointer (void *): (gdb) p debug_tree (tmp) <component_ref 0x7ffff669b360 type <pointer_type 0x7ffff68a02a0 type <void_type 0x7ffff68a0150 void VOID align 8 symtab 0 alias set -1 canonical type 0x7ffff68a0150 pointer_to_this <pointer_type 0x7ffff68a02a0>> public unsigned DI size <integer_cst 0x7ffff6887bb8 constant 64> unit size <integer_cst 0x7ffff6887bd0 constant 8> align 64 symtab 0 alias set -1 canonical type 0x7ffff68a02a0 pointer_to_this <pointer_type 0x7ffff68a6a80>> arg 0 <indirect_ref 0x7ffff6695c60 type <record_type 0x7ffff6696000 __class__STAR_t type_4 BLK the resulting INDIRECT_REF: <indirect_ref 0x7ffff6695c80 type <void_type 0x7ffff68a0150 void VOID align 8 symtab 0 alias set -1 canonical type 0x7ffff68a0150 pointer_to_this <pointer_type 0x7ffff68a02a0>> arg 0 <component_ref 0x7ffff669b360 type <pointer_type 0x7ffff68a02a0 type <void_type 0x7ffff68a0150 void> public unsigned DI this indirect ref is then further sub-setted by COMPONENT_REFs which means the FE knows the record type it intends to use here. This confuses the middle-end quite a bit and I intend to add checking that this doesn't happen. The following should catch this at the root (the ! type because I don't know whether we're lazily setting type anywhere) Index: gcc/tree.c =================================================================== --- gcc/tree.c (revision 239773) +++ gcc/tree.c (working copy) @@ -4405,6 +4407,7 @@ build1_stat (enum tree_code code, tree t /* Whether a dereference is readonly has nothing to do with whether its operand is readonly. */ TREE_READONLY (t) = 0; + gcc_assert (! type || ! VOID_TYPE_P (type)); break; case ADDR_EXPR: