summaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2014-03-25 10:33:25 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2014-03-25 10:33:25 +0000
commit3013aa3871d2c0acdb579923ab997d9367a637e8 (patch)
treed397a166338c88f9fb0d5f6f5302efcae20d8bd9 /gcc/fortran
parent63f3c6bcb4f99fa87d29566c1ffdae7e7323eb73 (diff)
downloadgcc-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/ChangeLog67
-rw-r--r--gcc/fortran/cpp.c1
-rw-r--r--gcc/fortran/decl.c21
-rw-r--r--gcc/fortran/expr.c3
-rw-r--r--gcc/fortran/gfortran.h1
-rw-r--r--gcc/fortran/gfortran.texi6
-rw-r--r--gcc/fortran/intrinsic.c5
-rw-r--r--gcc/fortran/io.c33
-rw-r--r--gcc/fortran/match.c27
-rw-r--r--gcc/fortran/parse.c3
-rw-r--r--gcc/fortran/resolve.c54
-rw-r--r--gcc/fortran/symbol.c4
-rw-r--r--gcc/fortran/trans-array.c18
-rw-r--r--gcc/fortran/trans-expr.c2
-rw-r--r--gcc/fortran/trans-intrinsic.c3
-rw-r--r--gcc/fortran/trans-io.c55
-rw-r--r--gcc/fortran/trans-stmt.c8
-rw-r--r--gcc/fortran/trans.c80
-rw-r--r--gcc/fortran/trans.h7
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, ...);