summaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/trans-decl.c')
-rw-r--r--gcc/fortran/trans-decl.c380
1 files changed, 273 insertions, 107 deletions
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 01756ed32c..efff9a15ac 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1,5 +1,5 @@
/* Backend function setup
- Copyright (C) 2002-2016 Free Software Foundation, Inc.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
Contributed by Paul Brook
This file is part of GCC.
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see
/* Only for gfc_trans_code. Shouldn't need to include this. */
#include "trans-stmt.h"
#include "gomp-constants.h"
+#include "gimplify.h"
#define MAX_LABEL_VALUE 99999
@@ -97,7 +98,6 @@ static int seen_ieee_symbol;
tree gfor_fndecl_pause_numeric;
tree gfor_fndecl_pause_string;
tree gfor_fndecl_stop_numeric;
-tree gfor_fndecl_stop_numeric_f08;
tree gfor_fndecl_stop_string;
tree gfor_fndecl_error_stop_numeric;
tree gfor_fndecl_error_stop_string;
@@ -134,6 +134,9 @@ tree gfor_fndecl_caf_deregister;
tree gfor_fndecl_caf_get;
tree gfor_fndecl_caf_send;
tree gfor_fndecl_caf_sendget;
+tree gfor_fndecl_caf_get_by_ref;
+tree gfor_fndecl_caf_send_by_ref;
+tree gfor_fndecl_caf_sendget_by_ref;
tree gfor_fndecl_caf_sync_all;
tree gfor_fndecl_caf_sync_memory;
tree gfor_fndecl_caf_sync_images;
@@ -150,11 +153,16 @@ tree gfor_fndecl_caf_unlock;
tree gfor_fndecl_caf_event_post;
tree gfor_fndecl_caf_event_wait;
tree gfor_fndecl_caf_event_query;
+tree gfor_fndecl_caf_fail_image;
+tree gfor_fndecl_caf_failed_images;
+tree gfor_fndecl_caf_image_status;
+tree gfor_fndecl_caf_stopped_images;
tree gfor_fndecl_co_broadcast;
tree gfor_fndecl_co_max;
tree gfor_fndecl_co_min;
tree gfor_fndecl_co_reduce;
tree gfor_fndecl_co_sum;
+tree gfor_fndecl_caf_is_present;
/* Math functions. Many other math functions are handled in
@@ -270,7 +278,7 @@ gfc_build_label_decl (tree label_id)
label_decl = build_decl (input_location,
LABEL_DECL, label_id, void_type_node);
DECL_CONTEXT (label_decl) = current_function_decl;
- DECL_MODE (label_decl) = VOIDmode;
+ SET_DECL_MODE (label_decl, VOIDmode);
/* We always define the label as used, even if the original source
file never references the label. We don't want all kinds of
@@ -351,12 +359,36 @@ gfc_sym_mangled_identifier (gfc_symbol * sym)
if (sym->attr.is_bind_c == 1 && sym->binding_label)
return get_identifier (sym->binding_label);
- if (sym->module == NULL)
- return gfc_sym_identifier (sym);
+ if (!sym->fn_result_spec)
+ {
+ if (sym->module == NULL)
+ return gfc_sym_identifier (sym);
+ else
+ {
+ snprintf (name, sizeof name, "__%s_MOD_%s", sym->module, sym->name);
+ return get_identifier (name);
+ }
+ }
else
{
- snprintf (name, sizeof name, "__%s_MOD_%s", sym->module, sym->name);
- return get_identifier (name);
+ /* This is an entity that is actually local to a module procedure
+ that appears in the result specification expression. Since
+ sym->module will be a zero length string, we use ns->proc_name
+ instead. */
+ if (sym->ns->proc_name && sym->ns->proc_name->module)
+ {
+ snprintf (name, sizeof name, "__%s_MOD__%s_PROC_%s",
+ sym->ns->proc_name->module,
+ sym->ns->proc_name->name,
+ sym->name);
+ return get_identifier (name);
+ }
+ else
+ {
+ snprintf (name, sizeof name, "__%s_PROC_%s",
+ sym->ns->proc_name->name, sym->name);
+ return get_identifier (name);
+ }
}
}
@@ -491,7 +523,7 @@ gfc_finish_decl (tree decl)
gcc_assert (TREE_CODE (decl) == PARM_DECL
|| DECL_INITIAL (decl) == NULL_TREE);
- if (TREE_CODE (decl) != VAR_DECL)
+ if (!VAR_P (decl))
return;
if (DECL_SIZE (decl) == NULL_TREE
@@ -610,6 +642,16 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
}
+ else if (sym->fn_result_spec && !sym->ns->proc_name->module)
+ {
+
+ if (sym->ns->proc_name->attr.if_source != IFSRC_DECL)
+ DECL_EXTERNAL (decl) = 1;
+ else
+ TREE_STATIC (decl) = 1;
+
+ TREE_PUBLIC (decl) = 1;
+ }
else if (sym->module && !sym->attr.result && !sym->attr.dummy)
{
/* TODO: Don't set sym->module for result or dummy variables. */
@@ -637,6 +679,16 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
&& sym->attr.codimension && !sym->attr.allocatable)))
TREE_STATIC (decl) = 1;
+ /* If derived-type variables with DTIO procedures are not made static
+ some bits of code referencing them get optimized away.
+ TODO Understand why this is so and fix it. */
+ if (!sym->attr.use_assoc
+ && ((sym->ts.type == BT_DERIVED
+ && sym->ts.u.derived->attr.has_dtio_procs)
+ || (sym->ts.type == BT_CLASS
+ && CLASS_DATA (sym)->ts.u.derived->attr.has_dtio_procs)))
+ TREE_STATIC (decl) = 1;
+
if (sym->attr.volatile_)
{
TREE_THIS_VOLATILE (decl) = 1;
@@ -646,7 +698,7 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
}
/* Keep variables larger than max-stack-var-size off stack. */
- if (!sym->ns->proc_name->attr.recursive
+ if (!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. */
@@ -656,7 +708,43 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
|| sym->attr.pointer
|| sym->attr.allocatable)
&& !DECL_ARTIFICIAL (decl))
- TREE_STATIC (decl) = 1;
+ {
+ TREE_STATIC (decl) = 1;
+
+ /* Because the size of this variable isn't known until now, we may have
+ greedily added an initializer to this variable (in build_init_assign)
+ even though the max-stack-var-size indicates the variable should be
+ static. Therefore we rip out the automatic initializer here and
+ replace it with a static one. */
+ gfc_symtree *st = gfc_find_symtree (sym->ns->sym_root, sym->name);
+ gfc_code *prev = NULL;
+ gfc_code *code = sym->ns->code;
+ while (code && code->op == EXEC_INIT_ASSIGN)
+ {
+ /* Look for an initializer meant for this symbol. */
+ if (code->expr1->symtree == st)
+ {
+ if (prev)
+ prev->next = code->next;
+ else
+ sym->ns->code = code->next;
+
+ break;
+ }
+
+ prev = code;
+ code = code->next;
+ }
+ if (code && code->op == EXEC_INIT_ASSIGN)
+ {
+ /* Keep the init expression for a static initializer. */
+ sym->value = code->expr2;
+ /* Cleanup the defunct code object, without freeing the init expr. */
+ code->expr2 = NULL;
+ gfc_free_statement (code);
+ free (code);
+ }
+ }
/* Handle threadprivate variables. */
if (sym->attr.threadprivate
@@ -887,6 +975,10 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
DECL_CONTEXT (token) = sym->ns->proc_name->backend_decl;
gfc_module_add_decl (cur_module, token);
}
+ else if (sym->attr.host_assoc
+ && TREE_CODE (DECL_CONTEXT (current_function_decl))
+ != TRANSLATION_UNIT_DECL)
+ gfc_add_decl_to_parent_function (token);
else
gfc_add_decl_to_function (token);
}
@@ -968,9 +1060,9 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
layout_type (type);
}
- if (TYPE_NAME (type) != NULL_TREE
+ if (TYPE_NAME (type) != NULL_TREE && as->rank > 0
&& GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1) != NULL_TREE
- && TREE_CODE (GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1)) == VAR_DECL)
+ && VAR_P (GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1)))
{
tree gtype = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
@@ -1000,8 +1092,10 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
can be tracked by VTA. Also set DECL_NAMELESS, so that
the artificial lbound.N or ubound.N DECL_NAME doesn't
end up in debug info. */
- if (lbound && TREE_CODE (lbound) == VAR_DECL
- && DECL_ARTIFICIAL (lbound) && DECL_IGNORED_P (lbound))
+ if (lbound
+ && VAR_P (lbound)
+ && DECL_ARTIFICIAL (lbound)
+ && DECL_IGNORED_P (lbound))
{
if (DECL_NAME (lbound)
&& strstr (IDENTIFIER_POINTER (DECL_NAME (lbound)),
@@ -1009,8 +1103,10 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
DECL_NAMELESS (lbound) = 1;
DECL_IGNORED_P (lbound) = 0;
}
- if (ubound && TREE_CODE (ubound) == VAR_DECL
- && DECL_ARTIFICIAL (ubound) && DECL_IGNORED_P (ubound))
+ if (ubound
+ && VAR_P (ubound)
+ && DECL_ARTIFICIAL (ubound)
+ && DECL_IGNORED_P (ubound))
{
if (DECL_NAME (ubound)
&& strstr (IDENTIFIER_POINTER (DECL_NAME (ubound)),
@@ -1322,7 +1418,10 @@ add_attributes_to_decl (symbol_attribute sym_attr, tree list)
list = chainon (list, attr);
}
- if (sym_attr.omp_declare_target)
+ if (sym_attr.omp_declare_target_link)
+ list = tree_cons (get_identifier ("omp declare target link"),
+ NULL_TREE, list);
+ else if (sym_attr.omp_declare_target)
list = tree_cons (get_identifier ("omp declare target"),
NULL_TREE, list);
@@ -1464,8 +1563,7 @@ gfc_get_symbol_decl (gfc_symbol * sym)
length = gfc_create_string_length (sym);
else
length = sym->ts.u.cl->backend_decl;
- if (TREE_CODE (length) == VAR_DECL
- && DECL_FILE_SCOPE_P (length))
+ if (VAR_P (length) && DECL_FILE_SCOPE_P (length))
{
/* Add the string length to the same context as the symbol. */
if (DECL_CONTEXT (sym->backend_decl) == current_function_decl)
@@ -1575,12 +1673,12 @@ gfc_get_symbol_decl (gfc_symbol * sym)
/* Create string length decl first so that they can be used in the
type declaration. For associate names, the target character
length is used. Set 'length' to a constant so that if the
- string lenght is a variable, it is not finished a second time. */
+ string length is a variable, it is not finished a second time. */
if (sym->ts.type == BT_CHARACTER)
{
if (sym->attr.associate_var
&& sym->ts.u.cl->backend_decl
- && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL)
+ && VAR_P (sym->ts.u.cl->backend_decl))
length = gfc_index_zero_node;
else
length = gfc_create_string_length (sym);
@@ -1597,7 +1695,7 @@ gfc_get_symbol_decl (gfc_symbol * sym)
/* Symbols from modules should have their assembler names mangled.
This is done here rather than in gfc_finish_var_decl because it
is different for string length variables. */
- if (sym->module)
+ if (sym->module || sym->fn_result_spec)
{
gfc_set_decl_assembler_name (decl, gfc_sym_mangled_identifier (sym));
if (sym->attr.use_assoc && !intrinsic_array_parameter)
@@ -1689,7 +1787,7 @@ gfc_get_symbol_decl (gfc_symbol * sym)
if (TREE_STATIC (decl)
&& !(sym->attr.use_assoc && !intrinsic_array_parameter)
&& (sym->attr.save || sym->ns->proc_name->attr.is_main_program
- || flag_max_stack_var_size == 0
+ || !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))
@@ -2874,8 +2972,7 @@ gfc_get_fake_result_decl (gfc_symbol * sym, int parent_flag)
length = gfc_create_string_length (sym);
else
length = sym->ts.u.cl->backend_decl;
- if (TREE_CODE (length) == VAR_DECL
- && DECL_CONTEXT (length) == NULL_TREE)
+ if (VAR_P (length) && DECL_CONTEXT (length) == NULL_TREE)
gfc_add_decl_to_function (length);
}
@@ -3380,12 +3477,6 @@ gfc_build_builtin_function_decls (void)
/* STOP doesn't return. */
TREE_THIS_VOLATILE (gfor_fndecl_stop_numeric) = 1;
- gfor_fndecl_stop_numeric_f08 = gfc_build_library_function_decl (
- get_identifier (PREFIX("stop_numeric_f08")),
- void_type_node, 1, gfc_int4_type_node);
- /* STOP doesn't return. */
- TREE_THIS_VOLATILE (gfor_fndecl_stop_numeric_f08) = 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);
@@ -3498,47 +3589,68 @@ gfc_build_builtin_function_decls (void)
= build_pointer_type (build_pointer_type (pchar_type_node));
gfor_fndecl_caf_init = gfc_build_library_function_decl (
- get_identifier (PREFIX("caf_init")), void_type_node,
- 2, pint_type, pppchar_type);
+ get_identifier (PREFIX("caf_init")), void_type_node,
+ 2, pint_type, pppchar_type);
gfor_fndecl_caf_finalize = gfc_build_library_function_decl (
get_identifier (PREFIX("caf_finalize")), void_type_node, 0);
gfor_fndecl_caf_this_image = gfc_build_library_function_decl (
- get_identifier (PREFIX("caf_this_image")), integer_type_node,
- 1, integer_type_node);
+ get_identifier (PREFIX("caf_this_image")), integer_type_node,
+ 1, integer_type_node);
gfor_fndecl_caf_num_images = gfc_build_library_function_decl (
- get_identifier (PREFIX("caf_num_images")), integer_type_node,
- 2, integer_type_node, integer_type_node);
+ get_identifier (PREFIX("caf_num_images")), integer_type_node,
+ 2, integer_type_node, integer_type_node);
gfor_fndecl_caf_register = gfc_build_library_function_decl_with_spec (
- get_identifier (PREFIX("caf_register")), "...WWW", pvoid_type_node, 6,
- size_type_node, integer_type_node, ppvoid_type_node, pint_type,
- pchar_type_node, integer_type_node);
+ 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);
gfor_fndecl_caf_deregister = gfc_build_library_function_decl_with_spec (
- get_identifier (PREFIX("caf_deregister")), ".WWW", void_type_node, 4,
- ppvoid_type_node, pint_type, pchar_type_node, integer_type_node);
+ get_identifier (PREFIX("caf_deregister")), "WRWWR", void_type_node, 5,
+ ppvoid_type_node, integer_type_node, pint_type, pchar_type_node,
+ integer_type_node);
gfor_fndecl_caf_get = gfc_build_library_function_decl_with_spec (
- get_identifier (PREFIX("caf_get")), ".R.RRRW", void_type_node, 9,
- pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
+ get_identifier (PREFIX("caf_get")), ".R.RRWRRRW", void_type_node, 10,
+ 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);
+ boolean_type_node, pint_type);
gfor_fndecl_caf_send = gfc_build_library_function_decl_with_spec (
- get_identifier (PREFIX("caf_send")), ".R.RRRR", void_type_node, 9,
- pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
+ get_identifier (PREFIX("caf_send")), ".R.RRRRRRW", void_type_node, 10,
+ 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);
+ boolean_type_node, pint_type);
gfor_fndecl_caf_sendget = gfc_build_library_function_decl_with_spec (
- get_identifier (PREFIX("caf_sendget")), ".R.RRRR.RRR", void_type_node,
- 13, pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
- pvoid_type_node, pvoid_type_node, size_type_node, integer_type_node,
- pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
- boolean_type_node);
+ get_identifier (PREFIX("caf_sendget")), ".R.RRRR.RRRRRR",
+ void_type_node, 14, pvoid_type_node, size_type_node, integer_type_node,
+ pvoid_type_node, pvoid_type_node, pvoid_type_node, size_type_node,
+ integer_type_node, pvoid_type_node, pvoid_type_node, integer_type_node,
+ 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);
+
+ 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);
+
+ 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,
+ 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);
gfor_fndecl_caf_sync_all = gfc_build_library_function_decl_with_spec (
get_identifier (PREFIX("caf_sync_all")), ".WW", void_type_node,
@@ -3566,31 +3678,31 @@ gfc_build_builtin_function_decls (void)
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);
+ get_identifier (PREFIX("caf_stop_numeric")), ".R.",
+ void_type_node, 1, gfc_int4_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);
+ get_identifier (PREFIX("caf_stop_str")), ".R.",
+ void_type_node, 2, pchar_type_node, gfc_int4_type_node);
/* CAF's STOP doesn't return. */
TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_str) = 1;
gfor_fndecl_caf_atomic_def = gfc_build_library_function_decl_with_spec (
get_identifier (PREFIX("caf_atomic_define")), "R..RW",
void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
- pvoid_type_node, pint_type, integer_type_node, integer_type_node);
+ pvoid_type_node, pint_type, integer_type_node, integer_type_node);
gfor_fndecl_caf_atomic_ref = gfc_build_library_function_decl_with_spec (
get_identifier (PREFIX("caf_atomic_ref")), "R..WW",
void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
- pvoid_type_node, pint_type, integer_type_node, integer_type_node);
+ pvoid_type_node, pint_type, integer_type_node, integer_type_node);
gfor_fndecl_caf_atomic_cas = gfc_build_library_function_decl_with_spec (
get_identifier (PREFIX("caf_atomic_cas")), "R..WRRW",
void_type_node, 9, pvoid_type_node, size_type_node, integer_type_node,
- pvoid_type_node, pvoid_type_node, pvoid_type_node, pint_type,
+ pvoid_type_node, pvoid_type_node, pvoid_type_node, pint_type,
integer_type_node, integer_type_node);
gfor_fndecl_caf_atomic_op = gfc_build_library_function_decl_with_spec (
@@ -3624,6 +3736,28 @@ gfc_build_builtin_function_decls (void)
void_type_node, 5, pvoid_type_node, size_type_node, integer_type_node,
pint_type, pint_type);
+ gfor_fndecl_caf_fail_image = gfc_build_library_function_decl (
+ get_identifier (PREFIX("caf_fail_image")), void_type_node, 0);
+ /* CAF's FAIL doesn't return. */
+ TREE_THIS_VOLATILE (gfor_fndecl_caf_fail_image) = 1;
+
+ gfor_fndecl_caf_failed_images
+ = gfc_build_library_function_decl_with_spec (
+ get_identifier (PREFIX("caf_failed_images")), "WRR",
+ void_type_node, 3, pvoid_type_node, ppvoid_type_node,
+ integer_type_node);
+
+ gfor_fndecl_caf_image_status
+ = gfc_build_library_function_decl_with_spec (
+ get_identifier (PREFIX("caf_image_status")), "RR",
+ integer_type_node, 2, integer_type_node, ppvoid_type_node);
+
+ gfor_fndecl_caf_stopped_images
+ = gfc_build_library_function_decl_with_spec (
+ get_identifier (PREFIX("caf_stopped_images")), "WRR",
+ void_type_node, 3, pvoid_type_node, ppvoid_type_node,
+ integer_type_node);
+
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,
@@ -3642,7 +3776,7 @@ gfc_build_builtin_function_decls (void)
gfor_fndecl_co_reduce = gfc_build_library_function_decl_with_spec (
get_identifier (PREFIX("caf_co_reduce")), "W.R.WW",
void_type_node, 8, pvoid_type_node,
- build_pointer_type (build_varargs_function_type_list (void_type_node,
+ 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);
@@ -3651,6 +3785,11 @@ gfc_build_builtin_function_decls (void)
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);
+
+ gfor_fndecl_caf_is_present = gfc_build_library_function_decl_with_spec (
+ get_identifier (PREFIX("caf_is_present")), "RRR",
+ integer_type_node, 3, pvoid_type_node, integer_type_node,
+ pvoid_type_node);
}
gfc_build_intrinsic_function_decls ();
@@ -3751,7 +3890,7 @@ gfc_trans_vla_one_sizepos (tree *tp, stmtblock_t *body)
var = gfc_create_var_np (TREE_TYPE (t), NULL);
gfc_add_decl_to_function (var);
- gfc_add_modify (body, var, val);
+ gfc_add_modify (body, var, unshare_expr (val));
if (TREE_CODE (t) == SAVE_EXPR)
TREE_OPERAND (t, 0) = var;
*tp = var;
@@ -4053,7 +4192,7 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
/* An automatic character length, pointer array result. */
if (proc_sym->ts.type == BT_CHARACTER
- && TREE_CODE (proc_sym->ts.u.cl->backend_decl) == VAR_DECL)
+ && VAR_P (proc_sym->ts.u.cl->backend_decl))
{
tmp = NULL;
if (proc_sym->ts.deferred)
@@ -4106,7 +4245,7 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
}
- else if (TREE_CODE (proc_sym->ts.u.cl->backend_decl) == VAR_DECL)
+ else if (VAR_P (proc_sym->ts.u.cl->backend_decl))
gfc_trans_dummy_character (proc_sym, proc_sym->ts.u.cl, block);
}
else
@@ -4372,12 +4511,15 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
tmp = gfc_deallocate_with_status (descriptor, NULL_TREE,
NULL_TREE, NULL_TREE,
NULL_TREE, true, NULL,
- true);
+ GFC_CAF_COARRAY_ANALYZE);
else
{
gfc_expr *expr = gfc_lval_expr_from_sym (sym);
- tmp = gfc_deallocate_scalar_with_status (se.expr, NULL_TREE,
- true, expr, sym->ts);
+ tmp = gfc_deallocate_scalar_with_status (se.expr,
+ NULL_TREE,
+ NULL_TREE,
+ true, expr,
+ sym->ts);
gfc_free_expr (expr);
}
}
@@ -4533,7 +4675,7 @@ gfc_find_module (const char *name)
{
module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
- entry->name = gfc_get_string (name);
+ entry->name = gfc_get_string ("%s", name);
entry->decls = hash_table<module_decl_hasher>::create_ggc (10);
*slot = entry;
}
@@ -4681,7 +4823,9 @@ gfc_create_module_variable (gfc_symbol * sym)
/* Create the variable. */
pushdecl (decl);
- gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
+ gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
+ || (sym->ns->parent->proc_name->attr.flavor == FL_MODULE
+ && sym->fn_result_spec));
DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
rest_of_decl_compilation (decl, 1, 0);
gfc_module_add_decl (cur_module, decl);
@@ -4773,8 +4917,7 @@ gfc_trans_use_stmts (gfc_namespace * ns)
&& strcmp (st->n.sym->module, use_stmt->module_name) == 0)
{
gcc_assert (DECL_EXTERNAL (entry->namespace_decl)
- || (TREE_CODE (st->n.sym->backend_decl)
- != VAR_DECL));
+ || !VAR_P (st->n.sym->backend_decl));
decl = copy_node (st->n.sym->backend_decl);
DECL_CONTEXT (decl) = entry->namespace_decl;
DECL_EXTERNAL (decl) = 1;
@@ -4955,9 +5098,11 @@ gfc_emit_parameter_debug_info (gfc_symbol *sym)
static void
generate_coarray_sym_init (gfc_symbol *sym)
{
- tree tmp, size, decl, token;
+ tree tmp, size, decl, token, desc;
bool is_lock_type, is_event_type;
int reg_type;
+ gfc_se se;
+ symbol_attribute attr;
if (sym->attr.dummy || sym->attr.allocatable || !sym->attr.codimension
|| sym->attr.use_assoc || !sym->attr.referenced
@@ -5008,12 +5153,30 @@ generate_coarray_sym_init (gfc_symbol *sym)
reg_type = GFC_CAF_EVENT_STATIC;
else
reg_type = GFC_CAF_COARRAY_STATIC;
- tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register, 6, size,
+
+ /* Compile the symbol attribute. */
+ if (sym->ts.type == BT_CLASS)
+ {
+ attr = CLASS_DATA (sym)->attr;
+ /* The pointer attribute is always set on classes, overwrite it with the
+ class_pointer attribute, which denotes the pointer for classes. */
+ attr.pointer = attr.class_pointer;
+ }
+ else
+ attr = sym->attr;
+ gfc_init_se (&se, NULL);
+ desc = gfc_conv_scalar_to_descriptor (&se, decl, attr);
+ gfc_add_block_to_block (&caf_init_block, &se.pre);
+
+ tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register, 7, size,
build_int_cst (integer_type_node, reg_type),
- token, null_pointer_node, /* token, stat. */
- null_pointer_node, /* errgmsg, errmsg_len. */
- build_int_cst (integer_type_node, 0));
- gfc_add_modify (&caf_init_block, decl, fold_convert (TREE_TYPE (decl), tmp));
+ token, gfc_build_addr_expr (pvoid_type_node, desc),
+ null_pointer_node, /* stat. */
+ null_pointer_node, /* errgmsg. */
+ integer_zero_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)));
/* Handle "static" initializer. */
if (sym->value)
@@ -5024,6 +5187,13 @@ generate_coarray_sym_init (gfc_symbol *sym)
sym->attr.pointer = 0;
gfc_add_expr_to_block (&caf_init_block, tmp);
}
+ else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pointer_comp)
+ {
+ tmp = gfc_nullify_alloc_comp (sym->ts.u.derived, decl, sym->as
+ ? sym->as->rank : 0,
+ GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
+ gfc_add_expr_to_block (&caf_init_block, tmp);
+ }
}
@@ -5279,9 +5449,19 @@ generate_local_decl (gfc_symbol * sym)
}
else if (!sym->attr.use_assoc)
{
- gfc_warning (OPT_Wunused_variable,
- "Unused variable %qs declared at %L",
- sym->name, &sym->declared_at);
+ /* Corner case: the symbol may be an entry point. At this point,
+ it may appear to be an unused variable. Suppress warning. */
+ bool enter = false;
+ gfc_entry_list *el;
+
+ for (el = sym->ns->entries; el; el=el->next)
+ if (strcmp(sym->name, el->sym->name) == 0)
+ enter = true;
+
+ if (!enter)
+ gfc_warning (OPT_Wunused_variable,
+ "Unused variable %qs declared at %L",
+ sym->name, &sym->declared_at);
if (sym->backend_decl != NULL_TREE)
TREE_NO_WARNING(sym->backend_decl) = 1;
}
@@ -5295,7 +5475,7 @@ generate_local_decl (gfc_symbol * sym)
if (sym->attr.dummy && !sym->attr.referenced
&& sym->ts.type == BT_CHARACTER
&& sym->ts.u.cl->backend_decl != NULL
- && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL)
+ && VAR_P (sym->ts.u.cl->backend_decl))
{
sym->attr.referenced = 1;
gfc_get_symbol_decl (sym);
@@ -5657,12 +5837,11 @@ create_main_function (tree fndecl)
{
tree array_type, array, var;
vec<constructor_elt, va_gc> *v = NULL;
+ static const int noptions = 7;
- /* Passing a new option to the library requires four modifications:
- + add it to the tree_cons list below
- + change the array size in the call to build_array_type
- + change the first argument to the library call
- gfor_fndecl_set_options
+ /* Passing a new option to the library requires three modifications:
+ + add it to the tree_cons list below
+ + change the noptions variable above
+ modify the library (runtime/compile_options.c)! */
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
@@ -5673,12 +5852,6 @@ create_main_function (tree fndecl)
gfc_option.allow_std));
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
build_int_cst (integer_type_node, pedantic));
- /* TODO: This is the old -fdump-core option, which is unused but
- passed due to ABI compatibility; remove when bumping the
- library ABI. */
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
- build_int_cst (integer_type_node,
- 0));
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
build_int_cst (integer_type_node, flag_backtrace));
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
@@ -5687,26 +5860,18 @@ create_main_function (tree fndecl)
build_int_cst (integer_type_node,
(gfc_option.rtcheck
& GFC_RTCHECK_BOUNDS)));
- /* TODO: This is the -frange-check option, which no longer affects
- library behavior; when bumping the library ABI this slot can be
- reused for something else. As it is the last element in the
- array, we can instead leave it out altogether. */
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
- build_int_cst (integer_type_node, 0));
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
build_int_cst (integer_type_node,
gfc_option.fpe_summary));
- array_type = build_array_type (integer_type_node,
- build_index_type (size_int (8)));
+ array_type = build_array_type_nelts (integer_type_node, noptions);
array = build_constructor (array_type, v);
TREE_CONSTANT (array) = 1;
TREE_STATIC (array) = 1;
/* Create a static variable to hold the jump table. */
var = build_decl (input_location, VAR_DECL,
- create_tmp_var_name ("options"),
- array_type);
+ create_tmp_var_name ("options"), array_type);
DECL_ARTIFICIAL (var) = 1;
DECL_IGNORED_P (var) = 1;
TREE_CONSTANT (var) = 1;
@@ -5718,7 +5883,7 @@ create_main_function (tree fndecl)
tmp = build_call_expr_loc (input_location,
gfor_fndecl_set_options, 2,
- build_int_cst (integer_type_node, 9), var);
+ build_int_cst (integer_type_node, noptions), var);
gfc_add_expr_to_block (&body, tmp);
}
@@ -5968,7 +6133,7 @@ finish_oacc_declare (gfc_namespace *ns, gfc_symbol *sym, bool block)
continue;
if (block)
- gfc_error ("Sorry, $!ACC DECLARE at %L is not allowed "
+ gfc_error ("Sorry, !$ACC DECLARE at %L is not allowed "
"in BLOCK construct", &oc->loc);
@@ -6049,8 +6214,8 @@ gfc_generate_function_code (gfc_namespace * ns)
previous_procedure_symbol = current_procedure_symbol;
current_procedure_symbol = sym;
- /* Check that the frontend isn't still using this. */
- gcc_assert (sym->tlink == NULL);
+ /* Initialize sym->tlink so that gfc_trans_deferred_vars does not get
+ lost or worse. */
sym->tlink = sym;
/* Create the declaration for functions with global scope. */
@@ -6219,7 +6384,8 @@ gfc_generate_function_code (gfc_namespace * ns)
/* Arrays are not initialized using the default initializer of
their elements. Therefore only check if a default
initializer is available when the result is scalar. */
- init_exp = rsym->as ? NULL : gfc_default_initializer (&rsym->ts);
+ init_exp = rsym->as ? NULL
+ : gfc_generate_initializer (&rsym->ts, true);
if (init_exp)
{
tmp = gfc_trans_structure_assign (result, init_exp, 0);