diff options
Diffstat (limited to 'gcc/fortran/trans-stmt.c')
-rw-r--r-- | gcc/fortran/trans-stmt.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index da074c8b454..ea5da88fe7b 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -80,7 +80,23 @@ gfc_trans_label_here (gfc_code * code) return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here)); } + +/* Given a variable expression which has been ASSIGNed to, find the decl + containing the auxiliary variables. For variables in common blocks this + is a field_decl. */ + +void +gfc_conv_label_variable (gfc_se * se, gfc_expr * expr) +{ + gcc_assert (expr->symtree->n.sym->attr.assign == 1); + gfc_conv_expr (se, expr); + /* Deals with variable in common block. Get the field declaration. */ + if (TREE_CODE (se->expr) == COMPONENT_REF) + se->expr = TREE_OPERAND (se->expr, 1); +} + /* Translate a label assignment statement. */ + tree gfc_trans_label_assign (gfc_code * code) { @@ -95,7 +111,8 @@ gfc_trans_label_assign (gfc_code * code) /* Start a new block. */ gfc_init_se (&se, NULL); gfc_start_block (&se.pre); - gfc_conv_expr (&se, code->expr); + gfc_conv_label_variable (&se, code->expr); + len = GFC_DECL_STRING_LEN (se.expr); addr = GFC_DECL_ASSIGN_ADDR (se.expr); @@ -103,6 +120,8 @@ gfc_trans_label_assign (gfc_code * code) if (code->label->defined == ST_LABEL_TARGET) { + /* Shouldn't need to set this flag. Reserve for optimization bug. */ + DECL_ARTIFICIAL (label_tree) = 0; label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree); len_tree = integer_minus_one_node; } @@ -140,7 +159,7 @@ gfc_trans_goto (gfc_code * code) /* ASSIGNED GOTO. */ gfc_init_se (&se, NULL); gfc_start_block (&se.pre); - gfc_conv_expr (&se, code->expr); + gfc_conv_label_variable (&se, code->expr); assign_error = gfc_build_cstring_const ("Assigned label is not a target label"); tmp = GFC_DECL_STRING_LEN (se.expr); |