Mercurial > hg > CbC > CbC_gcc
diff gcc/fortran/trans-decl.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/fortran/trans-decl.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/fortran/trans-decl.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Backend function setup - Copyright (C) 2002-2017 Free Software Foundation, Inc. + Copyright (C) 2002-2018 Free Software Foundation, Inc. Contributed by Paul Brook This file is part of GCC. @@ -61,9 +61,6 @@ static GTY(()) tree saved_function_decls; static GTY(()) tree saved_parent_function_decls; -static hash_set<tree> *nonlocal_dummy_decl_pset; -static GTY(()) tree nonlocal_dummy_decls; - /* Holds the variable DECLs that are locals. */ static GTY(()) tree saved_local_decls; @@ -123,7 +120,6 @@ tree gfor_fndecl_ieee_procedure_entry; tree gfor_fndecl_ieee_procedure_exit; - /* Coarray run-time library function decls. */ tree gfor_fndecl_caf_init; tree gfor_fndecl_caf_finalize; @@ -157,6 +153,12 @@ tree gfor_fndecl_caf_failed_images; tree gfor_fndecl_caf_image_status; tree gfor_fndecl_caf_stopped_images; +tree gfor_fndecl_caf_form_team; +tree gfor_fndecl_caf_change_team; +tree gfor_fndecl_caf_end_team; +tree gfor_fndecl_caf_sync_team; +tree gfor_fndecl_caf_get_team; +tree gfor_fndecl_caf_team_number; tree gfor_fndecl_co_broadcast; tree gfor_fndecl_co_max; tree gfor_fndecl_co_min; @@ -209,6 +211,9 @@ tree gfor_fndecl_size0; tree gfor_fndecl_size1; tree gfor_fndecl_iargc; +tree gfor_fndecl_kill; +tree gfor_fndecl_kill_sub; + /* Intrinsic functions implemented in Fortran. */ tree gfor_fndecl_sc_kind; @@ -221,6 +226,8 @@ tree gfor_fndecl_cgemm; tree gfor_fndecl_zgemm; +/* RANDOM_INIT function. */ +tree gfor_fndecl_random_init; static void gfc_add_decl_to_parent_function (tree decl) @@ -603,10 +610,12 @@ function scope. */ if (current_function_decl != NULL_TREE) { - if (sym->ns->proc_name->backend_decl == current_function_decl - || sym->result == sym) + if (sym->ns->proc_name + && (sym->ns->proc_name->backend_decl == current_function_decl + || sym->result == sym)) gfc_add_decl_to_function (decl); - else if (sym->ns->proc_name->attr.flavor == FL_LABEL) + else if (sym->ns->proc_name + && sym->ns->proc_name->attr.flavor == FL_LABEL) /* This is a BLOCK construct. */ add_decl_as_local (decl); else @@ -689,7 +698,8 @@ && CLASS_DATA (sym)->ts.u.derived->attr.has_dtio_procs))) TREE_STATIC (decl) = 1; - if (sym->attr.volatile_) + /* Treat asynchronous variables the same as volatile, for now. */ + if (sym->attr.volatile_ || sym->attr.asynchronous) { TREE_THIS_VOLATILE (decl) = 1; TREE_SIDE_EFFECTS (decl) = 1; @@ -698,7 +708,8 @@ } /* Keep variables larger than max-stack-var-size off stack. */ - if (!sym->ns->proc_name->attr.recursive && !sym->attr.automatic + if (!(sym->ns->proc_name && sym->ns->proc_name->attr.recursive) + && !sym->attr.automatic && INTEGER_CST_P (DECL_SIZE_UNIT (decl)) && !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)) /* Put variable length auto array pointers always into stack. */ @@ -1271,39 +1282,6 @@ return decl; } -/* For symbol SYM with GFC_DECL_SAVED_DESCRIPTOR used in contained - function add a VAR_DECL to the current function with DECL_VALUE_EXPR - pointing to the artificial variable for debug info purposes. */ - -static void -gfc_nonlocal_dummy_array_decl (gfc_symbol *sym) -{ - tree decl, dummy; - - if (! nonlocal_dummy_decl_pset) - nonlocal_dummy_decl_pset = new hash_set<tree>; - - if (nonlocal_dummy_decl_pset->add (sym->backend_decl)) - return; - - dummy = GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl); - decl = build_decl (input_location, VAR_DECL, DECL_NAME (dummy), - TREE_TYPE (sym->backend_decl)); - DECL_ARTIFICIAL (decl) = 0; - TREE_USED (decl) = 1; - TREE_PUBLIC (decl) = 0; - TREE_STATIC (decl) = 0; - DECL_EXTERNAL (decl) = 0; - if (DECL_BY_REFERENCE (dummy)) - DECL_BY_REFERENCE (decl) = 1; - DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (sym->backend_decl); - SET_DECL_VALUE_EXPR (decl, sym->backend_decl); - DECL_HAS_VALUE_EXPR_P (decl) = 1; - DECL_CONTEXT (decl) = DECL_CONTEXT (sym->backend_decl); - DECL_CHAIN (decl) = nonlocal_dummy_decls; - nonlocal_dummy_decls = decl; -} - /* Return a constant or a variable to use as a string length. Does not add the decl to the current scope. */ @@ -1532,6 +1510,13 @@ /* Dummy variables should already have been created. */ gcc_assert (sym->backend_decl); + /* However, the string length of deferred arrays must be set. */ + if (sym->ts.type == BT_CHARACTER + && sym->ts.deferred + && sym->attr.dimension + && sym->attr.allocatable) + gfc_defer_symbol_init (sym); + if (sym->attr.pointer && sym->attr.dimension && sym->ts.type != BT_CLASS) GFC_DECL_PTR_ARRAY_P (sym->backend_decl) = 1; @@ -1630,12 +1615,6 @@ gfc_add_assign_aux_vars (sym); } - if ((sym->attr.dimension || IS_CLASS_ARRAY (sym)) - && DECL_LANG_SPECIFIC (sym->backend_decl) - && GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl) - && DECL_CONTEXT (sym->backend_decl) != current_function_decl) - gfc_nonlocal_dummy_array_decl (sym); - if (sym->ts.type == BT_CLASS && sym->backend_decl) GFC_DECL_CLASS(sym->backend_decl) = 1; @@ -1701,12 +1680,13 @@ && sym->assoc && sym->assoc->target && ((sym->assoc->target->expr_type == EXPR_VARIABLE && sym->assoc->target->symtree->n.sym->ts.type != BT_CHARACTER) - || sym->assoc->target->expr_type == EXPR_FUNCTION)) + || sym->assoc->target->expr_type != EXPR_VARIABLE)) sym->ts.u.cl->backend_decl = NULL_TREE; if (sym->attr.associate_var && sym->ts.u.cl->backend_decl - && VAR_P (sym->ts.u.cl->backend_decl)) + && (VAR_P (sym->ts.u.cl->backend_decl) + || TREE_CODE (sym->ts.u.cl->backend_decl) == PARM_DECL)) length = gfc_index_zero_node; else length = gfc_create_string_length (sym); @@ -1765,13 +1745,35 @@ && !(sym->attr.use_assoc && !intrinsic_array_parameter))) gfc_defer_symbol_init (sym); + if (sym->ts.type == BT_CHARACTER + && sym->attr.allocatable + && !sym->attr.dimension + && sym->ts.u.cl && sym->ts.u.cl->length + && sym->ts.u.cl->length->expr_type == EXPR_VARIABLE) + gfc_defer_symbol_init (sym); + /* Associate names can use the hidden string length variable of their associated target. */ if (sym->ts.type == BT_CHARACTER - && TREE_CODE (length) != INTEGER_CST) + && TREE_CODE (length) != INTEGER_CST + && TREE_CODE (sym->ts.u.cl->backend_decl) != INDIRECT_REF) { + length = fold_convert (gfc_charlen_type_node, length); gfc_finish_var_decl (length, sym); - gcc_assert (!sym->value); + if (!sym->attr.associate_var + && TREE_CODE (length) == VAR_DECL + && sym->value && sym->value->expr_type != EXPR_NULL + && sym->value->ts.u.cl->length) + { + gfc_expr *len = sym->value->ts.u.cl->length; + DECL_INITIAL (length) = gfc_conv_initializer (len, &len->ts, + TREE_TYPE (length), + false, false, false); + DECL_INITIAL (length) = fold_convert (gfc_charlen_type_node, + DECL_INITIAL (length)); + } + else + gcc_assert (!sym->value || sym->value->expr_type == EXPR_NULL); } gfc_finish_var_decl (decl, sym); @@ -1809,7 +1811,10 @@ || !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)) || sym->attr.data || sym->ns->proc_name->attr.flavor == FL_MODULE) && (flag_coarray != GFC_FCOARRAY_LIB - || !sym->attr.codimension || sym->attr.allocatable)) + || !sym->attr.codimension || sym->attr.allocatable) + && !(sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type) + && !(sym->ts.type == BT_CLASS + && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)) { /* Add static initializer. For procedures, it is only needed if SAVE is specified otherwise they need to be reinitialized @@ -1837,7 +1842,7 @@ GFC_DECL_ASSOCIATE_VAR_P (decl) = 1; if (sym->attr.vtab - || (sym->name[0] == '_' && strncmp ("__def_init", sym->name, 10) == 0)) + || (sym->name[0] == '_' && gfc_str_startswith (sym->name, "__def_init"))) TREE_READONLY (decl) = 1; return decl; @@ -3312,6 +3317,11 @@ void_type_node, 3, pchar_type_node, gfc_charlen_type_node, gfc_int8_type_node); + gfor_fndecl_random_init = gfc_build_library_function_decl ( + get_identifier (PREFIX("random_init")), + void_type_node, 3, gfc_logical4_type_node, gfc_logical4_type_node, + gfc_int4_type_node); + gfor_fndecl_sc_kind = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("selected_char_kind")), "..R", gfc_int4_type_node, 2, gfc_charlen_type_node, pchar_type_node); @@ -3360,7 +3370,7 @@ jtype = gfc_get_int_type (ikinds[jkind]); if (itype && jtype) { - sprintf(name, PREFIX("pow_i%d_i%d"), ikinds[ikind], + sprintf (name, PREFIX("pow_i%d_i%d"), ikinds[ikind], ikinds[jkind]); gfor_fndecl_math_powi[jkind][ikind].integer = gfc_build_library_function_decl (get_identifier (name), @@ -3375,7 +3385,7 @@ rtype = gfc_get_real_type (rkinds[rkind]); if (rtype && itype) { - sprintf(name, PREFIX("pow_r%d_i%d"), rkinds[rkind], + sprintf (name, PREFIX("pow_r%d_i%d"), rkinds[rkind], ikinds[ikind]); gfor_fndecl_math_powi[rkind][ikind].real = gfc_build_library_function_decl (get_identifier (name), @@ -3387,7 +3397,7 @@ ctype = gfc_get_complex_type (rkinds[rkind]); if (ctype && itype) { - sprintf(name, PREFIX("pow_c%d_i%d"), rkinds[rkind], + sprintf (name, PREFIX("pow_c%d_i%d"), rkinds[rkind], ikinds[ikind]); gfor_fndecl_math_powi[rkind][ikind].cmplx = gfc_build_library_function_decl (get_identifier (name), @@ -3480,6 +3490,14 @@ gfor_fndecl_iargc = gfc_build_library_function_decl ( get_identifier (PREFIX ("iargc")), gfc_int4_type_node, 0); TREE_NOTHROW (gfor_fndecl_iargc) = 1; + + gfor_fndecl_kill_sub = gfc_build_library_function_decl ( + get_identifier (PREFIX ("kill_sub")), void_type_node, + 3, gfc_int4_type_node, gfc_int4_type_node, gfc_pint4_type_node); + + gfor_fndecl_kill = gfc_build_library_function_decl ( + get_identifier (PREFIX ("kill")), gfc_int4_type_node, + 2, gfc_int4_type_node, gfc_int4_type_node); } @@ -3488,39 +3506,41 @@ void gfc_build_builtin_function_decls (void) { - tree gfc_int4_type_node = gfc_get_int_type (4); + tree gfc_int8_type_node = gfc_get_int_type (8); gfor_fndecl_stop_numeric = gfc_build_library_function_decl ( get_identifier (PREFIX("stop_numeric")), - void_type_node, 1, gfc_int4_type_node); + void_type_node, 2, integer_type_node, boolean_type_node); /* STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_stop_numeric) = 1; gfor_fndecl_stop_string = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("stop_string")), ".R.", - void_type_node, 2, pchar_type_node, gfc_int4_type_node); + void_type_node, 3, pchar_type_node, size_type_node, + boolean_type_node); /* STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_stop_string) = 1; gfor_fndecl_error_stop_numeric = gfc_build_library_function_decl ( get_identifier (PREFIX("error_stop_numeric")), - void_type_node, 1, gfc_int4_type_node); + void_type_node, 2, integer_type_node, boolean_type_node); /* ERROR STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_error_stop_numeric) = 1; gfor_fndecl_error_stop_string = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("error_stop_string")), ".R.", - void_type_node, 2, pchar_type_node, gfc_int4_type_node); + void_type_node, 3, pchar_type_node, size_type_node, + boolean_type_node); /* ERROR STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_error_stop_string) = 1; gfor_fndecl_pause_numeric = gfc_build_library_function_decl ( get_identifier (PREFIX("pause_numeric")), - void_type_node, 1, gfc_int4_type_node); + void_type_node, 1, gfc_int8_type_node); gfor_fndecl_pause_string = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("pause_string")), ".R.", - void_type_node, 2, pchar_type_node, gfc_int4_type_node); + void_type_node, 2, pchar_type_node, size_type_node); gfor_fndecl_runtime_error = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("runtime_error")), ".R", @@ -3625,12 +3645,12 @@ gfor_fndecl_caf_register = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_register")), "RRWWWWR", void_type_node, 7, size_type_node, integer_type_node, ppvoid_type_node, pvoid_type_node, - pint_type, pchar_type_node, integer_type_node); + pint_type, pchar_type_node, size_type_node); gfor_fndecl_caf_deregister = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_deregister")), "WRWWR", void_type_node, 5, ppvoid_type_node, integer_type_node, pint_type, pchar_type_node, - integer_type_node); + size_type_node); gfor_fndecl_caf_get = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_get")), ".R.RRWRRRW", void_type_node, 10, @@ -3639,10 +3659,10 @@ boolean_type_node, pint_type); gfor_fndecl_caf_send = gfc_build_library_function_decl_with_spec ( - get_identifier (PREFIX("caf_send")), ".R.RRRRRRW", void_type_node, 10, + get_identifier (PREFIX("caf_send")), ".R.RRRRRRWR", void_type_node, 11, pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node, pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node, - boolean_type_node, pint_type); + boolean_type_node, pint_type, pvoid_type_node); gfor_fndecl_caf_sendget = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_sendget")), ".R.RRRR.RRRRRR", @@ -3652,59 +3672,60 @@ integer_type_node, boolean_type_node, integer_type_node); gfor_fndecl_caf_get_by_ref = gfc_build_library_function_decl_with_spec ( - get_identifier (PREFIX("caf_get_by_ref")), ".RWRRRRRW", void_type_node, - 9, pvoid_type_node, integer_type_node, pvoid_type_node, pvoid_type_node, - integer_type_node, integer_type_node, boolean_type_node, - boolean_type_node, pint_type); + get_identifier (PREFIX("caf_get_by_ref")), ".RWRRRRRWR", void_type_node, + 10, pvoid_type_node, integer_type_node, pvoid_type_node, + pvoid_type_node, integer_type_node, integer_type_node, + boolean_type_node, boolean_type_node, pint_type, integer_type_node); gfor_fndecl_caf_send_by_ref = gfc_build_library_function_decl_with_spec ( - get_identifier (PREFIX("caf_send_by_ref")), ".RRRRRRRW", void_type_node, - 9, pvoid_type_node, integer_type_node, pvoid_type_node, pvoid_type_node, - integer_type_node, integer_type_node, boolean_type_node, - boolean_type_node, pint_type); + get_identifier (PREFIX("caf_send_by_ref")), ".RRRRRRRWR", + void_type_node, 10, pvoid_type_node, integer_type_node, pvoid_type_node, + pvoid_type_node, integer_type_node, integer_type_node, + boolean_type_node, boolean_type_node, pint_type, integer_type_node); gfor_fndecl_caf_sendget_by_ref = gfc_build_library_function_decl_with_spec ( - get_identifier (PREFIX("caf_sendget_by_ref")), ".RR.RRRRRWW", - void_type_node, 11, pvoid_type_node, integer_type_node, + get_identifier (PREFIX("caf_sendget_by_ref")), ".RR.RRRRRWWRR", + void_type_node, 13, pvoid_type_node, integer_type_node, pvoid_type_node, pvoid_type_node, integer_type_node, pvoid_type_node, integer_type_node, integer_type_node, - boolean_type_node, pint_type, pint_type); + boolean_type_node, pint_type, pint_type, integer_type_node, + integer_type_node); gfor_fndecl_caf_sync_all = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_sync_all")), ".WW", void_type_node, - 3, pint_type, pchar_type_node, integer_type_node); + 3, pint_type, pchar_type_node, size_type_node); gfor_fndecl_caf_sync_memory = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_sync_memory")), ".WW", void_type_node, - 3, pint_type, pchar_type_node, integer_type_node); + 3, pint_type, pchar_type_node, size_type_node); gfor_fndecl_caf_sync_images = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_sync_images")), ".RRWW", void_type_node, 5, integer_type_node, pint_type, pint_type, - pchar_type_node, integer_type_node); + pchar_type_node, size_type_node); gfor_fndecl_caf_error_stop = gfc_build_library_function_decl ( get_identifier (PREFIX("caf_error_stop")), - void_type_node, 1, gfc_int4_type_node); + void_type_node, 1, integer_type_node); /* CAF's ERROR STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop) = 1; gfor_fndecl_caf_error_stop_str = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_error_stop_str")), ".R.", - void_type_node, 2, pchar_type_node, gfc_int4_type_node); + void_type_node, 2, pchar_type_node, size_type_node); /* CAF's ERROR STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop_str) = 1; gfor_fndecl_caf_stop_numeric = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_stop_numeric")), ".R.", - void_type_node, 1, gfc_int4_type_node); + void_type_node, 1, integer_type_node); /* CAF's STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_numeric) = 1; gfor_fndecl_caf_stop_str = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_stop_str")), ".R.", - void_type_node, 2, pchar_type_node, gfc_int4_type_node); + void_type_node, 2, pchar_type_node, size_type_node); /* CAF's STOP doesn't return. */ TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_str) = 1; @@ -3733,22 +3754,22 @@ gfor_fndecl_caf_lock = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_lock")), "R..WWW", void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node, - pint_type, pint_type, pchar_type_node, integer_type_node); + pint_type, pint_type, pchar_type_node, size_type_node); gfor_fndecl_caf_unlock = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_unlock")), "R..WW", void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node, - pint_type, pchar_type_node, integer_type_node); + pint_type, pchar_type_node, size_type_node); gfor_fndecl_caf_event_post = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_event_post")), "R..WW", void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node, - pint_type, pchar_type_node, integer_type_node); + pint_type, pchar_type_node, size_type_node); gfor_fndecl_caf_event_wait = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_event_wait")), "R..WW", void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node, - pint_type, pchar_type_node, integer_type_node); + pint_type, pchar_type_node, size_type_node); gfor_fndecl_caf_event_query = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_event_query")), "R..WW", @@ -3766,6 +3787,38 @@ void_type_node, 3, pvoid_type_node, ppvoid_type_node, integer_type_node); + gfor_fndecl_caf_form_team + = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("caf_form_team")), "RWR", + void_type_node, 3, integer_type_node, ppvoid_type_node, + integer_type_node); + + gfor_fndecl_caf_change_team + = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("caf_change_team")), "RR", + void_type_node, 2, ppvoid_type_node, + integer_type_node); + + gfor_fndecl_caf_end_team + = gfc_build_library_function_decl ( + get_identifier (PREFIX("caf_end_team")), void_type_node, 0); + + gfor_fndecl_caf_get_team + = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("caf_get_team")), "R", + void_type_node, 1, integer_type_node); + + gfor_fndecl_caf_sync_team + = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("caf_sync_team")), "RR", + void_type_node, 2, ppvoid_type_node, + integer_type_node); + + gfor_fndecl_caf_team_number + = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("caf_team_number")), "R", + integer_type_node, 1, integer_type_node); + gfor_fndecl_caf_image_status = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_image_status")), "RR", @@ -3780,17 +3833,17 @@ gfor_fndecl_co_broadcast = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_co_broadcast")), "W.WW", void_type_node, 5, pvoid_type_node, integer_type_node, - pint_type, pchar_type_node, integer_type_node); + pint_type, pchar_type_node, size_type_node); gfor_fndecl_co_max = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_co_max")), "W.WW", void_type_node, 6, pvoid_type_node, integer_type_node, - pint_type, pchar_type_node, integer_type_node, integer_type_node); + pint_type, pchar_type_node, integer_type_node, size_type_node); gfor_fndecl_co_min = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_co_min")), "W.WW", void_type_node, 6, pvoid_type_node, integer_type_node, - pint_type, pchar_type_node, integer_type_node, integer_type_node); + pint_type, pchar_type_node, integer_type_node, size_type_node); gfor_fndecl_co_reduce = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_co_reduce")), "W.R.WW", @@ -3798,12 +3851,12 @@ build_pointer_type (build_varargs_function_type_list (void_type_node, NULL_TREE)), integer_type_node, integer_type_node, pint_type, pchar_type_node, - integer_type_node, integer_type_node); + integer_type_node, size_type_node); gfor_fndecl_co_sum = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_co_sum")), "W.WW", void_type_node, 5, pvoid_type_node, integer_type_node, - pint_type, pchar_type_node, integer_type_node); + pint_type, pchar_type_node, size_type_node); gfor_fndecl_caf_is_present = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_is_present")), "RRR", @@ -4004,6 +4057,10 @@ gcc_assert (block); + /* Initialization of PDTs is done elsewhere. */ + if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type) + return; + gcc_assert (!sym->attr.allocatable); gfc_set_sym_referenced (sym); e = gfc_lval_expr_from_sym (sym); @@ -4161,6 +4218,24 @@ return tmp; } + +/* Get the result expression for a procedure. */ + +static tree +get_proc_result (gfc_symbol* sym) +{ + if (sym->attr.subroutine || sym == sym->result) + { + if (current_fake_result_decl != NULL) + return TREE_VALUE (current_fake_result_decl); + + return NULL_TREE; + } + + return sym->result->backend_decl; +} + + /* Generate function entry and exit code, and add it to the function body. This includes: Allocation and initialization of array variables. @@ -4198,7 +4273,7 @@ break; } /* TODO: move to the appropriate place in resolve.c. */ - if (warn_return_type && el == NULL) + if (warn_return_type > 0 && el == NULL) gfc_warning (OPT_Wreturn_type, "Return value of function %qs at %L not set", proc_sym->name, &proc_sym->declared_at); @@ -4255,10 +4330,11 @@ { tmp = proc_sym->ts.u.cl->passed_length; tmp = build_fold_indirect_ref_loc (input_location, tmp); - tmp = fold_convert (gfc_charlen_type_node, tmp); tmp = fold_build2_loc (input_location, MODIFY_EXPR, - gfc_charlen_type_node, tmp, - proc_sym->ts.u.cl->backend_decl); + TREE_TYPE (tmp), tmp, + fold_convert + (TREE_TYPE (tmp), + proc_sym->ts.u.cl->backend_decl)); } else tmp = NULL_TREE; @@ -4271,6 +4347,21 @@ else gcc_assert (flag_f2c && proc_sym->ts.type == BT_COMPLEX); } + else if (proc_sym == proc_sym->result && IS_CLASS_ARRAY (proc_sym)) + { + /* Nullify explicit return class arrays on entry. */ + tree type; + tmp = get_proc_result (proc_sym); + if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) + { + gfc_start_block (&init); + tmp = gfc_class_data_get (tmp); + type = TREE_TYPE (gfc_conv_descriptor_data_get (tmp)); + gfc_conv_descriptor_data_set (&init, tmp, build_int_cst (type, 0)); + gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE); + } + } + /* Initialize the INTENT(OUT) derived type dummy arguments. This should be done here so that the offsets and lbounds of arrays @@ -4304,9 +4395,12 @@ sym->as ? sym->as->rank : 0, sym->param_list); gfc_add_expr_to_block (&tmpblock, tmp); - tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, - sym->backend_decl, - sym->as ? sym->as->rank : 0); + if (!sym->attr.result) + tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, + sym->backend_decl, + sym->as ? sym->as->rank : 0); + else + tmp = NULL_TREE; gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp); } else if (sym->attr.dummy) @@ -4336,8 +4430,11 @@ sym->param_list); gfc_add_expr_to_block (&tmpblock, tmp); tmp = gfc_class_data_get (sym->backend_decl); - tmp = gfc_deallocate_pdt_comp (data->ts.u.derived, tmp, - data->as ? data->as->rank : 0); + if (!sym->attr.result) + tmp = gfc_deallocate_pdt_comp (data->ts.u.derived, tmp, + data->as ? data->as->rank : 0); + else + tmp = NULL_TREE; gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp); } else if (sym->attr.dummy) @@ -4527,6 +4624,13 @@ gfc_set_backend_locus (&sym->declared_at); gfc_start_block (&init); + if (sym->ts.type == BT_CHARACTER + && sym->attr.allocatable + && !sym->attr.dimension + && sym->ts.u.cl && sym->ts.u.cl->length + && sym->ts.u.cl->length->expr_type == EXPR_VARIABLE) + gfc_conv_string_length (sym->ts.u.cl, NULL, &init); + if (!sym->attr.pointer) { /* Nullify and automatic deallocation of allocatable @@ -4584,7 +4688,10 @@ && sym->ts.u.cl->passed_length) tmp = gfc_null_and_pass_deferred_len (sym, &init, &loc); else - gfc_restore_backend_locus (&loc); + { + gfc_restore_backend_locus (&loc); + tmp = NULL_TREE; + } /* Deallocate when leaving the scope. Nullifying is not needed. */ @@ -4636,10 +4743,6 @@ } gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp); - /* TODO find out why this is necessary to stop double calls to - free. Somebody is reusing the expression in 'tmp' because - it is being used unititialized. */ - tmp = NULL_TREE; } } else if (sym->ts.type == BT_CHARACTER && sym->ts.deferred) @@ -5263,7 +5366,7 @@ token, gfc_build_addr_expr (pvoid_type_node, desc), null_pointer_node, /* stat. */ null_pointer_node, /* errgmsg. */ - integer_zero_node); /* errmsg_len. */ + build_zero_cst (size_type_node)); /* errmsg_len. */ gfc_add_expr_to_block (&caf_init_block, tmp); gfc_add_modify (&caf_init_block, decl, fold_convert (TREE_TYPE (decl), gfc_conv_descriptor_data_get (desc))); @@ -5620,7 +5723,7 @@ else if (sym->attr.flavor == FL_PROCEDURE) { /* TODO: move to the appropriate place in resolve.c. */ - if (warn_return_type + if (warn_return_type > 0 && sym->attr.function && sym->result && sym != sym->result @@ -5726,8 +5829,7 @@ tmp = gfc_finish_block (&block); /* The first argument selects the entry point. */ val = DECL_ARGUMENTS (current_function_decl); - tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE, - val, tmp, NULL_TREE); + tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, val, tmp); return tmp; } @@ -5785,7 +5887,7 @@ /* Build the condition. For optional arguments, an actual length of 0 is also acceptable if the associated string is NULL, which means the argument was not passed. */ - cond = fold_build2_loc (input_location, comparison, boolean_type_node, + cond = fold_build2_loc (input_location, comparison, logical_type_node, cl->passed_length, cl->backend_decl); if (fsym->attr.optional) { @@ -5794,19 +5896,20 @@ tree absent_failed; not_0length = fold_build2_loc (input_location, NE_EXPR, - boolean_type_node, + logical_type_node, cl->passed_length, - build_zero_cst (gfc_charlen_type_node)); + build_zero_cst + (TREE_TYPE (cl->passed_length))); /* The symbol needs to be referenced for gfc_get_symbol_decl. */ fsym->attr.referenced = 1; not_absent = gfc_conv_expr_present (fsym); absent_failed = fold_build2_loc (input_location, TRUTH_OR_EXPR, - boolean_type_node, not_0length, + logical_type_node, not_0length, not_absent); cond = fold_build2_loc (input_location, TRUTH_AND_EXPR, - boolean_type_node, cond, absent_failed); + logical_type_node, cond, absent_failed); } /* Build the runtime check. */ @@ -6068,23 +6171,6 @@ } -/* Get the result expression for a procedure. */ - -static tree -get_proc_result (gfc_symbol* sym) -{ - if (sym->attr.subroutine || sym == sym->result) - { - if (current_fake_result_decl != NULL) - return TREE_VALUE (current_fake_result_decl); - - return NULL_TREE; - } - - return sym->result->backend_decl; -} - - /* Generate an appropriate return-statement for a procedure. */ tree @@ -6350,9 +6436,6 @@ gfc_generate_contained_functions (ns); - nonlocal_dummy_decls = NULL; - nonlocal_dummy_decl_pset = NULL; - has_coarray_vars = false; generate_local_vars (ns); @@ -6377,13 +6460,13 @@ msg = xasprintf ("Recursive call to nonrecursive procedure '%s'", sym->name); - recurcheckvar = gfc_create_var (boolean_type_node, "is_recursive"); + recurcheckvar = gfc_create_var (logical_type_node, "is_recursive"); TREE_STATIC (recurcheckvar) = 1; - DECL_INITIAL (recurcheckvar) = boolean_false_node; + DECL_INITIAL (recurcheckvar) = logical_false_node; gfc_add_expr_to_block (&init, recurcheckvar); gfc_trans_runtime_check (true, false, recurcheckvar, &init, &sym->declared_at, msg); - gfc_add_modify (&init, recurcheckvar, boolean_true_node); + gfc_add_modify (&init, recurcheckvar, logical_true_node); free (msg); } @@ -6495,11 +6578,11 @@ if (result == NULL_TREE || artificial_result_decl) { /* TODO: move to the appropriate place in resolve.c. */ - if (warn_return_type && sym == sym->result) + if (warn_return_type > 0 && sym == sym->result) gfc_warning (OPT_Wreturn_type, "Return value of function %qs at %L not set", sym->name, &sym->declared_at); - if (warn_return_type) + if (warn_return_type > 0) TREE_NO_WARNING(sym->backend_decl) = 1; } if (result != NULL_TREE) @@ -6512,7 +6595,7 @@ if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) && !is_recursive && !flag_openmp && recurcheckvar != NULL_TREE) { - gfc_add_modify (&cleanup, recurcheckvar, boolean_false_node); + gfc_add_modify (&cleanup, recurcheckvar, logical_false_node); recurcheckvar = NULL; } @@ -6552,15 +6635,6 @@ = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl)); - if (nonlocal_dummy_decls) - { - BLOCK_VARS (DECL_INITIAL (fndecl)) - = chainon (BLOCK_VARS (DECL_INITIAL (fndecl)), nonlocal_dummy_decls); - delete nonlocal_dummy_decl_pset; - nonlocal_dummy_decls = NULL; - nonlocal_dummy_decl_pset = NULL; - } - /* Output the GENERIC tree. */ dump_function (TDI_original, fndecl); @@ -6713,7 +6787,7 @@ { tree decl; - gcc_assert (saved_local_decls == NULL_TREE); + saved_local_decls = NULL_TREE; has_coarray_vars = false; generate_local_vars (ns);