diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-03-25 10:33:25 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-03-25 10:33:25 +0000 |
commit | 3013aa3871d2c0acdb579923ab997d9367a637e8 (patch) | |
tree | d397a166338c88f9fb0d5f6f5302efcae20d8bd9 /gcc/fortran | |
parent | 63f3c6bcb4f99fa87d29566c1ffdae7e7323eb73 (diff) | |
download | gcc-3013aa3871d2c0acdb579923ab997d9367a637e8.tar.gz |
2014-03-25 Basile Starynkevitch <basile@starynkevitch.net>
{{merge using svnmerge.py with trunk GCC 4.9 svn
rev.208803. Updated gcc/melt-runtime.cc...}}
[gcc/]
2014-03-25 Basile Starynkevitch <basile@starynkevitch.net>
{{merged with trunk, and....}}
* melt-runtime.cc (melt_load_module_index): Accept very short versionmelt strings.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@208808 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 67 | ||||
-rw-r--r-- | gcc/fortran/cpp.c | 1 | ||||
-rw-r--r-- | gcc/fortran/decl.c | 21 | ||||
-rw-r--r-- | gcc/fortran/expr.c | 3 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 1 | ||||
-rw-r--r-- | gcc/fortran/gfortran.texi | 6 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.c | 5 | ||||
-rw-r--r-- | gcc/fortran/io.c | 33 | ||||
-rw-r--r-- | gcc/fortran/match.c | 27 | ||||
-rw-r--r-- | gcc/fortran/parse.c | 3 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 54 | ||||
-rw-r--r-- | gcc/fortran/symbol.c | 4 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 18 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.c | 2 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.c | 3 | ||||
-rw-r--r-- | gcc/fortran/trans-io.c | 55 | ||||
-rw-r--r-- | gcc/fortran/trans-stmt.c | 8 | ||||
-rw-r--r-- | gcc/fortran/trans.c | 80 | ||||
-rw-r--r-- | gcc/fortran/trans.h | 7 |
19 files changed, 264 insertions, 134 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ce4063edd06..3e4d08d68c0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,70 @@ +2014-03-22 Jakub Jelinek <jakub@redhat.com> + + PR debug/60603 + * cpp.c (gfc_cpp_init): Restore cb_change_file call to + <built-in>. + +2014-03-21 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR fortran/60148 + * gfortran.texi: Add description of namelist DELIM= behavior. + +2014-03-19 Tobias Burnus <burnus@net-b.> + + PR fortran/60543 + * io.c (check_io_constraints): Use gfc_unset_implicit_pure. + * resolve.c (resolve_ordinary_assign): Ditto. + +2014-03-19 Tobias Burnus <burnus@net-b.de> + + PR fortran/60543 + PR fortran/60283 + * gfortran.h (gfc_unset_implicit_pure): New prototype. + * resolve.c (gfc_unset_implicit_pure): New. + (resolve_structure_cons, resolve_function, + pure_subroutine): Use it. + * decl.c (match_old_style_init, gfc_match_data, + match_pointer_init, variable_decl): Ditto. + * expr.c (gfc_check_pointer_assign): Ditto. + * intrinsic.c (gfc_intrinsic_sub_interface): Ditto. + * io.c (match_vtag, gfc_match_open, gfc_match_close, + match_filepos, gfc_match_inquire, gfc_match_print, + gfc_match_wait): Ditto. + * match.c (gfc_match_critical, gfc_match_stopcode, + lock_unlock_statement, sync_statement, gfc_match_allocate, + gfc_match_deallocate): Ditto. + * parse.c (decode_omp_directive): Ditto. + * symbol.c (gfc_add_save): Ditto. + +2014-03-18 Janus Weil <janus@gcc.gnu.org> + + PR fortran/55207 + PR fortran/60549 + * decl.c (match_attr_spec): Revert r208590. + +2014-03-18 Jakub Jelinek <jakub@redhat.com> + + PR ipa/58721 + * trans.c (gfc_unlikely, gfc_likely): Don't add __builtin_expect + if !optimize. + +2014-03-18 Tobias Burnus <burnus@net-b.de> + + PR ipa/58721 + * trans.h (gfc_unlikely, gfc_likely): Add predictor as argument. + (gfc_trans_io_runtime_check): Remove. + * trans-io.c (gfc_trans_io_runtime_check): Make static; add has_iostat + as argument, add predictor to block. + (set_parameter_value, gfc_trans_open, gfc_trans_close, build_filepos, + gfc_trans_inquire, gfc_trans_wait, build_dt): Update calls. + * trans.c (gfc_unlikely, gfc_likely): Add predictor as argument. + (gfc_trans_runtime_check, gfc_allocate_using_malloc, + gfc_allocate_allocatable, gfc_deallocate_with_status): Set explicitly + branch predictor. + * trans-expr.c (gfc_conv_procedure_call): Ditto. + * trans-stmt.c (gfc_trans_allocate): Ditto. + * trans-array.c (gfc_array_init_size, gfc_array_allocate): Ditto. + 2014-03-15 Janus Weil <janus@gcc.gnu.org> PR fortran/55207 diff --git a/gcc/fortran/cpp.c b/gcc/fortran/cpp.c index 68ce91ffdbf..169599003db 100644 --- a/gcc/fortran/cpp.c +++ b/gcc/fortran/cpp.c @@ -576,6 +576,7 @@ gfc_cpp_init (void) if (gfc_option.flag_preprocessed) return; + cpp_change_file (cpp_in, LC_RENAME, _("<built-in>")); if (!gfc_cpp_option.no_predefined) { /* Make sure all of the builtins about to be declared have diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index c7f5eed3682..4048ac91353 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -510,9 +510,7 @@ match_old_style_init (const char *name) free (newdata); return MATCH_ERROR; } - - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (gfc_current_ns->proc_name); /* Mark the variable as having appeared in a data statement. */ if (!gfc_add_data (&sym->attr, sym->name, &sym->declared_at)) @@ -571,9 +569,7 @@ gfc_match_data (void) gfc_error ("DATA statement at %C is not allowed in a PURE procedure"); return MATCH_ERROR; } - - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (gfc_current_ns->proc_name); return MATCH_YES; @@ -1739,6 +1735,7 @@ match_pointer_init (gfc_expr **init, int procptr) "a PURE procedure"); return MATCH_ERROR; } + gfc_unset_implicit_pure (gfc_current_ns->proc_name); /* Match NULL() initialization. */ m = gfc_match_null (init); @@ -2046,6 +2043,10 @@ variable_decl (int elem) m = MATCH_ERROR; } + if (current_attr.flavor != FL_PARAMETER + && gfc_state_stack->state != COMP_DERIVED) + gfc_unset_implicit_pure (gfc_current_ns->proc_name); + if (m != MATCH_YES) goto cleanup; } @@ -3827,11 +3828,9 @@ match_attr_spec (void) } } - /* Since Fortran 2008, variables declared in a MODULE or PROGRAM - implicitly have the SAVE attribute. */ - if ((gfc_current_state () == COMP_MODULE - || gfc_current_state () == COMP_PROGRAM) - && !current_attr.save && (gfc_option.allow_std & GFC_STD_F2008) != 0) + /* Since Fortran 2008 module variables implicitly have the SAVE attribute. */ + if (gfc_current_state () == COMP_MODULE && !current_attr.save + && (gfc_option.allow_std & GFC_STD_F2008) != 0) current_attr.save = SAVE_IMPLICIT; colon_seen = 1; diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index fe92c53a453..f6772047e27 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -3704,8 +3704,7 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue) } if (is_implicit_pure && gfc_impure_variable (rvalue->symtree->n.sym)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; - + gfc_unset_implicit_pure (gfc_current_ns->proc_name); if (gfc_has_vector_index (rvalue)) { diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index cd2a91323a3..14c202dd413 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2837,6 +2837,7 @@ void gfc_resolve_blocks (gfc_code *, gfc_namespace *); int gfc_impure_variable (gfc_symbol *); int gfc_pure (gfc_symbol *); int gfc_implicit_pure (gfc_symbol *); +void gfc_unset_implicit_pure (gfc_symbol *); int gfc_elemental (gfc_symbol *); bool gfc_resolve_iterator (gfc_iterator *, bool, bool); bool find_forall_index (gfc_expr *, gfc_symbol *, int); diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 7bab3e209ed..725ee8dfc4f 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -1494,6 +1494,12 @@ elements will be given the values 1.00 and 2.00. / @end smallexample +When writing a namelist, if no @code{DELIM=} is specified, by default a +double quote is used to delimit character strings. If -std=F95, F2003, +or F2008, etc, the delim status is set to 'none'. Defaulting to +quotes ensures that namelists with character strings can be subsequently +read back in accurately. + @node X format descriptor without count field @subsection @code{X} format descriptor without count field diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index 3db000b6ccf..19d46202e08 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -4404,13 +4404,16 @@ gfc_intrinsic_sub_interface (gfc_code *c, int error_flag) return MATCH_ERROR; } - if (gfc_pure (NULL) && !isym->pure) + if (!isym->pure && gfc_pure (NULL)) { gfc_error ("Subroutine call to intrinsic '%s' at %L is not PURE", name, &c->loc); return MATCH_ERROR; } + if (!isym->pure) + gfc_unset_implicit_pure (NULL); + c->resolved_sym->attr.noreturn = isym->noreturn; return MATCH_YES; diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index f2593b04e30..84d0db818de 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -1305,7 +1305,8 @@ match_vtag (const io_tag *tag, gfc_expr **v) return MATCH_ERROR; } - if (gfc_pure (NULL) && gfc_impure_variable (result->symtree->n.sym)) + bool impure = gfc_impure_variable (result->symtree->n.sym); + if (impure && gfc_pure (NULL)) { gfc_error ("Variable %s cannot be assigned in PURE procedure at %C", tag->name); @@ -1313,8 +1314,8 @@ match_vtag (const io_tag *tag, gfc_expr **v) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL) && gfc_impure_variable (result->symtree->n.sym)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + if (impure) + gfc_unset_implicit_pure (NULL); *v = result; return MATCH_YES; @@ -1829,8 +1830,7 @@ gfc_match_open (void) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); warn = (open->err || open->iostat) ? true : false; @@ -2242,8 +2242,7 @@ gfc_match_close (void) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); warn = (close->iostat || close->err) ? true : false; @@ -2410,8 +2409,7 @@ done: goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); new_st.op = op; new_st.ext.filepos = fp; @@ -3261,9 +3259,8 @@ if (condition) \ "an internal file in a PURE procedure", io_kind_name (k)); - if (gfc_implicit_pure (NULL) && (k == M_READ || k == M_WRITE)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; - + if (k == M_READ || k == M_WRITE) + gfc_unset_implicit_pure (NULL); } if (k != M_READ) @@ -3793,8 +3790,7 @@ gfc_match_print (void) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); return MATCH_YES; } @@ -3953,8 +3949,7 @@ gfc_match_inquire (void) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); new_st.block = gfc_get_code (EXEC_IOLENGTH); terminate_io (code); @@ -4006,8 +4001,7 @@ gfc_match_inquire (void) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (inquire->id != NULL && inquire->pending == NULL) { @@ -4195,8 +4189,7 @@ gfc_match_wait (void) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); new_st.op = EXEC_WAIT; new_st.ext.wait = wait; diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index 171774ce445..4c4609401a0 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -1751,8 +1751,7 @@ gfc_match_critical (void) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (!gfc_notify_std (GFC_STD_F2008, "CRITICAL statement at %C")) return MATCH_ERROR; @@ -2676,8 +2675,7 @@ gfc_match_stopcode (gfc_statement st) goto cleanup; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (st == ST_STOP && gfc_find_state (COMP_CRITICAL)) { @@ -2814,8 +2812,7 @@ lock_unlock_statement (gfc_statement st) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (gfc_option.coarray == GFC_FCOARRAY_NONE) { @@ -3008,8 +3005,7 @@ sync_statement (gfc_statement st) return MATCH_ERROR; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (!gfc_notify_std (GFC_STD_F2008, "SYNC statement at %C")) return MATCH_ERROR; @@ -3479,15 +3475,15 @@ gfc_match_allocate (void) if (gfc_check_do_variable (tail->expr->symtree)) goto cleanup; - if (gfc_pure (NULL) && gfc_impure_variable (tail->expr->symtree->n.sym)) + bool impure = gfc_impure_variable (tail->expr->symtree->n.sym); + if (impure && gfc_pure (NULL)) { gfc_error ("Bad allocate-object at %C for a PURE procedure"); goto cleanup; } - if (gfc_implicit_pure (NULL) - && gfc_impure_variable (tail->expr->symtree->n.sym)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + if (impure) + gfc_unset_implicit_pure (NULL); if (tail->expr->ts.deferred) { @@ -3868,14 +3864,15 @@ gfc_match_deallocate (void) sym = tail->expr->symtree->n.sym; - if (gfc_pure (NULL) && gfc_impure_variable (sym)) + bool impure = gfc_impure_variable (sym); + if (impure && gfc_pure (NULL)) { gfc_error ("Illegal allocate-object at %C for a PURE procedure"); goto cleanup; } - if (gfc_implicit_pure (NULL) && gfc_impure_variable (sym)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + if (impure) + gfc_unset_implicit_pure (NULL); if (gfc_is_coarray (tail->expr) && gfc_find_state (COMP_DO_CONCURRENT)) diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index d9af60e578b..0faf47a0041 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -550,8 +550,7 @@ decode_omp_directive (void) return ST_NONE; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); old_locus = gfc_current_locus; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index bcdfcadd3d1..6e23e570b17 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -1328,9 +1328,10 @@ resolve_structure_cons (gfc_expr *expr, int init) } /* F2003, C1272 (3). */ - if (gfc_pure (NULL) && cons->expr->expr_type == EXPR_VARIABLE - && (gfc_impure_variable (cons->expr->symtree->n.sym) - || gfc_is_coindexed (cons->expr))) + bool impure = cons->expr->expr_type == EXPR_VARIABLE + && (gfc_impure_variable (cons->expr->symtree->n.sym) + || gfc_is_coindexed (cons->expr)); + if (impure && gfc_pure (NULL)) { t = false; gfc_error ("Invalid expression in the structure constructor for " @@ -1338,12 +1339,8 @@ resolve_structure_cons (gfc_expr *expr, int init) comp->name, &cons->expr->where); } - if (gfc_implicit_pure (NULL) - && cons->expr->expr_type == EXPR_VARIABLE - && (gfc_impure_variable (cons->expr->symtree->n.sym) - || gfc_is_coindexed (cons->expr))) - gfc_current_ns->proc_name->attr.implicit_pure = 0; - + if (impure) + gfc_unset_implicit_pure (NULL); } return t; @@ -3006,8 +3003,7 @@ resolve_function (gfc_expr *expr) t = false; } - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); } /* Functions without the RECURSIVE attribution are not allowed to @@ -3072,8 +3068,7 @@ pure_subroutine (gfc_code *c, gfc_symbol *sym) gfc_error ("Subroutine call to '%s' at %L is not PURE", sym->name, &c->loc); - if (gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); } @@ -9170,7 +9165,7 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns) if (lhs->expr_type == EXPR_VARIABLE && lhs->symtree->n.sym != gfc_current_ns->proc_name && lhs->symtree->n.sym->ns != gfc_current_ns) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); if (lhs->ts.type == BT_DERIVED && lhs->expr_type == EXPR_VARIABLE @@ -9178,11 +9173,11 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns) && rhs->expr_type == EXPR_VARIABLE && (gfc_impure_variable (rhs->symtree->n.sym) || gfc_is_coindexed (rhs))) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); /* Fortran 2008, C1283. */ if (gfc_is_coindexed (lhs)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + gfc_unset_implicit_pure (NULL); } /* F2008, 7.2.1.2. */ @@ -13927,6 +13922,33 @@ gfc_implicit_pure (gfc_symbol *sym) } +void +gfc_unset_implicit_pure (gfc_symbol *sym) +{ + gfc_namespace *ns; + + if (sym == NULL) + { + /* Check if the current procedure is implicit_pure. Walk up + the procedure list until we find a procedure. */ + for (ns = gfc_current_ns; ns; ns = ns->parent) + { + sym = ns->proc_name; + if (sym == NULL) + return; + + if (sym->attr.flavor == FL_PROCEDURE) + break; + } + } + + if (sym->attr.flavor == FL_PROCEDURE) + sym->attr.implicit_pure = 0; + else + sym->attr.pure = 0; +} + + /* Test whether the current procedure is elemental or not. */ int diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 66668720b7b..19d792e0862 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -1114,8 +1114,8 @@ gfc_add_save (symbol_attribute *attr, save_state s, const char *name, return false; } - if (s == SAVE_EXPLICIT && gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + if (s == SAVE_EXPLICIT) + gfc_unset_implicit_pure (NULL); if (s == SAVE_EXPLICIT && attr->save == SAVE_EXPLICIT) { diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index dee422cc130..8c4afb098bf 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -4993,12 +4993,14 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset, TYPE_MAX_VALUE (gfc_array_index_type)), size); cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR, - boolean_type_node, tmp, stride)); + boolean_type_node, tmp, stride), + PRED_FORTRAN_OVERFLOW); tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond, integer_one_node, integer_zero_node); cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, size, - gfc_index_zero_node)); + gfc_index_zero_node), + PRED_FORTRAN_SIZE_ZERO); tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond, integer_zero_node, tmp); tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node, @@ -5095,12 +5097,14 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset, size_type_node, TYPE_MAX_VALUE (size_type_node), element_size); cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR, - boolean_type_node, tmp, stride)); + boolean_type_node, tmp, stride), + PRED_FORTRAN_OVERFLOW); tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond, integer_one_node, integer_zero_node); cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, element_size, - build_int_cst (size_type_node, 0))); + build_int_cst (size_type_node, 0)), + PRED_FORTRAN_SIZE_ZERO); tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond, integer_zero_node, tmp); tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node, @@ -5282,7 +5286,8 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, if (dimension) { cond = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR, - boolean_type_node, var_overflow, integer_zero_node)); + boolean_type_node, var_overflow, integer_zero_node), + PRED_FORTRAN_OVERFLOW); tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, error, gfc_finish_block (&elseblock)); } @@ -5303,7 +5308,8 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, build_int_cst (TREE_TYPE (status), 0)); gfc_add_expr_to_block (&se->pre, fold_build3_loc (input_location, COND_EXPR, void_type_node, - gfc_likely (cond), set_descriptor, + gfc_likely (cond, PRED_FORTRAN_FAIL_ALLOC), + set_descriptor, build_empty_stmt (input_location))); } else diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 269fcc5c86c..f5350bb5ba9 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -4099,7 +4099,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, parmse.expr = fold_build3_loc (input_location, COND_EXPR, TREE_TYPE (parmse.expr), - gfc_unlikely (tmp), + gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY), fold_convert (TREE_TYPE (parmse.expr), null_pointer_node), parmse.expr); diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 75bd20ae04a..e21d52fece9 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -1196,8 +1196,7 @@ trans_image_index (gfc_se * se, gfc_expr *expr) boolean_type_node, invalid_bound, cond); } - invalid_bound = gfc_unlikely (invalid_bound); - + invalid_bound = gfc_unlikely (invalid_bound, PRED_FORTRAN_INVALID_BOUND); /* See Fortran 2008, C.10 for the following algorithm. */ diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c index 853e77d62f5..d15159857d0 100644 --- a/gcc/fortran/trans-io.c +++ b/gcc/fortran/trans-io.c @@ -230,9 +230,10 @@ gfc_build_st_parameter (enum ioparam_type ptype, tree *types) Therefore, the code to set these flags must be generated before this function is used. */ -void -gfc_trans_io_runtime_check (tree cond, tree var, int error_code, - const char * msgid, stmtblock_t * pblock) +static void +gfc_trans_io_runtime_check (bool has_iostat, tree cond, tree var, + int error_code, const char * msgid, + stmtblock_t * pblock) { stmtblock_t block; tree body; @@ -246,6 +247,13 @@ gfc_trans_io_runtime_check (tree cond, tree var, int error_code, /* The code to generate the error. */ gfc_start_block (&block); + if (has_iostat) + gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_FAIL_IO, + NOT_TAKEN)); + else + gfc_add_expr_to_block (&block, build_predict_expr (PRED_NORETURN, + NOT_TAKEN)); + arg1 = gfc_build_addr_expr (NULL_TREE, var); arg2 = build_int_cst (integer_type_node, error_code), @@ -268,7 +276,6 @@ gfc_trans_io_runtime_check (tree cond, tree var, int error_code, } else { - cond = gfc_unlikely (cond); tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt (input_location)); gfc_add_expr_to_block (pblock, tmp); } @@ -494,8 +501,8 @@ set_parameter_const (stmtblock_t *block, tree var, enum iofield type, st_parameter_XXX structure. This is a pass by value. */ static unsigned int -set_parameter_value (stmtblock_t *block, tree var, enum iofield type, - gfc_expr *e) +set_parameter_value (stmtblock_t *block, bool has_iostat, tree var, + enum iofield type, gfc_expr *e) { gfc_se se; tree tmp; @@ -520,18 +527,18 @@ set_parameter_value (stmtblock_t *block, tree var, enum iofield type, cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, se.expr, fold_convert (TREE_TYPE (se.expr), val)); - gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT, - "Unit number in I/O statement too small", - &se.pre); + gfc_trans_io_runtime_check (has_iostat, cond, var, LIBERROR_BAD_UNIT, + "Unit number in I/O statement too small", + &se.pre); /* UNIT numbers should be less than the max. */ val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4); cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, se.expr, fold_convert (TREE_TYPE (se.expr), val)); - gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT, - "Unit number in I/O statement too large", - &se.pre); + gfc_trans_io_runtime_check (has_iostat, cond, var, LIBERROR_BAD_UNIT, + "Unit number in I/O statement too large", + &se.pre); } @@ -960,7 +967,8 @@ gfc_trans_open (gfc_code * code) mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form); if (p->recl) - mask |= set_parameter_value (&block, var, IOPARM_open_recl_in, p->recl); + mask |= set_parameter_value (&block, p->iostat, var, IOPARM_open_recl_in, + p->recl); if (p->blank) mask |= set_string (&block, &post_block, var, IOPARM_open_blank, @@ -1010,7 +1018,7 @@ gfc_trans_open (gfc_code * code) set_parameter_const (&block, var, IOPARM_common_flags, mask); if (p->unit) - set_parameter_value (&block, var, IOPARM_common_unit, p->unit); + set_parameter_value (&block, p->iostat, var, IOPARM_common_unit, p->unit); else set_parameter_const (&block, var, IOPARM_common_unit, 0); @@ -1063,7 +1071,7 @@ gfc_trans_close (gfc_code * code) set_parameter_const (&block, var, IOPARM_common_flags, mask); if (p->unit) - set_parameter_value (&block, var, IOPARM_common_unit, p->unit); + set_parameter_value (&block, p->iostat, var, IOPARM_common_unit, p->unit); else set_parameter_const (&block, var, IOPARM_common_unit, 0); @@ -1114,7 +1122,7 @@ build_filepos (tree function, gfc_code * code) set_parameter_const (&block, var, IOPARM_common_flags, mask); if (p->unit) - set_parameter_value (&block, var, IOPARM_common_unit, p->unit); + set_parameter_value (&block, p->iostat, var, IOPARM_common_unit, p->unit); else set_parameter_const (&block, var, IOPARM_common_unit, 0); @@ -1375,7 +1383,7 @@ gfc_trans_inquire (gfc_code * code) set_parameter_const (&block, var, IOPARM_common_flags, mask); if (p->unit) - set_parameter_value (&block, var, IOPARM_common_unit, p->unit); + set_parameter_value (&block, p->iostat, var, IOPARM_common_unit, p->unit); else set_parameter_const (&block, var, IOPARM_common_unit, 0); @@ -1422,12 +1430,12 @@ gfc_trans_wait (gfc_code * code) mask |= IOPARM_common_err; if (p->id) - mask |= set_parameter_value (&block, var, IOPARM_wait_id, p->id); + mask |= set_parameter_value (&block, p->iostat, var, IOPARM_wait_id, p->id); set_parameter_const (&block, var, IOPARM_common_flags, mask); if (p->unit) - set_parameter_value (&block, var, IOPARM_common_unit, p->unit); + set_parameter_value (&block, p->iostat, var, IOPARM_common_unit, p->unit); tmp = gfc_build_addr_expr (NULL_TREE, var); tmp = build_call_expr_loc (input_location, @@ -1718,7 +1726,8 @@ build_dt (tree function, gfc_code * code) IOPARM_dt_id, dt->id); if (dt->pos) - mask |= set_parameter_value (&block, var, IOPARM_dt_pos, dt->pos); + mask |= set_parameter_value (&block, dt->iostat, var, IOPARM_dt_pos, + dt->pos); if (dt->asynchronous) mask |= set_string (&block, &post_block, var, IOPARM_dt_asynchronous, @@ -1749,7 +1758,8 @@ build_dt (tree function, gfc_code * code) dt->sign); if (dt->rec) - mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec); + mask |= set_parameter_value (&block, dt->iostat, var, IOPARM_dt_rec, + dt->rec); if (dt->advance) mask |= set_string (&block, &post_block, var, IOPARM_dt_advance, @@ -1801,7 +1811,8 @@ build_dt (tree function, gfc_code * code) set_parameter_const (&block, var, IOPARM_common_flags, mask); if (dt->io_unit && dt->io_unit->ts.type == BT_INTEGER) - set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit); + set_parameter_value (&block, dt->iostat, var, IOPARM_common_unit, + dt->io_unit); } else set_parameter_const (&block, var, IOPARM_common_flags, mask); diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index c7ff7a8cb8e..1a9068c0f46 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -5107,8 +5107,8 @@ gfc_trans_allocate (gfc_code * code) boolean_type_node, stat, build_int_cst (TREE_TYPE (stat), 0)); tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, - gfc_unlikely (parm), tmp, - build_empty_stmt (input_location)); + gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC), + tmp, build_empty_stmt (input_location)); gfc_add_expr_to_block (&block, tmp); } @@ -5501,7 +5501,7 @@ gfc_trans_deallocate (gfc_code *code) cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat, build_int_cst (TREE_TYPE (stat), 0)); tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, - gfc_unlikely (cond), + gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), build1_v (GOTO_EXPR, label_errmsg), build_empty_stmt (input_location)); gfc_add_expr_to_block (&se.pre, tmp); @@ -5541,7 +5541,7 @@ gfc_trans_deallocate (gfc_code *code) cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat, build_int_cst (TREE_TYPE (stat), 0)); tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, - gfc_unlikely (cond), tmp, + gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp, build_empty_stmt (input_location)); gfc_add_expr_to_block (&block, tmp); diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index 073e34f0eb5..5961c267e8c 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -501,6 +501,11 @@ gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock, gfc_start_block (&block); + /* For error, runtime_error_at already implies PRED_NORETURN. */ + if (!error && once) + gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE, + NOT_TAKEN)); + /* The code to generate the error. */ va_start (ap, msgid); gfc_add_expr_to_block (&block, @@ -519,14 +524,12 @@ gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock, } else { - /* Tell the compiler that this isn't likely. */ if (once) cond = fold_build2_loc (where->lb->location, TRUTH_AND_EXPR, long_integer_type_node, tmpvar, cond); else cond = fold_convert (long_integer_type_node, cond); - cond = gfc_unlikely (cond); tmp = fold_build3_loc (where->lb->location, COND_EXPR, void_type_node, cond, body, build_empty_stmt (where->lb->location)); @@ -616,7 +619,8 @@ void gfc_allocate_using_malloc (stmtblock_t * block, tree pointer, tree size, tree status) { - tree tmp, on_error, error_cond; + tree tmp, error_cond; + stmtblock_t on_error; tree status_type = status ? TREE_TYPE (status) : NULL_TREE; /* Evaluate size only once, and make sure it has the right type. */ @@ -640,20 +644,31 @@ gfc_allocate_using_malloc (stmtblock_t * block, tree pointer, build_int_cst (size_type_node, 1))))); /* What to do in case of error. */ + gfc_start_block (&on_error); if (status != NULL_TREE) - on_error = fold_build2_loc (input_location, MODIFY_EXPR, status_type, - status, build_int_cst (status_type, LIBERROR_ALLOCATION)); + { + gfc_add_expr_to_block (&on_error, + build_predict_expr (PRED_FORTRAN_FAIL_ALLOC, + NOT_TAKEN)); + tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status, + build_int_cst (status_type, LIBERROR_ALLOCATION)); + gfc_add_expr_to_block (&on_error, tmp); + } else - on_error = build_call_expr_loc (input_location, gfor_fndecl_os_error, 1, + { + /* Here, os_error already implies PRED_NORETURN. */ + tmp = build_call_expr_loc (input_location, gfor_fndecl_os_error, 1, gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const - ("Allocation would exceed memory limit"))); + ("Allocation would exceed memory limit"))); + gfc_add_expr_to_block (&on_error, tmp); + } error_cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pointer, build_int_cst (prvoid_type_node, 0)); tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, - gfc_unlikely (error_cond), on_error, + error_cond, gfc_finish_block (&on_error), build_empty_stmt (input_location)); gfc_add_expr_to_block (block, tmp); @@ -750,7 +765,8 @@ gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size, tree token, null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR, boolean_type_node, mem, - build_int_cst (type, 0))); + build_int_cst (type, 0)), + PRED_FORTRAN_FAIL_ALLOC); /* If mem is NULL, we call gfc_allocate_using_malloc or gfc_allocate_using_lib. */ @@ -770,8 +786,8 @@ gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size, tree token, cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, status, build_zero_cst (TREE_TYPE (status))); tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, - gfc_unlikely (cond), tmp, - build_empty_stmt (input_location)); + gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), + tmp, build_empty_stmt (input_location)); gfc_add_expr_to_block (&alloc_block, tmp); } } @@ -1268,8 +1284,8 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg, status_type, status), build_int_cst (status_type, 0)); tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, - gfc_unlikely (cond2), tmp, - build_empty_stmt (input_location)); + gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC), + tmp, build_empty_stmt (input_location)); gfc_add_expr_to_block (&non_null, tmp); } } @@ -1327,8 +1343,8 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg, cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat, build_zero_cst (TREE_TYPE (stat))); tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, - gfc_unlikely (cond2), tmp, - build_empty_stmt (input_location)); + gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC), + tmp, build_empty_stmt (input_location)); gfc_add_expr_to_block (&non_null, tmp); } } @@ -2015,15 +2031,20 @@ gfc_finish_wrapped_block (gfc_wrapped_block* block) /* Helper function for marking a boolean expression tree as unlikely. */ tree -gfc_unlikely (tree cond) +gfc_unlikely (tree cond, enum br_predictor predictor) { tree tmp; - cond = fold_convert (long_integer_type_node, cond); - tmp = build_zero_cst (long_integer_type_node); - cond = build_call_expr_loc (input_location, - builtin_decl_explicit (BUILT_IN_EXPECT), - 2, cond, tmp); + if (optimize) + { + cond = fold_convert (long_integer_type_node, cond); + tmp = build_zero_cst (long_integer_type_node); + cond = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_EXPECT), + 3, cond, tmp, + build_int_cst (integer_type_node, + predictor)); + } cond = fold_convert (boolean_type_node, cond); return cond; } @@ -2032,15 +2053,20 @@ gfc_unlikely (tree cond) /* Helper function for marking a boolean expression tree as likely. */ tree -gfc_likely (tree cond) +gfc_likely (tree cond, enum br_predictor predictor) { tree tmp; - cond = fold_convert (long_integer_type_node, cond); - tmp = build_one_cst (long_integer_type_node); - cond = build_call_expr_loc (input_location, - builtin_decl_explicit (BUILT_IN_EXPECT), - 2, cond, tmp); + if (optimize) + { + cond = fold_convert (long_integer_type_node, cond); + tmp = build_one_cst (long_integer_type_node); + cond = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_EXPECT), + 3, cond, tmp, + build_int_cst (integer_type_node, + predictor)); + } cond = fold_convert (boolean_type_node, cond); return cond; } diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 5fb0cbf2289..4ae68c6cb85 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see #ifndef GFC_TRANS_H #define GFC_TRANS_H +#include "predict.h" /* For enum br_predictor and PRED_*. */ + /* Mangled symbols take the form __module__name. */ #define GFC_MAX_MANGLED_SYMBOL_LEN (GFC_MAX_SYMBOL_LEN*2+4) @@ -580,8 +582,8 @@ void gfc_generate_constructors (void); bool get_array_ctor_strlen (stmtblock_t *, gfc_constructor_base, tree *); /* Mark a condition as likely or unlikely. */ -tree gfc_likely (tree); -tree gfc_unlikely (tree); +tree gfc_likely (tree, enum br_predictor); +tree gfc_unlikely (tree, enum br_predictor); /* Return the string length of a deferred character length component. */ bool gfc_deferred_strlen (gfc_component *, tree *); @@ -630,7 +632,6 @@ tree gfc_trans_pointer_assignment (gfc_expr *, gfc_expr *); /* Initialize function decls for library functions. */ void gfc_build_intrinsic_lib_fndecls (void); /* Create function decls for IO library functions. */ -void gfc_trans_io_runtime_check (tree, tree, int, const char *, stmtblock_t *); void gfc_build_io_library_fndecls (void); /* Build a function decl for a library function. */ tree gfc_build_library_function_decl (tree, tree, int, ...); |