public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/5] function result decl location; type demotion
@ 2022-11-12 23:45 Bernhard Reutner-Fischer
  2022-11-12 23:45 ` [PATCH 1/5] c: Set the locus of the function result decl Bernhard Reutner-Fischer
                   ` (4 more replies)
  0 siblings, 5 replies; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2022-11-12 23:45 UTC (permalink / raw)
  To: gcc-patches
  Cc: Bernhard Reutner-Fischer, Bernhard Reutner-Fischer, fortran,
	David Malcolm, Aldy Hernandez, Jason Merrill

Hi!

The location of function result declarations was not set.
The first two patches set the location of normal functions in C and C++.

Jason, Nathan, I failed to support C++ template functions, see below.

TL;DR.
Why all this?
PR78798 noted that we should use narrower function return types if feasable.

So one idea to bring that idea forward is to determine the range a
function can return and match that range against the range provided by
the actual return type. If we waste bits, warn and, ideally, suggest a
better alternative. Ideally with a fix-it hint for the narrower type and
with a patch.
David's tremendously useful work on diagnostics makes both user-facing
aspecs rather easy to achieve (thanks, once again, David!).
Ideally, one would be able to accumulate such suggested fix-it hints
driven patches by stating something like:
  ... -Wtype-demotion -fdiagnostics-generate-patch=>>/tmp/hmz.patch
i.e. have ways to direct the ...-generate-patch to creat/append to some
given path. But that doesn't seem to work for me or i did not read the
documentation carefully enough. awk to the rescue for the full buildlog
output to extract the patch(es) but not all that userfriendly i fear.
How would i write a combined patch out to some given path, David?

Patch 1 handles locations for the C FE, this works perfectly fine.

Patch 2 handles locations for normal, non-template functions in C++
and these work fine, too.

Patch 3, the actual Fortran bits work fine and are sound (good job, Aldy
and Andrew!)

Patch 4 is a way to print the actual range to some diagnostics.
I wrote this about a year ago when only irange was available.
And from what i've heared, it's doubtful if such an as_string() is
considered useful. So i post it just for reference and don't ask for
inclusion of such a facility. Nevertheless i think that would be useful
if not just for debugging and dumping (but please to a buffer, too, so
one can hijack it ;)

Patch5 is not to be merged for obvious reasons. It is way too chatty,
doesn't run in IPA so probably ruins any "comparer" like function.
I've compiled one or two userspace, integer programs and it is not
completely off, from the looks.


C++ template functions.
=======================
I couldn't make this work, the mechanics in start_preparsed_function are
beyond what i could grok in a couple of evenings TBH.

Can you maybe help, Json or Nathan?

I tried several spots.
Directly in start_preparsed_function, in grokmethod, grokfndecl after
type = build_cp_fntype_variant, in grokfndecl if (funcdef_flag), in
finish_function but to no avail.
To me it seems that most locations are unset/ broken in the C++ FE for
the template path, or, more likely, i'm unable to operate them properly
to be fair.
I even tried the enterprise-level idea to get something vaguely around
the result decl in a template by (please don't cite me):

@@ -18214,6 +18260,17 @@ grokmethod (cp_decl_specifier_seq *declspecs,
       DECL_NO_INLINE_WARNING_P (fndecl) = 1;
     }
 
+  /* Set the location of the result decl, approximately.  */
+  tree result;
+  if ((result = DECL_RESULT (fndecl))
+      && DECL_SOURCE_LOCATION (result) == UNKNOWN_LOCATION)
+    for (int i = (int)ds_first; i != (int)ds_last; ++i)
+      if (location_t loc = declspecs->locations[i])
+       {
+         DECL_SOURCE_LOCATION (result) = loc;
+         break;
+       }
+

but there's nothing much there in my POV?

My C++ template based testcase was this:

$ cat return-narrow-2.cc ; echo EOF
namespace std { template < typename, typename > struct pair; }
template < typename > struct __mini_vector
{
  int _M_finish;
  unsigned long
  _M_space_left()
  { return _M_finish != 0; }
};
 template class __mini_vector< std::pair< long, long > >;
 template class __mini_vector< int >;
EOF

Where the locations are all confused (maybe a tad different on trunk):
$ ../gcc/xg++ -B../gcc -c -o /tmp/foo.o return-narrow-2.cc -O -Wtype-demotion
return-narrow-2.cc: In member function ‘long unsigned int __mini_vector< <template-parameter-1-1> >::_M_space_left() [with <template-parameter-1-1> = std::pair<long int, long int>]’:
return-narrow-2.cc:6:3: warning: Function ‘_M_space_left’ could return ‘bool’ [-Wtype-demotion]
    6 |   _M_space_left()
      |   ^~~~~~~~~~~~~
      |   bool
return-narrow-2.cc:6:3: note: with a range of [0,1]
return-narrow-2.cc: In member function ‘long unsigned int __mini_vector< <template-parameter-1-1> >::_M_space_left() [with <template-parameter-1-1> = int]’:
return-narrow-2.cc:6:3: warning: Function ‘_M_space_left’ could return ‘bool’ [-Wtype-demotion]
    6 |   _M_space_left()
      |   ^~~~~~~~~~~~~
      |   bool
return-narrow-2.cc:6:3: note: with a range of [0,1]


The normal C function and C++ function (non-template) dummy tests are all
fine and work as i had expected:
$ cat return-narrow.cc ; echo EOF
int xyz (int param1, int param2, int param3)
{
	if (param1 == 42)
		return 1;
	if (param2 == 17)
		return 1;
	if (param3 == 99)
		return 1;
	return 0;
}
int abc (int param1, int param2, int param3)
{
	if (param1 == 42)
		return 0;
	if (param2 == 17)
		return 0;
	if (param3 == 99)
		return 0;
	return 0;
}
const void *const * pointer_thingie (void *i)
{
	return (const void *const *)((long)i & 1);
}
int comparer (int param1, int param2, int param3) /* signed char */
{
	if (param1 >= 42)
		return 1;
	if (param2 == 17)
		return 1;
	if (param3 <= 99)
		return -1;
	return 0;
}
int
zero_to_two (int i) /* suggest: unsigned char */
{
  if (i < 0)
    return 0;
  if (i > 0)
    return 2;
  return 0;
}
int main (void) // dg-bogus "Function .main. could return .bool."
{
	return 0;
}


_Pragma("GCC visibility push(hidden)")
int my_main (int argc, char**argv) __attribute__(( visibility("default") ));
int my_main (int, char**) { return 0; }
int hidden_main (int, char**) { return 1; }
_Pragma("GCC visibility pop")


int i64c(int i)
{ /* returns [46,122] */
	i &= 0x3f;
	if (i == 0)
		return '.';
	if (i == 1)
		return '/';
	if (i < 12)
		return ('0' - 2 + i);
	if (i < 38)
		return ('A' - 12 + i);
	return ('a' - 38 + i);
}


EOF

Which gives for the normal C-flavour hunks:

$ ../gcc/xg++ -B../gcc -c -o /tmp/foo.o return-narrow.cc -O1 -Wall
return-narrow.cc: In function ‘int xyz(int, int, int)’:
return-narrow.cc:1:1: warning: Function ‘xyz’ could return ‘bool’ [-Wtype-demotion]
    1 | int xyz (int param1, int param2, int param3)
      | ^~~
      | bool
return-narrow.cc:1:1: note: with a range of [0,1]
return-narrow.cc: In function ‘int abc(int, int, int)’:
return-narrow.cc:11:1: warning: Function ‘abc’ could return ‘bool’ [-Wtype-demotion]
   11 | int abc (int param1, int param2, int param3)
      | ^~~
      | bool
return-narrow.cc:11:1: note: with a range of [0,0]
return-narrow.cc: In function ‘const void* const* pointer_thingie(void*)’:
return-narrow.cc:21:7: warning: Function ‘pointer_thingie’ could return ‘bool’ [-Wtype-demotion]
   21 | const void *const * pointer_thingie (void *i)
      |       ^~~~
      |       bool
return-narrow.cc:21:7: note: with a range of [0B,1B]
return-narrow.cc: In function ‘int comparer(int, int, int)’:
return-narrow.cc:25:1: warning: Function ‘comparer’ could return ‘signed char’ [-Wtype-demotion]
   25 | int comparer (int param1, int param2, int param3) /* signed char */
      | ^~~
      | signed char
return-narrow.cc:25:1: note: with a range of [-1,1]
return-narrow.cc: In function ‘int zero_to_two(int)’:
return-narrow.cc:35:1: warning: Function ‘zero_to_two’ could return ‘unsigned char’ [-Wtype-demotion]
   35 | int
      | ^~~
      | unsigned char
return-narrow.cc:35:1: note: with a range of [0,2]
return-narrow.cc: In function ‘int my_main(int, char**)’:
return-narrow.cc:51:1: warning: Function ‘my_main’ could return ‘bool’ [-Wtype-demotion]
   51 | int my_main (int, char**) { return 0; }
      | ^~~
      | bool
return-narrow.cc:51:1: note: with a range of [0,0]
return-narrow.cc: In function ‘int hidden_main(int, char**)’:
return-narrow.cc:52:1: warning: Function ‘hidden_main’ could return ‘bool’ [-Wtype-demotion]
   52 | int hidden_main (int, char**) { return 1; }
      | ^~~
      | bool
return-narrow.cc:52:1: note: with a range of [1,1]
return-narrow.cc: In function ‘int i64c(int)’:
return-narrow.cc:55:1: warning: Function ‘i64c’ could return ‘unsigned char’ [-Wtype-demotion]
   55 | int i64c(int i)
      | ^~~
      | unsigned char
return-narrow.cc:55:1: note: with a range of [46,122]

So, any help wrt the template case? -- many TIA!


Bernhard Reutner-Fischer (5):
  c: Set the locus of the function result decl
  c++: Set the locus of the function result decl
  Fortran: Narrow return types [PR78798]
  value-range: Add as_string diagnostics helper
  gimple: Add pass to note possible type demotions; IPA pro/demotion

 gcc/Makefile.in              |   1 +
 gcc/c-family/c.opt           |   6 +
 gcc/c/c-decl.cc              |   6 +-
 gcc/cp/decl.cc               |  15 +-
 gcc/fortran/arith.cc         |   4 +-
 gcc/fortran/arith.h          |   4 +-
 gcc/fortran/array.cc         |   8 +-
 gcc/fortran/check.cc         |   2 +-
 gcc/fortran/cpp.cc           |   3 +-
 gcc/fortran/cpp.h            |   2 +-
 gcc/fortran/dependency.cc    |   8 +-
 gcc/fortran/dependency.h     |   6 +-
 gcc/fortran/expr.cc          |   6 +-
 gcc/fortran/gfortran.h       |  51 ++--
 gcc/fortran/intrinsic.cc     |   6 +-
 gcc/fortran/io.cc            |  13 +-
 gcc/fortran/misc.cc          |   2 +-
 gcc/fortran/parse.cc         |   2 +-
 gcc/fortran/parse.h          |   2 +-
 gcc/fortran/primary.cc       |   4 +-
 gcc/fortran/resolve.cc       |  22 +-
 gcc/fortran/scanner.cc       |  20 +-
 gcc/fortran/symbol.cc        |   2 +-
 gcc/fortran/target-memory.cc |   6 +-
 gcc/fortran/trans-array.cc   |   2 +-
 gcc/fortran/trans-decl.cc    |   2 +-
 gcc/fortran/trans-types.cc   |   6 +-
 gcc/fortran/trans-types.h    |   6 +-
 gcc/fortran/trans.h          |   2 +-
 gcc/gimple-warn-types.cc     | 441 +++++++++++++++++++++++++++++++++++
 gcc/passes.def               |   1 +
 gcc/tree-pass.h              |   1 +
 gcc/value-range.cc           |  56 +++++
 gcc/value-range.h            |   3 +
 34 files changed, 618 insertions(+), 103 deletions(-)
 create mode 100644 gcc/gimple-warn-types.cc

-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/5] c: Set the locus of the function result decl
  2022-11-12 23:45 [PATCH 0/5] function result decl location; type demotion Bernhard Reutner-Fischer
@ 2022-11-12 23:45 ` Bernhard Reutner-Fischer
  2022-11-14 21:25   ` Joseph Myers
  2022-11-12 23:45 ` [PATCH 2/5] c++: " Bernhard Reutner-Fischer
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2022-11-12 23:45 UTC (permalink / raw)
  To: gcc-patches
  Cc: Bernhard Reutner-Fischer, Bernhard Reutner-Fischer, fortran,
	Joseph Myers

Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
Ok for trunk?

Cc: Joseph Myers <joseph@codesourcery.com>
---
gcc/c/ChangeLog:

	* c-decl.cc (start_function): Set the result decl source
	location to the location of the typespec.
---
 gcc/c/c-decl.cc | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index a99b7456055..5250cb96c41 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9980,6 +9980,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   tree decl1, old_decl;
   tree restype, resdecl;
   location_t loc;
+  location_t result_loc;
 
   current_function_returns_value = 0;  /* Assume, until we see it does.  */
   current_function_returns_null = 0;
@@ -10206,8 +10207,11 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   push_scope ();
   declare_parm_level ();
 
+  /* Set the result decl source location to the location of the typespec.  */
+  result_loc = (declspecs->locations[cdw_typespec] == UNKNOWN_LOCATION
+		? loc : declspecs->locations[cdw_typespec]);
   restype = TREE_TYPE (TREE_TYPE (current_function_decl));
-  resdecl = build_decl (loc, RESULT_DECL, NULL_TREE, restype);
+  resdecl = build_decl (result_loc, RESULT_DECL, NULL_TREE, restype);
   DECL_ARTIFICIAL (resdecl) = 1;
   DECL_IGNORED_P (resdecl) = 1;
   DECL_RESULT (current_function_decl) = resdecl;
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 2/5] c++: Set the locus of the function result decl
  2022-11-12 23:45 [PATCH 0/5] function result decl location; type demotion Bernhard Reutner-Fischer
  2022-11-12 23:45 ` [PATCH 1/5] c: Set the locus of the function result decl Bernhard Reutner-Fischer
@ 2022-11-12 23:45 ` Bernhard Reutner-Fischer
  2022-11-15 23:52   ` Jason Merrill
  2022-11-12 23:45 ` [PATCH 3/5] Fortran: Narrow return types [PR78798] Bernhard Reutner-Fischer
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2022-11-12 23:45 UTC (permalink / raw)
  To: gcc-patches
  Cc: Bernhard Reutner-Fischer, Bernhard Reutner-Fischer, fortran,
	Nathan Sidwell, Jason Merrill

gcc/cp/ChangeLog:

	* decl.cc (start_function): Set the result decl source location to
	the location of the typespec.

---
Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
Ok for trunk?

Cc: Nathan Sidwell <nathan@acm.org>
Cc: Jason Merrill <jason@redhat.com>
---
 gcc/cp/decl.cc | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 6e98ea35a39..ed40815e645 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17449,6 +17449,8 @@ start_function (cp_decl_specifier_seq *declspecs,
 		tree attrs)
 {
   tree decl1;
+  tree result;
+  bool ret;
 
   decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
   invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
@@ -17461,7 +17463,18 @@ start_function (cp_decl_specifier_seq *declspecs,
     gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
 			     integer_type_node));
 
-  return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
+  ret = start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
+
+  /* decl1 might be ggc_freed here.  */
+  decl1 = current_function_decl;
+
+  /* Set the result decl source location to the location of the typespec.  */
+  if (TREE_CODE (decl1) == FUNCTION_DECL
+      && declspecs->locations[ds_type_spec] != UNKNOWN_LOCATION
+      && (result = DECL_RESULT (decl1)) != NULL_TREE
+      && DECL_SOURCE_LOCATION (result) == input_location)
+    DECL_SOURCE_LOCATION (result) = declspecs->locations[ds_type_spec];
+  return ret;
 }
 \f
 /* Returns true iff an EH_SPEC_BLOCK should be created in the body of
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 3/5] Fortran: Narrow return types [PR78798]
  2022-11-12 23:45 [PATCH 0/5] function result decl location; type demotion Bernhard Reutner-Fischer
  2022-11-12 23:45 ` [PATCH 1/5] c: Set the locus of the function result decl Bernhard Reutner-Fischer
  2022-11-12 23:45 ` [PATCH 2/5] c++: " Bernhard Reutner-Fischer
@ 2022-11-12 23:45 ` Bernhard Reutner-Fischer
  2022-11-13 10:13   ` Janne Blomqvist
  2022-11-12 23:45 ` [PATCH 4/5] value-range: Add as_string diagnostics helper Bernhard Reutner-Fischer
  2022-11-12 23:45 ` [PATCH 5/5] gimple: Add pass to note possible type demotions; IPA pro/demotion; DO NOT MERGE Bernhard Reutner-Fischer
  4 siblings, 1 reply; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2022-11-12 23:45 UTC (permalink / raw)
  To: gcc-patches; +Cc: Bernhard Reutner-Fischer, Bernhard Reutner-Fischer, fortran

gcc/fortran/ChangeLog:

	* arith.cc (compare_complex): Use narrower return type.
	(gfc_compare_string): Likewise.
	* arith.h (gfc_compare_string): Same.
	(gfc_compare_with_Cstring): Ditto.
	* array.cc (compare_bounds): Ditto.
	(gfc_compare_array_spec): Likewise.
	(is_constant_element): Likewise.
	(gfc_constant_ac): Likewise.
	* check.cc (dim_rank_check): Likewise.
	* cpp.cc (gfc_cpp_init_options): Likewise.
	(dump_macro): Likewise.
	* cpp.h (gfc_cpp_handle_option): Likewise.
	* dependency.cc (gfc_ref_needs_temporary_p): Likewise.
	(gfc_check_argument_dependency): Likewise.
	(gfc_check_fncall_dependency): Likewise.
	(ref_same_as_full_array): Likewise.
	* dependency.h (gfc_check_fncall_dependency): Likewise.
	(gfc_dep_resolver): Likewise.
	(gfc_are_equivalenced_arrays): Likewise.
	* expr.cc (gfc_copy_ref): Likewise.
	(gfc_kind_max): Likewise.
	(numeric_type): Likewise.
	* gfortran.h (gfc_at_end): Likewise.
	(gfc_at_eof): Likewise.
	(gfc_at_bol): Likewise.
	(gfc_at_eol): Likewise.
	(gfc_check_include): Likewise.
	(gfc_define_undef_line): Likewise.
	(gfc_wide_is_printable): Likewise.
	(gfc_wide_is_digit): Likewise.
	(gfc_wide_fits_in_byte): Likewise.
	(get_c_kind): Likewise.
	(gfc_find_sym_tree): Likewise.
	(gfc_generic_intrinsic): Likewise.
	(gfc_specific_intrinsic): Likewise.
	(gfc_intrinsic_actual_ok): Likewise.
	(gfc_has_vector_index): Likewise.
	(gfc_numeric_ts): Likewise.
	(gfc_impure_variable): Likewise.
	(gfc_pure): Likewise.
	(gfc_implicit_pure): Likewise.
	(gfc_elemental): Likewise.
	(gfc_pure_function): Likewise.
	(gfc_implicit_pure_function): Likewise.
	(gfc_compare_array_spec): Likewise.
	(gfc_constant_ac): Likewise.
	(gfc_expanded_ac): Likewise.
	(gfc_check_digit): Likewise.
	* intrinsic.cc (gfc_find_subroutine): Likewise.
	(gfc_generic_intrinsic): Likewise.
	(gfc_specific_intrinsic): Likewise.
	* io.cc (compare_to_allowed_values): Likewise.
	* misc.cc (gfc_done_2): Likewise.
	* parse.cc: Likewise.
	* parse.h (gfc_check_do_variable): Likewise.
	* primary.cc (gfc_check_digit): Likewise.
	* resolve.cc (resolve_structure_cons): Likewise.
	(pure_stmt_function): Likewise.
	(gfc_pure_function): Likewise.
	(impure_stmt_fcn): Likewise.
	(resolve_forall_iterators): Likewise.
	(resolve_data): Likewise.
	(gfc_impure_variable): Likewise.
	(gfc_pure): Likewise.
	(gfc_unset_implicit_pure): Likewise.
	* scanner.cc (wide_is_ascii): Likewise.
	(gfc_wide_toupper): Likewise.
	(gfc_open_included_file): Likewise.
	(gfc_at_end): Likewise.
	(gfc_at_eof): Likewise.
	(gfc_at_bol): Likewise.
	(skip_comment_line): Likewise.
	(gfc_gobble_whitespace): Likewise.
	* symbol.cc (gfc_find_symtree_in_proc): Likewise.
	* target-memory.cc (size_integer): Likewise.
	(size_complex): Likewise.
	* trans-array.cc: Likewise.
	* trans-decl.cc (gfc_set_decl_assembler_name): Likewise.
	* trans-types.cc (gfc_get_element_type): Likewise.
	(gfc_add_field_to_struct): Likewise.
	* trans-types.h (gfc_copy_dt_decls_ifequal): Likewise.
	(gfc_return_by_reference): Likewise.
	(gfc_is_nodesc_array): Likewise.
	* trans.h (gfc_can_put_var_on_stack): Likewise.
---
Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
Ok for trunk?

Cc: fortran@gcc.gnu.org
---
 gcc/fortran/arith.cc         |  4 +--
 gcc/fortran/arith.h          |  4 +--
 gcc/fortran/array.cc         |  8 +++---
 gcc/fortran/check.cc         |  2 +-
 gcc/fortran/cpp.cc           |  3 +--
 gcc/fortran/cpp.h            |  2 +-
 gcc/fortran/dependency.cc    |  8 +++---
 gcc/fortran/dependency.h     |  6 ++---
 gcc/fortran/expr.cc          |  6 ++---
 gcc/fortran/gfortran.h       | 51 ++++++++++++++++++------------------
 gcc/fortran/intrinsic.cc     |  6 ++---
 gcc/fortran/io.cc            | 13 ++-------
 gcc/fortran/misc.cc          |  2 +-
 gcc/fortran/parse.cc         |  2 +-
 gcc/fortran/parse.h          |  2 +-
 gcc/fortran/primary.cc       |  4 +--
 gcc/fortran/resolve.cc       | 22 ++++++++--------
 gcc/fortran/scanner.cc       | 20 +++++++-------
 gcc/fortran/symbol.cc        |  2 +-
 gcc/fortran/target-memory.cc |  6 ++---
 gcc/fortran/trans-array.cc   |  2 +-
 gcc/fortran/trans-decl.cc    |  2 +-
 gcc/fortran/trans-types.cc   |  6 ++---
 gcc/fortran/trans-types.h    |  6 ++---
 gcc/fortran/trans.h          |  2 +-
 25 files changed, 90 insertions(+), 101 deletions(-)

diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc
index fc9224ebc5c..55f35ea66be 100644
--- a/gcc/fortran/arith.cc
+++ b/gcc/fortran/arith.cc
@@ -1135,7 +1135,7 @@ compare_complex (gfc_expr *op1, gfc_expr *op2)
    strings.  We return -1 for a < b, 0 for a == b and 1 for a > b.
    We use the processor's default collating sequence.  */
 
-int
+signed char
 gfc_compare_string (gfc_expr *a, gfc_expr *b)
 {
   size_t len, alen, blen, i;
@@ -1162,7 +1162,7 @@ gfc_compare_string (gfc_expr *a, gfc_expr *b)
 }
 
 
-int
+signed char
 gfc_compare_with_Cstring (gfc_expr *a, const char *b, bool case_sensitive)
 {
   size_t len, alen, blen, i;
diff --git a/gcc/fortran/arith.h b/gcc/fortran/arith.h
index 4a79c985231..8aeb7242166 100644
--- a/gcc/fortran/arith.h
+++ b/gcc/fortran/arith.h
@@ -33,8 +33,8 @@ void gfc_set_model (mpfr_t);
 arith gfc_range_check (gfc_expr *);
 
 int gfc_compare_expr (gfc_expr *, gfc_expr *, gfc_intrinsic_op);
-int gfc_compare_string (gfc_expr *, gfc_expr *);
-int gfc_compare_with_Cstring (gfc_expr *, const char *, bool);
+signed char gfc_compare_string (gfc_expr *, gfc_expr *);
+signed char gfc_compare_with_Cstring (gfc_expr *, const char *, bool);
 
 
 /* Constant folding for gfc_expr trees.  */
diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
index bbdb5b392fc..281f95a0a7e 100644
--- a/gcc/fortran/array.cc
+++ b/gcc/fortran/array.cc
@@ -985,7 +985,7 @@ compare_bounds (gfc_expr *bound1, gfc_expr *bound2)
 /* Compares two array specifications.  They must be constant or deferred
    shape.  */
 
-int
+bool
 gfc_compare_array_spec (gfc_array_spec *as1, gfc_array_spec *as2)
 {
   int i;
@@ -1030,7 +1030,7 @@ gfc_compare_array_spec (gfc_array_spec *as1, gfc_array_spec *as2)
    use the symbol as an implied-DO iterator.  Returns nonzero if a
    duplicate was found.  */
 
-static int
+static bool
 check_duplicate_iterator (gfc_constructor_base base, gfc_symbol *master)
 {
   gfc_constructor *c;
@@ -1973,7 +1973,7 @@ is_constant_element (gfc_expr *e)
    i=1,100000000) /) will take a while as* opposed to a more clever
    function that traverses the expression tree. FIXME.  */
 
-int
+bool
 gfc_constant_ac (gfc_expr *e)
 {
   expand_info expand_save;
@@ -1996,7 +1996,7 @@ gfc_constant_ac (gfc_expr *e)
 /* Returns nonzero if an array constructor has been completely
    expanded (no iterators) and zero if iterators are present.  */
 
-int
+bool
 gfc_expanded_ac (gfc_expr *e)
 {
   gfc_constructor *c;
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 91d87a1b2c1..e0ca1e8d7ca 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -1156,7 +1156,7 @@ dim_rank_check (gfc_expr *dim, gfc_expr *array, int allow_assumed)
    dimension bi, returning 0 if they are known not to be identical,
    and 1 if they are identical, or if this cannot be determined.  */
 
-static int
+static bool
 identical_dimen_shape (gfc_expr *a, int ai, gfc_expr *b, int bi)
 {
   mpz_t a_size, b_size;
diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc
index 364bd0d2a85..9ae8046c4bc 100644
--- a/gcc/fortran/cpp.cc
+++ b/gcc/fortran/cpp.cc
@@ -297,7 +297,7 @@ gfc_cpp_init_options (unsigned int decoded_options_count,
   gfc_cpp_option.deferred_opt_count = 0;
 }
 
-int
+bool
 gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED)
 {
   int result = 1;
@@ -749,7 +749,6 @@ gfc_cpp_add_include_path_after (char *path, bool user_supplied)
 
 static void scan_translation_unit_trad (cpp_reader *);
 static void account_for_newlines (const unsigned char *, size_t);
-static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
 
 static void print_line (location_t, const char *);
 static void maybe_print_line (location_t);
diff --git a/gcc/fortran/cpp.h b/gcc/fortran/cpp.h
index 28673e32aa2..a003d5922d6 100644
--- a/gcc/fortran/cpp.h
+++ b/gcc/fortran/cpp.h
@@ -39,7 +39,7 @@ void gfc_cpp_init (void);
 void gfc_cpp_init_options (unsigned int decoded_options_count,
 			   struct cl_decoded_option *decoded_options);
 
-int gfc_cpp_handle_option(size_t scode, const char *arg, int value);
+bool gfc_cpp_handle_option(size_t scode, const char *arg, int value);
 
 void gfc_cpp_post_options (bool);
 
diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
index ab3bd36f74e..dee50cc8926 100644
--- a/gcc/fortran/dependency.cc
+++ b/gcc/fortran/dependency.cc
@@ -921,7 +921,7 @@ gfc_ref_needs_temporary_p (gfc_ref *ref)
 }
 
 
-static int
+static bool
 gfc_is_data_pointer (gfc_expr *e)
 {
   gfc_ref *ref;
@@ -1091,7 +1091,7 @@ gfc_check_argument_dependency (gfc_expr *other, sym_intent intent,
 /* Like gfc_check_argument_dependency, but check all the arguments in ACTUAL.
    FNSYM is the function being called, or NULL if not known.  */
 
-int
+bool
 gfc_check_fncall_dependency (gfc_expr *other, sym_intent intent,
 			     gfc_symbol *fnsym, gfc_actual_arglist *actual,
 			     gfc_dep_check elemental)
@@ -1137,7 +1137,7 @@ gfc_check_fncall_dependency (gfc_expr *other, sym_intent intent,
    e1->ref and e2->ref to determine whether the actually accessed
    portions of these variables/arrays potentially overlap.  */
 
-int
+bool
 gfc_are_equivalenced_arrays (gfc_expr *e1, gfc_expr *e2)
 {
   gfc_equiv_list *l;
@@ -2093,7 +2093,7 @@ ref_same_as_full_array (gfc_ref *full_ref, gfc_ref *ref)
 	    there is some kind of overlap.
 	0 : array references are identical or not overlapping.  */
 
-int
+bool
 gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
 		  bool identical)
 {
diff --git a/gcc/fortran/dependency.h b/gcc/fortran/dependency.h
index 339be76a8d0..81114054eb8 100644
--- a/gcc/fortran/dependency.h
+++ b/gcc/fortran/dependency.h
@@ -32,13 +32,13 @@ enum gfc_dep_check
 bool gfc_ref_needs_temporary_p (gfc_ref *);
 bool gfc_full_array_ref_p (gfc_ref *, bool *);
 gfc_expr *gfc_get_noncopying_intrinsic_argument (gfc_expr *);
-int gfc_check_fncall_dependency (gfc_expr *, sym_intent, gfc_symbol *,
+bool gfc_check_fncall_dependency (gfc_expr *, sym_intent, gfc_symbol *,
 				 gfc_actual_arglist *, gfc_dep_check);
 int gfc_check_dependency (gfc_expr *, gfc_expr *, bool);
 int gfc_expr_is_one (gfc_expr *, int);
 
-int gfc_dep_resolver (gfc_ref *, gfc_ref *, gfc_reverse *,
+bool gfc_dep_resolver (gfc_ref *, gfc_ref *, gfc_reverse *,
 		      bool identical = false);
-int gfc_are_equivalenced_arrays (gfc_expr *, gfc_expr *);
+bool gfc_are_equivalenced_arrays (gfc_expr *, gfc_expr *);
 
 gfc_expr * gfc_discard_nops (gfc_expr *);
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index 69d0b57c688..e095e74d290 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -787,7 +787,7 @@ gfc_copy_ref (gfc_ref *src)
 
 /* Detect whether an expression has any vector index array references.  */
 
-int
+bool
 gfc_has_vector_index (gfc_expr *e)
 {
   gfc_ref *ref;
@@ -877,7 +877,7 @@ gfc_kind_max (gfc_expr *e1, gfc_expr *e2)
 
 /* Returns nonzero if the type is numeric, zero otherwise.  */
 
-static int
+static bool
 numeric_type (bt type)
 {
   return type == BT_COMPLEX || type == BT_REAL || type == BT_INTEGER;
@@ -886,7 +886,7 @@ numeric_type (bt type)
 
 /* Returns nonzero if the typespec is a numeric type, zero otherwise.  */
 
-int
+bool
 gfc_numeric_ts (gfc_typespec *ts)
 {
   return numeric_type (ts->type);
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 6bd8800ecf8..4cc969d7dc8 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3202,17 +3202,16 @@ void gfc_release_include_path (void);
 void gfc_check_include_dirs (bool);
 FILE *gfc_open_included_file (const char *, bool, bool);
 
-int gfc_at_end (void);
-int gfc_at_eof (void);
-int gfc_at_bol (void);
-int gfc_at_eol (void);
+bool gfc_at_end (void);
+bool gfc_at_eof (void);
+bool gfc_at_bol (void);
+bool gfc_at_eol (void);
 void gfc_advance_line (void);
-int gfc_check_include (void);
-int gfc_define_undef_line (void);
+bool gfc_define_undef_line (void);
 
-int gfc_wide_is_printable (gfc_char_t);
-int gfc_wide_is_digit (gfc_char_t);
-int gfc_wide_fits_in_byte (gfc_char_t);
+bool gfc_wide_is_printable (gfc_char_t);
+bool gfc_wide_is_digit (gfc_char_t);
+bool gfc_wide_fits_in_byte (gfc_char_t);
 gfc_char_t gfc_wide_tolower (gfc_char_t);
 gfc_char_t gfc_wide_toupper (gfc_char_t);
 size_t gfc_wide_strlen (const gfc_char_t *);
@@ -3258,7 +3257,7 @@ void gfc_init_2 (void);
 void gfc_done_1 (void);
 void gfc_done_2 (void);
 
-int get_c_kind (const char *, CInteropKind_t *);
+signed char get_c_kind (const char *, CInteropKind_t *);
 
 const char *gfc_closest_fuzzy_match (const char *, char **);
 static inline void
@@ -3469,7 +3468,7 @@ void gfc_release_symbol (gfc_symbol *&);
 gfc_symbol *gfc_new_symbol (const char *, gfc_namespace *);
 gfc_symtree* gfc_find_symtree_in_proc (const char *, gfc_namespace *);
 int gfc_find_symbol (const char *, gfc_namespace *, int, gfc_symbol **);
-int gfc_find_sym_tree (const char *, gfc_namespace *, int, gfc_symtree **);
+bool gfc_find_sym_tree (const char *, gfc_namespace *, int, gfc_symtree **);
 int gfc_get_symbol (const char *, gfc_namespace *, gfc_symbol **);
 bool gfc_verify_c_interop (gfc_typespec *);
 bool gfc_verify_c_interop_param (gfc_symbol *);
@@ -3549,10 +3548,10 @@ bool gfc_convert_type (gfc_expr *, gfc_typespec *, int);
 bool gfc_convert_type_warn (gfc_expr *, gfc_typespec *, int, int,
 			    bool array = false);
 bool gfc_convert_chartype (gfc_expr *, gfc_typespec *);
-int gfc_generic_intrinsic (const char *);
-int gfc_specific_intrinsic (const char *);
+bool gfc_generic_intrinsic (const char *);
+bool gfc_specific_intrinsic (const char *);
 bool gfc_is_intrinsic (gfc_symbol*, int, locus);
-int gfc_intrinsic_actual_ok (const char *, const bool);
+bool gfc_intrinsic_actual_ok (const char *, const bool);
 gfc_intrinsic_sym *gfc_find_function (const char *);
 gfc_intrinsic_sym *gfc_find_subroutine (const char *);
 gfc_intrinsic_sym *gfc_intrinsic_function_by_id (gfc_isym_id);
@@ -3630,7 +3629,7 @@ void gfc_type_convert_binary (gfc_expr *, int);
 bool gfc_is_constant_expr (gfc_expr *);
 bool gfc_simplify_expr (gfc_expr *, int);
 bool gfc_try_simplify_expr (gfc_expr *, int);
-int gfc_has_vector_index (gfc_expr *);
+bool gfc_has_vector_index (gfc_expr *);
 
 gfc_expr *gfc_get_expr (void);
 gfc_expr *gfc_get_array_expr (bt type, int kind, locus *);
@@ -3654,7 +3653,7 @@ gfc_ref* gfc_copy_ref (gfc_ref*);
 
 bool gfc_specification_expr (gfc_expr *);
 
-int gfc_numeric_ts (gfc_typespec *);
+bool gfc_numeric_ts (gfc_typespec *);
 int gfc_kind_max (gfc_expr *, gfc_expr *);
 
 bool gfc_check_conformance (gfc_expr *, gfc_expr *, const char *, ...) ATTRIBUTE_PRINTF_3;
@@ -3718,11 +3717,11 @@ void gfc_resolve (gfc_namespace *);
 void gfc_resolve_code (gfc_code *, gfc_namespace *);
 void gfc_resolve_blocks (gfc_code *, gfc_namespace *);
 void gfc_resolve_formal_arglist (gfc_symbol *);
-int gfc_impure_variable (gfc_symbol *);
-int gfc_pure (gfc_symbol *);
-int gfc_implicit_pure (gfc_symbol *);
+bool gfc_impure_variable (gfc_symbol *);
+bool gfc_pure (gfc_symbol *);
+bool gfc_implicit_pure (gfc_symbol *);
 void gfc_unset_implicit_pure (gfc_symbol *);
-int gfc_elemental (gfc_symbol *);
+bool gfc_elemental (gfc_symbol *);
 bool gfc_resolve_iterator (gfc_iterator *, bool, bool);
 bool find_forall_index (gfc_expr *, gfc_symbol *, int);
 bool gfc_resolve_index (gfc_expr *, int);
@@ -3736,8 +3735,8 @@ bool gfc_resolve_intrinsic (gfc_symbol *, locus *);
 bool gfc_explicit_interface_required (gfc_symbol *, char *, int);
 extern int gfc_do_concurrent_flag;
 const char* gfc_lookup_function_fuzzy (const char *, gfc_symtree *);
-int gfc_pure_function (gfc_expr *e, const char **name);
-int gfc_implicit_pure_function (gfc_expr *e);
+bool gfc_pure_function (gfc_expr *e, const char **name);
+bool gfc_implicit_pure_function (gfc_expr *e);
 
 
 /* array.cc */
@@ -3750,12 +3749,12 @@ bool gfc_set_array_spec (gfc_symbol *, gfc_array_spec *, locus *);
 gfc_array_spec *gfc_copy_array_spec (gfc_array_spec *);
 bool gfc_resolve_array_spec (gfc_array_spec *, int);
 
-int gfc_compare_array_spec (gfc_array_spec *, gfc_array_spec *);
+bool gfc_compare_array_spec (gfc_array_spec *, gfc_array_spec *);
 
 void gfc_simplify_iterator_var (gfc_expr *);
 bool gfc_expand_constructor (gfc_expr *, bool);
-int gfc_constant_ac (gfc_expr *);
-int gfc_expanded_ac (gfc_expr *);
+bool gfc_constant_ac (gfc_expr *);
+bool gfc_expanded_ac (gfc_expr *);
 bool gfc_resolve_character_array_constructor (gfc_expr *);
 bool gfc_resolve_array_constructor (gfc_expr *);
 bool gfc_check_constructor_type (gfc_expr *);
@@ -3840,7 +3839,7 @@ symbol_attribute gfc_expr_attr (gfc_expr *);
 symbol_attribute gfc_caf_attr (gfc_expr *, bool i = false, bool *r = NULL);
 match gfc_match_rvalue (gfc_expr **);
 match gfc_match_varspec (gfc_expr*, int, bool, bool);
-int gfc_check_digit (char, int);
+bool gfc_check_digit (char, int);
 bool gfc_is_function_return_value (gfc_symbol *, gfc_namespace *);
 bool gfc_convert_to_structure_constructor (gfc_expr *, gfc_symbol *,
 					      gfc_expr **,
diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc
index e89131f5a71..1d3702ff313 100644
--- a/gcc/fortran/intrinsic.cc
+++ b/gcc/fortran/intrinsic.cc
@@ -1106,7 +1106,7 @@ gfc_find_subroutine (const char *name)
 /* Given a string, figure out if it is the name of a generic intrinsic
    function or not.  */
 
-int
+bool
 gfc_generic_intrinsic (const char *name)
 {
   gfc_intrinsic_sym *sym;
@@ -1119,7 +1119,7 @@ gfc_generic_intrinsic (const char *name)
 /* Given a string, figure out if it is the name of a specific
    intrinsic function or not.  */
 
-int
+bool
 gfc_specific_intrinsic (const char *name)
 {
   gfc_intrinsic_sym *sym;
@@ -1131,7 +1131,7 @@ gfc_specific_intrinsic (const char *name)
 
 /* Given a string, figure out if it is the name of an intrinsic function
    or subroutine allowed as an actual argument or not.  */
-int
+bool
 gfc_intrinsic_actual_ok (const char *name, const bool subroutine_flag)
 {
   gfc_intrinsic_sym *sym;
diff --git a/gcc/fortran/io.cc b/gcc/fortran/io.cc
index 902aa19f55a..488264de4b4 100644
--- a/gcc/fortran/io.cc
+++ b/gcc/fortran/io.cc
@@ -2010,15 +2010,6 @@ gfc_free_open (gfc_open *open)
   free (open);
 }
 
-
-static int
-compare_to_allowed_values (const char *specifier, const char *allowed[],
-			   const char *allowed_f2003[],
-			   const char *allowed_gnu[], gfc_char_t *value,
-			   const char *statement, bool warn, locus *where,
-			   int *num = NULL);
-
-
 static bool
 check_open_constraints (gfc_open *open, locus *where);
 
@@ -2062,12 +2053,12 @@ gfc_resolve_open (gfc_open *open, locus *where)
    value if it is not allowed.  */
 
 
-static int
+static bool
 compare_to_allowed_values (const char *specifier, const char *allowed[],
 			   const char *allowed_f2003[],
 			   const char *allowed_gnu[], gfc_char_t *value,
 			   const char *statement, bool warn, locus *where,
-			   int *num)
+			   int *num = NULL)
 {
   int i;
   unsigned int len;
diff --git a/gcc/fortran/misc.cc b/gcc/fortran/misc.cc
index af363472641..270ea817f61 100644
--- a/gcc/fortran/misc.cc
+++ b/gcc/fortran/misc.cc
@@ -387,7 +387,7 @@ gfc_done_2 (void)
 /* Returns the index into the table of C interoperable kinds where the
    kind with the given name (c_kind_name) was found.  */
 
-int
+signed char
 get_c_kind(const char *c_kind_name, CInteropKind_t kinds_table[])
 {
   int index = 0;
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index f04fd13cc69..352191e650e 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -4703,7 +4703,7 @@ done:
    context that causes it to become redefined.  If the symbol is an
    iterator, we generate an error message and return nonzero.  */
 
-int
+bool
 gfc_check_do_variable (gfc_symtree *st)
 {
   gfc_state_data *s;
diff --git a/gcc/fortran/parse.h b/gcc/fortran/parse.h
index 013aeaedc03..44b3a5079c0 100644
--- a/gcc/fortran/parse.h
+++ b/gcc/fortran/parse.h
@@ -63,7 +63,7 @@ extern gfc_state_data *gfc_state_stack;
 #define gfc_comp_struct(s) \
   ((s) == COMP_DERIVED || (s) == COMP_STRUCTURE || (s) == COMP_MAP)
 
-int gfc_check_do_variable (gfc_symtree *);
+bool gfc_check_do_variable (gfc_symtree *);
 bool gfc_find_state (gfc_compile_state);
 gfc_state_data *gfc_enclosing_unit (gfc_compile_state *);
 const char *gfc_ascii_statement (gfc_statement, bool strip_sentinel = false) ;
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 19f2e78c8ff..52457cc8277 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -109,10 +109,10 @@ get_kind (int *is_iso_c)
 /* Given a character and a radix, see if the character is a valid
    digit in that radix.  */
 
-int
+bool
 gfc_check_digit (char c, int radix)
 {
-  int r;
+  bool r;
 
   switch (radix)
     {
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 9202e2f10ad..39074273e95 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -1562,7 +1562,7 @@ resolve_structure_cons (gfc_expr *expr, int init)
 /* Returns 0 if a symbol was not declared with a type or
    attribute declaration statement, nonzero otherwise.  */
 
-static int
+static bool
 was_declared (gfc_symbol *sym)
 {
   symbol_attribute a;
@@ -3066,13 +3066,13 @@ is_external_proc (gfc_symbol *sym)
 /* Figure out if a function reference is pure or not.  Also set the name
    of the function for a potential error message.  Return nonzero if the
    function is PURE, zero if not.  */
-static int
+static bool
 pure_stmt_function (gfc_expr *, gfc_symbol *);
 
-int
+bool
 gfc_pure_function (gfc_expr *e, const char **name)
 {
-  int pure;
+  bool pure;
   gfc_component *comp;
 
   *name = NULL;
@@ -3112,7 +3112,7 @@ gfc_pure_function (gfc_expr *e, const char **name)
 
 /* Check if the expression is a reference to an implicitly pure function.  */
 
-int
+bool
 gfc_implicit_pure_function (gfc_expr *e)
 {
   gfc_component *comp = gfc_get_proc_ptr_comp (e);
@@ -3143,7 +3143,7 @@ impure_stmt_fcn (gfc_expr *e, gfc_symbol *sym,
 }
 
 
-static int
+static bool
 pure_stmt_function (gfc_expr *e, gfc_symbol *sym)
 {
   return gfc_traverse_expr (e, sym, impure_stmt_fcn, 0) ? 0 : 1;
@@ -7524,7 +7524,7 @@ resolve_forall_iterators (gfc_forall_iterator *it)
    PRIVATE.  The search is recursive if necessary.  Returns zero if no
    inaccessible components are found, nonzero otherwise.  */
 
-static int
+static bool
 derived_inaccessible (gfc_symbol *sym)
 {
   gfc_component *c;
@@ -16757,7 +16757,7 @@ resolve_data (gfc_data *d)
 /* Determines if a variable is not 'pure', i.e., not assignable within a pure
    procedure.  Returns zero if assignment is OK, nonzero if there is a
    problem.  */
-int
+bool
 gfc_impure_variable (gfc_symbol *sym)
 {
   gfc_symbol *proc;
@@ -16792,7 +16792,7 @@ gfc_impure_variable (gfc_symbol *sym)
 /* Test whether a symbol is pure or not.  For a NULL pointer, checks if the
    current namespace is inside a pure procedure.  */
 
-int
+bool
 gfc_pure (gfc_symbol *sym)
 {
   symbol_attribute attr;
@@ -16824,7 +16824,7 @@ gfc_pure (gfc_symbol *sym)
    checks if the current namespace is implicitly pure.  Note that this
    function returns false for a PURE procedure.  */
 
-int
+bool
 gfc_implicit_pure (gfc_symbol *sym)
 {
   gfc_namespace *ns;
@@ -16878,7 +16878,7 @@ gfc_unset_implicit_pure (gfc_symbol *sym)
 
 /* Test whether the current procedure is elemental or not.  */
 
-int
+bool
 gfc_elemental (gfc_symbol *sym)
 {
   symbol_attribute attr;
diff --git a/gcc/fortran/scanner.cc b/gcc/fortran/scanner.cc
index fa1d9cba394..cae26a9f2bc 100644
--- a/gcc/fortran/scanner.cc
+++ b/gcc/fortran/scanner.cc
@@ -56,7 +56,7 @@ gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
 
 static gfc_file *file_head, *current_file;
 
-static int continue_flag, end_flag, gcc_attribute_flag;
+static bool continue_flag, end_flag, gcc_attribute_flag;
 /* If !$omp/!$acc occurred in current comment line.  */
 static int openmp_flag, openacc_flag;
 static int continue_count, continue_line;
@@ -86,7 +86,7 @@ static gfc_char_t *last_error_char;
 /* Functions dealing with our wide characters (gfc_char_t) and
    sequences of such characters.  */
 
-int
+bool
 gfc_wide_fits_in_byte (gfc_char_t c)
 {
   return (c <= UCHAR_MAX);
@@ -98,7 +98,7 @@ wide_is_ascii (gfc_char_t c)
   return (gfc_wide_fits_in_byte (c) && ((unsigned char) c & ~0x7f) == 0);
 }
 
-int
+bool
 gfc_wide_is_printable (gfc_char_t c)
 {
   return (gfc_wide_fits_in_byte (c) && ISPRINT ((unsigned char) c));
@@ -116,7 +116,7 @@ gfc_wide_toupper (gfc_char_t c)
   return (wide_is_ascii (c) ? (gfc_char_t) TOUPPER((unsigned char) c) : c);
 }
 
-int
+bool
 gfc_wide_is_digit (gfc_char_t c)
 {
   return (c >= '0' && c <= '9');
@@ -518,7 +518,7 @@ gfc_open_included_file (const char *name, bool include_cwd, bool module)
 
 /* Test to see if we're at the end of the main source file.  */
 
-int
+bool
 gfc_at_end (void)
 {
   return end_flag;
@@ -527,7 +527,7 @@ gfc_at_end (void)
 
 /* Test to see if we're at the end of the current file.  */
 
-int
+bool
 gfc_at_eof (void)
 {
   if (gfc_at_end ())
@@ -545,7 +545,7 @@ gfc_at_eof (void)
 
 /* Test to see if we're at the beginning of a new line.  */
 
-int
+bool
 gfc_at_bol (void)
 {
   if (gfc_at_eof ())
@@ -557,7 +557,7 @@ gfc_at_bol (void)
 
 /* Test to see if we're at the end of a line.  */
 
-int
+bool
 gfc_at_eol (void)
 {
   if (gfc_at_eof ())
@@ -702,7 +702,7 @@ skip_comment_line (void)
 }
 
 
-int
+bool
 gfc_define_undef_line (void)
 {
   char *tmp;
@@ -1803,7 +1803,7 @@ gfc_gobble_whitespace (void)
 	 easily report line and column numbers consistent with other 
 	 parts of gfortran.  */
 
-static int
+static bool
 load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
 {
   int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index 49fb37864bd..65860938681 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
@@ -3210,7 +3210,7 @@ gfc_find_symtree_in_proc (const char* name, gfc_namespace* ns)
    any parent namespaces if requested by a nonzero parent_flag.
    Returns nonzero if the name is ambiguous.  */
 
-int
+bool
 gfc_find_sym_tree (const char *name, gfc_namespace *ns, int parent_flag,
 		   gfc_symtree **result)
 {
diff --git a/gcc/fortran/target-memory.cc b/gcc/fortran/target-memory.cc
index 7ce7d736629..8e32c56f479 100644
--- a/gcc/fortran/target-memory.cc
+++ b/gcc/fortran/target-memory.cc
@@ -36,14 +36,14 @@ along with GCC; see the file COPYING3.  If not see
 /* Calculate the size of an expression.  */
 
 
-static size_t
+static short unsigned int
 size_integer (int kind)
 {
   return GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (gfc_get_int_type (kind)));
 }
 
 
-static size_t
+static short unsigned int
 size_float (int kind)
 {
   return GET_MODE_SIZE (SCALAR_FLOAT_TYPE_MODE (gfc_get_real_type (kind)));
@@ -57,7 +57,7 @@ size_complex (int kind)
 }
 
 
-static size_t
+static short unsigned int
 size_logical (int kind)
 {
   return GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (gfc_get_logical_type (kind)));
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 514cb057afb..dc84fbaeb20 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -4931,7 +4931,7 @@ done:
 /* Return true if both symbols could refer to the same data object.  Does
    not take account of aliasing due to equivalence statements.  */
 
-static int
+static bool
 symbols_could_alias (gfc_symbol *lsym, gfc_symbol *rsym, bool lsym_pointer,
 		     bool lsym_target, bool rsym_pointer, bool rsym_target)
 {
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 63515b9072a..ba855c4569e 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -483,7 +483,7 @@ gfc_set_decl_assembler_name (tree decl, tree name)
 
 /* Returns true if a variable of specified size should go on the stack.  */
 
-int
+bool
 gfc_can_put_var_on_stack (tree size)
 {
   unsigned HOST_WIDE_INT low;
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index def7552ac67..99a28415cb3 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -1374,7 +1374,7 @@ gfc_get_element_type (tree type)
 
 /* Returns true if the array sym does not require a descriptor.  */
 
-int
+bool
 gfc_is_nodesc_array (gfc_symbol * sym)
 {
   symbol_attribute *array_attr;
@@ -2451,7 +2451,7 @@ gfc_add_field_to_struct (tree context, tree name, tree type, tree **chain)
    the two derived type symbols are "equal", as described
    in 4.4.2 and resolved by gfc_compare_derived_types.  */
 
-int
+bool
 gfc_copy_dt_decls_ifequal (gfc_symbol *from, gfc_symbol *to,
 			   bool from_gsym)
 {
@@ -2940,7 +2940,7 @@ copy_derived_types:
 }
 
 
-int
+bool
 gfc_return_by_reference (gfc_symbol * sym)
 {
   if (!sym->attr.function)
diff --git a/gcc/fortran/trans-types.h b/gcc/fortran/trans-types.h
index 6a360de69f6..297b93702d8 100644
--- a/gcc/fortran/trans-types.h
+++ b/gcc/fortran/trans-types.h
@@ -88,7 +88,7 @@ tree gfc_get_character_type_len_for_eltype (tree, tree);
 tree gfc_sym_type (gfc_symbol *, bool is_bind_c_arg = false);
 tree gfc_get_cfi_type (int dimen, bool restricted);
 tree gfc_typenode_for_spec (gfc_typespec *, int c = 0);
-int gfc_copy_dt_decls_ifequal (gfc_symbol *, gfc_symbol *, bool);
+bool gfc_copy_dt_decls_ifequal (gfc_symbol *, gfc_symbol *, bool);
 
 tree gfc_get_function_type (gfc_symbol *, gfc_actual_arglist *args = NULL,
 			    const char *fnspec = NULL);
@@ -109,10 +109,10 @@ tree gfc_add_field_to_struct (tree, tree, tree, tree **);
 void gfc_finish_type (tree);
 
 /* Some functions have an extra parameter for the return value.  */
-int gfc_return_by_reference (gfc_symbol *);
+bool gfc_return_by_reference (gfc_symbol *);
 
 /* Returns true if the array sym does not require a descriptor.  */
-int gfc_is_nodesc_array (gfc_symbol *);
+bool gfc_is_nodesc_array (gfc_symbol *);
 
 /* Return the DTYPE for an array.  */
 tree gfc_get_dtype_rank_type (int, tree);
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index bc9035c1717..1ea30156675 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -664,7 +664,7 @@ void gfc_restore_sym (gfc_symbol *, gfc_saved_var *);
 void gfc_set_decl_assembler_name (tree, tree);
 
 /* Returns true if a variable of specified size should go on the stack.  */
-int gfc_can_put_var_on_stack (tree);
+bool gfc_can_put_var_on_stack (tree);
 
 /* Set GFC_DECL_SCALAR_* on decl from sym if needed.  */
 void gfc_finish_decl_attrs (tree, symbol_attribute *);
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 4/5] value-range: Add as_string diagnostics helper
  2022-11-12 23:45 [PATCH 0/5] function result decl location; type demotion Bernhard Reutner-Fischer
                   ` (2 preceding siblings ...)
  2022-11-12 23:45 ` [PATCH 3/5] Fortran: Narrow return types [PR78798] Bernhard Reutner-Fischer
@ 2022-11-12 23:45 ` Bernhard Reutner-Fischer
  2022-11-12 23:55   ` Andrew Pinski
  2022-11-12 23:45 ` [PATCH 5/5] gimple: Add pass to note possible type demotions; IPA pro/demotion; DO NOT MERGE Bernhard Reutner-Fischer
  4 siblings, 1 reply; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2022-11-12 23:45 UTC (permalink / raw)
  To: gcc-patches
  Cc: Bernhard Reutner-Fischer, Bernhard Reutner-Fischer, fortran,
	Andrew MacLeod, Aldy Hernandez

gcc/ChangeLog:

	* value-range.cc (get_bound_with_infinite_markers): New static helper.
	(irange::as_string): New definition.
	* value-range.h: New declaration.

---
Provide means to print a value range to a newly allocated buffer.
The caller is responsible to free() the allocated memory.

Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
Ok for trunk?

Cc: Andrew MacLeod <amacleod@redhat.com>
Cc: Aldy Hernandez <aldyh@redhat.com>
---
 gcc/value-range.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++
 gcc/value-range.h  |  3 +++
 2 files changed, 59 insertions(+)

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index a855aaf626c..51cd9a38d90 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -3099,6 +3099,62 @@ debug (const value_range &vr)
   fprintf (stderr, "\n");
 }
 
+/* Helper for irange::as_string().  Print a bound to an allocated buffer.  */
+static char *
+get_bound_with_infinite_markers (tree bound)
+{
+  tree type = TREE_TYPE (bound);
+  wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
+  wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
+
+  if (INTEGRAL_TYPE_P (type)
+      && !TYPE_UNSIGNED (type)
+      && TREE_CODE (bound) == INTEGER_CST
+      && wi::to_wide (bound) == type_min
+      && TYPE_PRECISION (type) != 1)
+    return xstrdup ("-INF");
+  else if (TREE_CODE (bound) == INTEGER_CST
+	   && wi::to_wide (bound) == type_max
+	   && TYPE_PRECISION (type) != 1)
+    return xstrdup ("+INF");
+  else
+    return print_generic_expr_to_str (bound);
+}
+
+
+/* Return an irange as string. Return NULL on failure, an allocated
+   string on success.  */
+char *
+irange::as_string ()
+{
+  char *ret = NULL;
+  if (undefined_p() || varying_p () || m_num_ranges == 0)
+    return ret;
+
+  for (unsigned i = 0; i < m_num_ranges; ++i)
+    {
+      tree lb = m_base[i * 2];
+      tree ub = m_base[i * 2 + 1];
+      /* Construct [lower_bound,upper_bound].  */
+      char *lbs = get_bound_with_infinite_markers (lb);
+      char *ubs = get_bound_with_infinite_markers (ub);
+      /* Paranoia mode */
+      if (!lbs)
+	lbs = xstrdup ("");
+      if (!ubs)
+	ubs = xstrdup ("");
+
+      if (ret)
+	ret = reconcat (ret, ret, "[", lbs, ",", ubs, "]", NULL);
+      else
+	ret = concat ("[", lbs, ",", ubs, "]", NULL);
+
+      free (lbs);
+      free (ubs);
+    }
+  return ret;
+}
+
 /* Create two value-ranges in *VR0 and *VR1 from the anti-range *AR
    so that *VR0 U *VR1 == *AR.  Returns true if that is possible,
    false otherwise.  If *AR can be represented with a single range
diff --git a/gcc/value-range.h b/gcc/value-range.h
index c87734dd8cd..76242e4bf45 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -160,6 +160,9 @@ public:
   wide_int get_nonzero_bits () const;
   void set_nonzero_bits (const wide_int_ref &bits);
 
+  // For diagnostics.
+  char *as_string ();
+
   // Deprecated legacy public methods.
   tree min () const;				// DEPRECATED
   tree max () const;				// DEPRECATED
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 5/5] gimple: Add pass to note possible type demotions; IPA pro/demotion; DO NOT MERGE
  2022-11-12 23:45 [PATCH 0/5] function result decl location; type demotion Bernhard Reutner-Fischer
                   ` (3 preceding siblings ...)
  2022-11-12 23:45 ` [PATCH 4/5] value-range: Add as_string diagnostics helper Bernhard Reutner-Fischer
@ 2022-11-12 23:45 ` Bernhard Reutner-Fischer
  4 siblings, 0 replies; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2022-11-12 23:45 UTC (permalink / raw)
  To: gcc-patches; +Cc: Bernhard Reutner-Fischer, Bernhard Reutner-Fischer, fortran

gcc/ChangeLog:

	* Makefile.in (OBJS): Add gimple-warn-types.o.
	* passes.def: Add pass_warn_type_demotion.
	* tree-pass.h (make_pass_warn_type_demotion): New declaration.
	* gimple-warn-types.cc: New file.

gcc/c-family/ChangeLog:

	* c.opt (Wtype-demotion): New.

---
DO NOT MERGE.
This is the script^Wpass to emit a warning if a function's return type
could potentially be narrowed.
What would probably be useful is to equip an IPA pass with that
knowledge and demote return types of functions that do not contribute to
an external interface to the smallest possible type. The idea is that if
a target determines late via targetm.calls.promote_prototypes to promote
return values, the target will ultimately have the final say about
return types while for non-exported functions we can narrow types for
size- or speed reasons as we see fit.

This hunk does not implement an IPA pass that would do anything really
useful but merely queries the ranger to see if there are possibilities
to demote a return type, any (!) return type.
For the IPA real thing, we'd want to notice that if a function returns a
singleton, the caller would just use that singleton and demote the
callee to void. And in the caller, we'd appropriately shift the callee's
return value to the required range/value.
The usual trouble makers come to mind: qsort helpers that insist on int
return codes (that we could extend to int).

As said, that's just for your amusement and is not meant to be merged.
---
 gcc/Makefile.in          |   1 +
 gcc/c-family/c.opt       |   6 +
 gcc/gimple-warn-types.cc | 441 +++++++++++++++++++++++++++++++++++++++
 gcc/passes.def           |   1 +
 gcc/tree-pass.h          |   1 +
 5 files changed, 450 insertions(+)
 create mode 100644 gcc/gimple-warn-types.cc

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f672e6ea549..c6901ececd4 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1433,6 +1433,7 @@ OBJS = \
 	gimple-streamer-out.o \
 	gimple-walk.o \
 	gimple-warn-recursion.o \
+	gimple-warn-types.o \
 	gimplify.o \
 	gimplify-me.o \
 	godump.o \
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 63a300ecd7c..0b46669e2b7 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1005,6 +1005,12 @@ Wtemplates
 C++ ObjC++ Var(warn_templates) Warning
 Warn on primary template declaration.
 
+Wtype-demotion
+C ObjC C++ ObjC++ Var(warn_type_demotion) Warning LangEnabledBy(C ObjC C++ ObjC++, Wall)
+Warn if function return type could be narrowed or demoted.
+; function return type, parameter type, variable type.
+; if values used for a type indicate that the type could use a narrower mode.
+
 Wmissing-attributes
 C ObjC C++ ObjC++ Var(warn_missing_attributes) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
 Warn about declarations of entities that may be missing attributes
diff --git a/gcc/gimple-warn-types.cc b/gcc/gimple-warn-types.cc
new file mode 100644
index 00000000000..e0b7212a1bb
--- /dev/null
+++ b/gcc/gimple-warn-types.cc
@@ -0,0 +1,441 @@
+/* Pass to detect and issue warnings about possibly using narrower types.
+
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+   Contributed by Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "pointer-query.h"
+#include "ssa.h"
+#include "gimple-pretty-print.h"
+#include "diagnostic-core.h"
+#include "fold-const.h"
+#include "gimple-iterator.h"
+#include "tree-dfa.h" //
+#include "tree-ssa.h"
+#include "tree-cfg.h"
+#include "tree-object-size.h" //
+#include "calls.h" //
+#include "cfgloop.h" //
+#include "intl.h"
+#include "gimple-range.h"
+
+#include "value-range.h"
+#include "gimple-range-path.h"
+#include "gcc-rich-location.h"
+#include "langhooks.h"
+#pragma GCC optimize("O0")
+namespace {
+
+const pass_data pass_data_wtype_demotion = {
+  GIMPLE_PASS,
+  "wtype_demotion",
+  OPTGROUP_NONE,
+  TV_NONE,
+  PROP_cfg, /* properties_required.  */
+  0,	    /* properties_provided.  */
+  0,	    /* properties_destroyed.  */
+  0,	    /* properties_start */
+  0,	    /* properties_finish */
+};
+
+class pass_wtype_demotion : public gimple_opt_pass
+{
+ public:
+  pass_wtype_demotion (gcc::context *ctxt)
+    : gimple_opt_pass (pass_data_wtype_demotion, ctxt)
+    { }
+
+  opt_pass *clone () { return new pass_wtype_demotion (m_ctxt); }
+
+  virtual bool gate (function *);
+  virtual unsigned int execute (function *);
+};
+
+bool
+pass_wtype_demotion::gate (function *)
+{
+  return warn_type_demotion;
+}
+
+} /* anonymous namespace */
+
+gimple_opt_pass *
+make_pass_warn_type_demotion (gcc::context *ctxt)
+{
+  return new pass_wtype_demotion (ctxt);
+}
+
+\f
+
+/* Determine the smallest type capable of representing values between TMIN
+   and TMAX with sign TSGN.  Returns a demoted type.  */
+static tree
+narrowest_type (wide_int tmin, wide_int tmax, signop tsgn)
+{
+  tree t;
+  gcc_checking_assert (wi::cmp(tmax, tmin, tsgn) >= 0);
+  const unsigned int tmin_bits = wi::min_precision (tmin, tsgn);
+  const unsigned int tmax_bits = wi::min_precision (tmax, tsgn);
+  const bool equal_sgn = wi::neg_p (tmin, tsgn) == wi::neg_p (tmax, tsgn);
+  const unsigned int bp = wi::get_binary_precision (tmin, tmax);
+  const bool fitsl = wi::fits_uhwi_p (tmin);
+  const bool fitsh = wi::fits_uhwi_p (tmax);
+  int fl = wi::floor_log2 (tmin);
+  int fh = wi::floor_log2 (tmax);
+  signop sgn;
+  unsigned int bits;
+
+  /* ideally equal_sgn [46,122] (i.e. [101110,1111010]) -> [0,76] 6bit, << 1 */
+  if (equal_sgn)
+    bits = tmax_bits - tmin_bits == 1 ? tmin_bits : fh - fl;
+    //bits = fh - fl;
+  else
+    bits = tmin_bits + tmax_bits;
+  bits = MIN (bp, bits);
+
+  if (bits <= 1)
+    t = boolean_type_node; // build_nonstandard_boolean_type (bits);
+  else
+    {
+      if (equal_sgn && fitsl && fitsh && bits < HOST_BITS_PER_WIDE_INT)
+	sgn = UNSIGNED;
+      else
+	sgn = tsgn;
+
+      t = lang_hooks.types.type_for_size (bits, sgn == UNSIGNED);
+#if 0
+      The nonstandard type would not have a typename to suggest, skip it.
+      if (t == NULL_TREE)
+	{
+	  /* Probably a type with > 64 bits. */
+	  /* We currently disregard complex or float types.  */
+	  scalar_int_mode m = smallest_int_mode_for_size (bits);
+	  t = build_nonstandard_integer_type (bits, sgn == UNSIGNED);
+	}
+#endif
+    }
+  return t;
+}
+
+/* A bit like gcc/tree-cfg.cc last_stmt(), but for a whole function.  */
+/* Return the last nondebug statement of function FUN.  */
+
+static gimple *
+fn_last_stmt (function *fun)
+{
+  basic_block bb = EXIT_BLOCK_PTR_FOR_FN (fun);
+  gimple_stmt_iterator gsi;
+  do {
+    bb = bb->prev_bb;
+    gsi = gsi_last_nondebug_bb (bb);
+  } while (gsi_end_p (gsi) && bb != ENTRY_BLOCK_PTR_FOR_FN (fun));
+  if (gsi_end_p (gsi))
+    /* There were no real statements whatsoever.  */
+    return NULL;
+  return gsi_stmt (gsi);
+}
+
+/* Return true if the type of RESULT_TYPE of the functions result_decl is
+   handled, false otherwise.  */
+
+static bool
+handled_result_decl_type_p (tree result_type)
+{
+  switch (TREE_CODE (result_type))
+    {
+    case VOID_TYPE:
+    case ERROR_MARK:
+    case COMPLEX_TYPE: /* Don't care.  */
+    case REAL_TYPE: /* Don't care.  */
+    case ENUMERAL_TYPE: /* Probably does not make sense to mention.  */
+    /* Should maybe look through and suggest to adjust the innards */
+    case RECORD_TYPE:
+    case UNION_TYPE:
+      return false;
+    default: return true;
+    }
+}
+
+/* Return true if the gimple STMT is handled.
+   If it is, set VR to the value_range by querying ranger R.
+   Return false otherwise.  */
+
+static bool
+handled_result_decl_code_p (gimple_ranger *r, gimple *stmt, value_range &vr)
+{
+  bool ok = false;
+  tree tstmt;
+
+  switch (gimple_code (stmt))
+    {
+    case GIMPLE_ASM:
+    case GIMPLE_NOP:
+      break;
+    case GIMPLE_RETURN:
+      tstmt = gimple_return_retval (as_a <greturn *> (stmt));
+      /* c-c++-common/pr53633-2.c, naked function
+         (gdb) call debug_gimple_stmt(stmt)
+	 # VUSE <.MEM_1(D)>
+	 return;
+	 p tstmt
+	 $3 = <tree 0x0>
+      */
+      if (tstmt == NULL_TREE)
+	return ok;
+      ok = r->range_of_expr (vr, tstmt,
+	    as_a <greturn *> (stmt));
+      break;
+    case GIMPLE_ASSIGN:
+#if 0
+      /* libgomp/loop_ull.c:414 gomp_loop_ull_dynamic_start
+(gdb) call debug(bb)
+<bb 45> [local count: 31004295]:
+_159 = team_45->nthreads;
+iftmp.1_87 = (long int) _159;
+_91 = (long long unsigned int) iftmp.1_87;
+# DEBUG nthreads => iftmp.1_87
+# DEBUG BEGIN_STMT
+goto <bb 17>; [100.00%]
+
+(gdb) p gsi_stmt(gsi_last_nondebug_bb (bb))
+$66 = <gimple_assign 0x7ffff6ef1cd0>
+(gdb) call debug(gsi_stmt(gsi_last_nondebug_bb (bb)))
+_91 = (long long unsigned int) iftmp.1_87;
+      The goto is the successor block flag
+      */
+      ok = get_range_query (fun)->range_of_expr (vr,
+	    gimple_assign_lhs (as_a <gassign *> (stmt)),
+	    as_a <gassign *> (stmt));
+#endif
+      break;
+    case GIMPLE_COND:
+#if 0
+      /* libgcc/generic-morestack.c:414 __generic_morestack */
+      ok = get_range_query (fun)->range_of_expr (vr,
+	    gimple_cond_lhs (as_a <gcond *> (stmt)),
+	    as_a <gcond *> (stmt));
+#endif
+      break;
+    case GIMPLE_CALL:
+#if 0
+      ok = get_range_query (fun)->range_of_expr (vr,
+	    gimple_call_lhs (as_a <gcall *> (stmt)),
+	    as_a <gcall *> (stmt));
+#endif
+      break;
+    case GIMPLE_SWITCH:
+#if 0
+      /* combine.c simplify_shift_const_1 */
+      break;
+#endif
+    case GIMPLE_LABEL:
+      break;
+    case GIMPLE_PHI:
+    case GIMPLE_RESX:
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  return ok;
+}
+
+static unsigned
+wnarrow_return (gimple_ranger *ranger, function *fun, bool do_demotion=false)
+{
+// targetm.calls.promote_prototypes
+// current_function_return_value
+// outer_curly_brace_block
+
+  tree decl = fun->decl;
+  /* Leave main alone.  */
+  if (MAIN_NAME_P (DECL_NAME (decl)))
+    return false;
+
+  /* We should probably leave the type of an exported API alone..  */
+  if (00 && DECL_VISIBILITY_SPECIFIED (decl)
+      && DECL_VISIBILITY (decl) == VISIBILITY_DEFAULT)
+    return false;
+
+  tree result = DECL_RESULT (decl);
+  tree result_type = TREE_TYPE (result);
+
+  if (! handled_result_decl_type_p (result_type))
+    return false;
+
+  /* Get the last nondebug statement of function FUN.  */
+  gimple *stmt = fn_last_stmt (fun);
+  if (stmt == NULL)
+    return false;
+
+  /* See if we can handle the gimple stmt to deduce a value_range.  */
+  value_range vr;
+  if (! handled_result_decl_code_p (ranger, stmt, vr))
+    return false;
+
+  if (vr.undefined_p())
+    return false; // Should not occur when returning ints
+  if (vr.varying_p())
+    return false; // Cannot do much about those
+
+  location_t loc = DECL_SOURCE_LOCATION (result);
+  gcc_rich_location iloc (loc);
+
+  if (!warnings_are_errors && vr.singleton_p() && 00) /* disabled for now */
+    {
+      auto_diagnostic_group d;
+      iloc.add_fixit_replace ("void");
+      // borked iloc.add_fixit_remove (LOCATION_LOCUS (gimple_location (stmt)));
+      if (warning_at (&iloc, OPT_Wtype_demotion,
+		      "Function %qE returns a single value", DECL_NAME(decl)))
+	{
+	  if (vr.num_pairs () == 1 && vr.lower_bound () == vr.upper_bound ())
+	    {
+	      if (wi::fits_shwi_p (vr.lower_bound ()))
+		inform (loc, "Maybe the function should be %<void%> "
+			"and the caller use a const value of "
+			"%wd "
+			"instead of the result of the call",
+			vr.lower_bound ().to_shwi ());
+	      else
+		inform (loc, "Maybe the function should be %<void%> "
+			"and the caller use a const value of "
+			"%wu "
+			"instead of the result of the call",
+			vr.lower_bound ().to_uhwi ());
+	    }
+	  else
+	    {
+	      gcc_unreachable (); // TODO: do this for non-singletons
+	      char *range_str = vr.as_string ();
+	      if (range_str)
+		inform (loc, "Maybe the function should be %<void%> "
+			"and the caller use a fixed value in the range of %s "
+			"instead of the result of the call",
+			range_str);
+	      free (range_str);
+	    }
+	}
+      return false;
+    }
+
+  wide_int ret_min = vr.lower_bound();
+  wide_int ret_max = vr.upper_bound();
+  signop ret_sgn = TYPE_SIGN (vr.type ());
+
+  // TODO: Nah.  We want [-42,-1] to suggest unsigned char
+  // TODO: and shift the caller accordingly.
+  if (00 && ! wi::neg_p (ret_min, ret_sgn) && ! wi::neg_p (ret_max, ret_sgn))
+    ret_sgn = UNSIGNED;
+
+  tree demoted = narrowest_type (ret_min, ret_max, ret_sgn);
+  if (demoted == NULL_TREE)
+    /* libgcc2.c UDWtype __fixunssfDI (SFtype a) , 128bit.  */
+    /* Don't know which typename to suggest to the user..  typeid? Punt.  */
+    return false;
+  gcc_checking_assert (demoted != NULL_TREE);
+//int o = TYPE_PRECISION (result_type);
+//int n = TYPE_PRECISION (demoted);
+  gcc_checking_assert (TYPE_PRECISION (demoted)
+      <= TYPE_PRECISION (result_type));
+
+  /* Punt if we cannot reduce the number of bits required.
+     ??? should we still favour signed -> unsigned conversion if possible?
+   */
+  if (TYPE_PRECISION (demoted) == TYPE_PRECISION (result_type))
+    return false;
+
+  if (warnings_are_errors)
+    return false; // libgomp/icv.c
+
+  char *caller_adjust = NULL;
+  int diff = 0;
+  if (TYPE_SIGN (demoted) != TYPE_SIGN (result_type))
+    {
+      if (TYPE_SIGN (demoted) == UNSIGNED)
+	{
+	  /* TYPE_MIN_VALUE (demoted) == 0  */
+	  //diff = wi::abs (wi::to_wide (vr.min ()));
+	  diff = tree_int_cst_sign_bit (vr.min ());
+	  caller_adjust = xasprintf ("+ %d", diff);
+	}
+      else
+	{
+	  diff = tree_int_cst_sign_bit (vr.max ())
+		  - tree_int_cst_sign_bit (vr.min ());
+	  caller_adjust = xasprintf ("XXX %d", diff);
+	}
+    }
+  auto_diagnostic_group d;
+  iloc.add_fixit_replace (
+      DECL_SOURCE_LOCATION (result),
+      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (demoted))));
+  if (warning_at (&iloc, OPT_Wtype_demotion, "Function %qE could return %qE",
+		  DECL_NAME (decl), DECL_NAME (TYPE_NAME (demoted))))
+    {
+      char *range_str = vr.as_string ();
+      if (range_str)
+	{
+	  if (diff)
+	    inform (loc, "with a range of %s and %s in the caller", range_str,
+		    caller_adjust);
+	  else
+	    inform (loc, "with a range of %s", range_str);
+	}
+      free (range_str);
+    }
+  free (caller_adjust);
+  if (dump_file)
+    {
+      fprintf (dump_file, "Function %s return type:\nold %s\nnew %s\n",
+	       print_generic_expr_to_str (DECL_NAME (decl)),
+	       print_generic_expr_to_str (DECL_NAME (result_type)),
+	       print_generic_expr_to_str (DECL_NAME (TYPE_NAME (demoted))));
+    }
+
+  if (!do_demotion)
+    return false;
+
+  /* We have a demoted type to use for the function result, use it.  */
+#if 1
+  return false;
+#else
+  //TREE_TYPE (result) = demoted;
+  //*result_type = *demoted;
+  This would have to be an IPA pass
+  return true;
+#endif
+}
+
+unsigned
+pass_wtype_demotion::execute (function *fun)
+{
+  gimple_ranger ranger;
+
+  if (wnarrow_return (&ranger, fun, /*do_demotion=*/true))
+    return TODO_update_ssa;
+
+  return 0;
+}
+
diff --git a/gcc/passes.def b/gcc/passes.def
index 193b5794749..d6c4a0609f5 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -202,6 +202,7 @@ along with GCC; see the file COPYING3.  If not see
 	 form if possible.  */
       NEXT_PASS (pass_object_sizes);
       NEXT_PASS (pass_post_ipa_warn);
+      NEXT_PASS (pass_warn_type_demotion);
       /* Must run before loop unrolling.  */
       NEXT_PASS (pass_warn_access, /*early=*/true);
       NEXT_PASS (pass_complete_unrolli);
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 8480d41384b..5d314bc7865 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -480,6 +480,7 @@ extern gimple_opt_pass *make_pass_local_pure_const (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_nothrow (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_tracer (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_warn_restrict (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_warn_type_demotion (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_warn_unused_result (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_diagnose_tm_blocks (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_lower_tm (gcc::context *ctxt);
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] value-range: Add as_string diagnostics helper
  2022-11-12 23:45 ` [PATCH 4/5] value-range: Add as_string diagnostics helper Bernhard Reutner-Fischer
@ 2022-11-12 23:55   ` Andrew Pinski
  2022-11-17  3:30     ` Jeff Law
  0 siblings, 1 reply; 20+ messages in thread
From: Andrew Pinski @ 2022-11-12 23:55 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer
  Cc: gcc-patches, Bernhard Reutner-Fischer, fortran, Andrew MacLeod,
	Aldy Hernandez

On Sat, Nov 12, 2022 at 3:47 PM Bernhard Reutner-Fischer via
Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>
> gcc/ChangeLog:
>
>         * value-range.cc (get_bound_with_infinite_markers): New static helper.
>         (irange::as_string): New definition.
>         * value-range.h: New declaration.
>
> ---
> Provide means to print a value range to a newly allocated buffer.
> The caller is responsible to free() the allocated memory.
>
> Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
> Ok for trunk?
>
> Cc: Andrew MacLeod <amacleod@redhat.com>
> Cc: Aldy Hernandez <aldyh@redhat.com>
> ---
>  gcc/value-range.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++
>  gcc/value-range.h  |  3 +++
>  2 files changed, 59 insertions(+)
>
> diff --git a/gcc/value-range.cc b/gcc/value-range.cc
> index a855aaf626c..51cd9a38d90 100644
> --- a/gcc/value-range.cc
> +++ b/gcc/value-range.cc
> @@ -3099,6 +3099,62 @@ debug (const value_range &vr)
>    fprintf (stderr, "\n");
>  }
>
> +/* Helper for irange::as_string().  Print a bound to an allocated buffer.  */
> +static char *

Can we start using std::string instead of char* here?


> +get_bound_with_infinite_markers (tree bound)
> +{
> +  tree type = TREE_TYPE (bound);
> +  wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
> +  wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
> +
> +  if (INTEGRAL_TYPE_P (type)
> +      && !TYPE_UNSIGNED (type)
> +      && TREE_CODE (bound) == INTEGER_CST
> +      && wi::to_wide (bound) == type_min
> +      && TYPE_PRECISION (type) != 1)
> +    return xstrdup ("-INF");
> +  else if (TREE_CODE (bound) == INTEGER_CST
> +          && wi::to_wide (bound) == type_max
> +          && TYPE_PRECISION (type) != 1)
> +    return xstrdup ("+INF");
> +  else
> +    return print_generic_expr_to_str (bound);
No reason to do xstrdup any more either.

> +}
> +
> +
> +/* Return an irange as string. Return NULL on failure, an allocated
> +   string on success.  */
> +char *

Likewise.

Thanks,
Andrew Pinski

> +irange::as_string ()
> +{
> +  char *ret = NULL;
This becomes std::string ret;
> +  if (undefined_p() || varying_p () || m_num_ranges == 0)
> +    return ret;
> +
> +  for (unsigned i = 0; i < m_num_ranges; ++i)
> +    {
> +      tree lb = m_base[i * 2];
> +      tree ub = m_base[i * 2 + 1];
> +      /* Construct [lower_bound,upper_bound].  */
> +      char *lbs = get_bound_with_infinite_markers (lb);
> +      char *ubs = get_bound_with_infinite_markers (ub);
> +      /* Paranoia mode */
> +      if (!lbs)
> +       lbs = xstrdup ("");
> +      if (!ubs)
> +       ubs = xstrdup ("");
> +
> +      if (ret)
> +       ret = reconcat (ret, ret, "[", lbs, ",", ubs, "]", NULL);
> +      else
> +       ret = concat ("[", lbs, ",", ubs, "]", NULL);
> +
> +      free (lbs);
> +      free (ubs);
> +    }
> +  return ret;
> +}
> +
>  /* Create two value-ranges in *VR0 and *VR1 from the anti-range *AR
>     so that *VR0 U *VR1 == *AR.  Returns true if that is possible,
>     false otherwise.  If *AR can be represented with a single range
> diff --git a/gcc/value-range.h b/gcc/value-range.h
> index c87734dd8cd..76242e4bf45 100644
> --- a/gcc/value-range.h
> +++ b/gcc/value-range.h
> @@ -160,6 +160,9 @@ public:
>    wide_int get_nonzero_bits () const;
>    void set_nonzero_bits (const wide_int_ref &bits);
>
> +  // For diagnostics.
> +  char *as_string ();
> +
>    // Deprecated legacy public methods.
>    tree min () const;                           // DEPRECATED
>    tree max () const;                           // DEPRECATED
> --
> 2.38.1
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/5] Fortran: Narrow return types [PR78798]
  2022-11-12 23:45 ` [PATCH 3/5] Fortran: Narrow return types [PR78798] Bernhard Reutner-Fischer
@ 2022-11-13 10:13   ` Janne Blomqvist
  2022-11-13 10:39     ` Bernhard Reutner-Fischer
  0 siblings, 1 reply; 20+ messages in thread
From: Janne Blomqvist @ 2022-11-13 10:13 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer; +Cc: gcc-patches, Bernhard Reutner-Fischer, fortran

On Sun, Nov 13, 2022 at 1:47 AM Bernhard Reutner-Fischer via Fortran
<fortran@gcc.gnu.org> wrote:
> --- a/gcc/fortran/arith.cc
> +++ b/gcc/fortran/arith.cc
> @@ -1135,7 +1135,7 @@ compare_complex (gfc_expr *op1, gfc_expr *op2)
>     strings.  We return -1 for a < b, 0 for a == b and 1 for a > b.
>     We use the processor's default collating sequence.  */
>
> -int
> +signed char
>  gfc_compare_string (gfc_expr *a, gfc_expr *b)
>  {
>    size_t len, alen, blen, i;
> @@ -1162,7 +1162,7 @@ gfc_compare_string (gfc_expr *a, gfc_expr *b)
>  }

Hmm, really? PR 78798 mentions changing int to bool, where
appropriate, which I think is uncontroversial, but this?


-- 
Janne Blomqvist

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/5] Fortran: Narrow return types [PR78798]
  2022-11-13 10:13   ` Janne Blomqvist
@ 2022-11-13 10:39     ` Bernhard Reutner-Fischer
  2022-11-13 20:29       ` Harald Anlauf
  0 siblings, 1 reply; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2022-11-13 10:39 UTC (permalink / raw)
  To: Janne Blomqvist
  Cc: rep.dot.nop, gcc-patches, Bernhard Reutner-Fischer, fortran

On Sun, 13 Nov 2022 12:13:26 +0200
Janne Blomqvist <blomqvist.janne@gmail.com> wrote:

> On Sun, Nov 13, 2022 at 1:47 AM Bernhard Reutner-Fischer via Fortran
> <fortran@gcc.gnu.org> wrote:
> > --- a/gcc/fortran/arith.cc
> > +++ b/gcc/fortran/arith.cc
> > @@ -1135,7 +1135,7 @@ compare_complex (gfc_expr *op1, gfc_expr *op2)
> >     strings.  We return -1 for a < b, 0 for a == b and 1 for a > b.
> >     We use the processor's default collating sequence.  */
> >
> > -int
> > +signed char
> >  gfc_compare_string (gfc_expr *a, gfc_expr *b)
> >  {
> >    size_t len, alen, blen, i;
> > @@ -1162,7 +1162,7 @@ gfc_compare_string (gfc_expr *a, gfc_expr *b)
> >  }  
> 
> Hmm, really? PR 78798 mentions changing int to bool, where
> appropriate, which I think is uncontroversial, but this?

Well we could leave this or all spots alone where a bool is
insufficient, if you prefer.

In the case of gfc_compare_string, the only user is simplify which only
looks at ge/gt/le/lt 0

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/5] Fortran: Narrow return types [PR78798]
  2022-11-13 10:39     ` Bernhard Reutner-Fischer
@ 2022-11-13 20:29       ` Harald Anlauf
  2022-11-13 21:50         ` Bernhard Reutner-Fischer
  0 siblings, 1 reply; 20+ messages in thread
From: Harald Anlauf @ 2022-11-13 20:29 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer, Janne Blomqvist
  Cc: gcc-patches, Bernhard Reutner-Fischer, fortran

Am 13.11.22 um 11:39 schrieb Bernhard Reutner-Fischer via Gcc-patches:
> On Sun, 13 Nov 2022 12:13:26 +0200
> Janne Blomqvist <blomqvist.janne@gmail.com> wrote:
>
>> On Sun, Nov 13, 2022 at 1:47 AM Bernhard Reutner-Fischer via Fortran
>> <fortran@gcc.gnu.org> wrote:
>>> --- a/gcc/fortran/arith.cc
>>> +++ b/gcc/fortran/arith.cc
>>> @@ -1135,7 +1135,7 @@ compare_complex (gfc_expr *op1, gfc_expr *op2)
>>>      strings.  We return -1 for a < b, 0 for a == b and 1 for a > b.
>>>      We use the processor's default collating sequence.  */
>>>
>>> -int
>>> +signed char
>>>   gfc_compare_string (gfc_expr *a, gfc_expr *b)
>>>   {
>>>     size_t len, alen, blen, i;
>>> @@ -1162,7 +1162,7 @@ gfc_compare_string (gfc_expr *a, gfc_expr *b)
>>>   }
>>
>> Hmm, really? PR 78798 mentions changing int to bool, where
>> appropriate, which I think is uncontroversial, but this?
>
> Well we could leave this or all spots alone where a bool is
> insufficient, if you prefer.
>
> In the case of gfc_compare_string, the only user is simplify which only
> looks at ge/gt/le/lt 0

My reading of the mentioned PR is that there is a fundamental
disagreement with the subject:

Bug 78798 - [cleanup] some int-valued functions should be bool

I see that as an issue of (a minor lack of) conciseness;
it is *not* about narrowing.

Replacing "int" by "signed char" adds confusion and makes code
less understandable, so I would oppose it, as we don't solve a
real problem and rather add confusion.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/5] Fortran: Narrow return types [PR78798]
  2022-11-13 20:29       ` Harald Anlauf
@ 2022-11-13 21:50         ` Bernhard Reutner-Fischer
  2023-05-10 16:47           ` [PATCH v2] " Bernhard Reutner-Fischer
  0 siblings, 1 reply; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2022-11-13 21:50 UTC (permalink / raw)
  To: Harald Anlauf, Janne Blomqvist
  Cc: gcc-patches, Bernhard Reutner-Fischer, fortran

On 13 November 2022 21:29:50 CET, Harald Anlauf <anlauf@gmx.de> wrote:

>Replacing "int" by "signed char" adds confusion and makes code
>less understandable, so I would oppose it, as we don't solve a
>real problem and rather add confusion.

Ok so consider the non-bool hunks dropped, they just fell out of my helper and I thought I'd ask.

I can send an updated patch during the weekend.

thanks,

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/5] c: Set the locus of the function result decl
  2022-11-12 23:45 ` [PATCH 1/5] c: Set the locus of the function result decl Bernhard Reutner-Fischer
@ 2022-11-14 21:25   ` Joseph Myers
  0 siblings, 0 replies; 20+ messages in thread
From: Joseph Myers @ 2022-11-14 21:25 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer; +Cc: gcc-patches, Bernhard Reutner-Fischer, fortran

On Sun, 13 Nov 2022, Bernhard Reutner-Fischer via Gcc-patches wrote:

> Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
> Ok for trunk?
> 
> Cc: Joseph Myers <joseph@codesourcery.com>
> ---
> gcc/c/ChangeLog:
> 
> 	* c-decl.cc (start_function): Set the result decl source
> 	location to the location of the typespec.

OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/5] c++: Set the locus of the function result decl
  2022-11-12 23:45 ` [PATCH 2/5] c++: " Bernhard Reutner-Fischer
@ 2022-11-15 23:52   ` Jason Merrill
  0 siblings, 0 replies; 20+ messages in thread
From: Jason Merrill @ 2022-11-15 23:52 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer, gcc-patches
  Cc: Bernhard Reutner-Fischer, fortran, Nathan Sidwell

On 11/12/22 13:45, Bernhard Reutner-Fischer wrote:
> gcc/cp/ChangeLog:
> 
> 	* decl.cc (start_function): Set the result decl source location to
> 	the location of the typespec.
> 
> ---
> Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
> Ok for trunk?
> 
> Cc: Nathan Sidwell <nathan@acm.org>
> Cc: Jason Merrill <jason@redhat.com>
> ---
>   gcc/cp/decl.cc | 15 ++++++++++++++-
>   1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> index 6e98ea35a39..ed40815e645 100644
> --- a/gcc/cp/decl.cc
> +++ b/gcc/cp/decl.cc
> @@ -17449,6 +17449,8 @@ start_function (cp_decl_specifier_seq *declspecs,
>   		tree attrs)
>   {
>     tree decl1;
> +  tree result;
> +  bool ret;

We now prefer to declare new variables as late as possible, usually when 
they are initialized.

>     decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
>     invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
> @@ -17461,7 +17463,18 @@ start_function (cp_decl_specifier_seq *declspecs,
>       gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
>   			     integer_type_node));
>   
> -  return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
> +  ret = start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
> +
> +  /* decl1 might be ggc_freed here.  */
> +  decl1 = current_function_decl;
> +
> +  /* Set the result decl source location to the location of the typespec.  */
> +  if (TREE_CODE (decl1) == FUNCTION_DECL
> +      && declspecs->locations[ds_type_spec] != UNKNOWN_LOCATION
> +      && (result = DECL_RESULT (decl1)) != NULL_TREE
> +      && DECL_SOURCE_LOCATION (result) == input_location)
> +    DECL_SOURCE_LOCATION (result) = declspecs->locations[ds_type_spec];

One way to handle the template case would be for the code in 
start_preparsed_function that sets DECL_RESULT to check whether decl1 is 
a template instantiation, and in that case copy the location from the 
template's DECL_RESULT, i.e.

DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1)))

> +  return ret;
>   }
>   \f
>   /* Returns true iff an EH_SPEC_BLOCK should be created in the body of


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/5] value-range: Add as_string diagnostics helper
  2022-11-12 23:55   ` Andrew Pinski
@ 2022-11-17  3:30     ` Jeff Law
  0 siblings, 0 replies; 20+ messages in thread
From: Jeff Law @ 2022-11-17  3:30 UTC (permalink / raw)
  To: Andrew Pinski, Bernhard Reutner-Fischer
  Cc: gcc-patches, Bernhard Reutner-Fischer, fortran, Andrew MacLeod,
	Aldy Hernandez


On 11/12/22 16:55, Andrew Pinski via Gcc-patches wrote:
> On Sat, Nov 12, 2022 at 3:47 PM Bernhard Reutner-Fischer via
> Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>> gcc/ChangeLog:
>>
>>          * value-range.cc (get_bound_with_infinite_markers): New static helper.
>>          (irange::as_string): New definition.
>>          * value-range.h: New declaration.
>>
>> ---
>> Provide means to print a value range to a newly allocated buffer.
>> The caller is responsible to free() the allocated memory.
>>
>> Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
>> Ok for trunk?
>>
>> Cc: Andrew MacLeod <amacleod@redhat.com>
>> Cc: Aldy Hernandez <aldyh@redhat.com>
>> ---
>>   gcc/value-range.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++
>>   gcc/value-range.h  |  3 +++
>>   2 files changed, 59 insertions(+)
>>
>> diff --git a/gcc/value-range.cc b/gcc/value-range.cc
>> index a855aaf626c..51cd9a38d90 100644
>> --- a/gcc/value-range.cc
>> +++ b/gcc/value-range.cc
>> @@ -3099,6 +3099,62 @@ debug (const value_range &vr)
>>     fprintf (stderr, "\n");
>>   }
>>
>> +/* Helper for irange::as_string().  Print a bound to an allocated buffer.  */
>> +static char *
> Can we start using std::string instead of char* here?

If it makes the code easier to read/maintain, sure.  std::string isn't 
used heavily, but has crept into a few places, mostly in target files.  
std::string isn't something we've pushed at all in terms of preferred 
practices.


Jeff

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2] Fortran: Narrow return types [PR78798]
  2022-11-13 21:50         ` Bernhard Reutner-Fischer
@ 2023-05-10 16:47           ` Bernhard Reutner-Fischer
  2023-05-14 12:27             ` Mikael Morin
  0 siblings, 1 reply; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2023-05-10 16:47 UTC (permalink / raw)
  To: fortran; +Cc: gcc-patches, Bernhard Reutner-Fischer

From: Bernhard Reutner-Fischer <aldot@gcc.gnu.org>

gcc/fortran/ChangeLog:

	PR fortran/78798
	* array.cc (compare_bounds): Use narrower return type.
	(gfc_compare_array_spec): Likewise.
	(is_constant_element): Likewise.
	(gfc_constant_ac): Likewise.
	* check.cc (dim_rank_check): Likewise.
	* cpp.cc (gfc_cpp_init_options): Likewise.
	(dump_macro): Likewise.
	* cpp.h (gfc_cpp_handle_option): Likewise.
	* dependency.cc (gfc_ref_needs_temporary_p): Likewise.
	(gfc_check_argument_dependency): Likewise.
	(gfc_check_fncall_dependency): Likewise.
	(ref_same_as_full_array): Likewise.
	* dependency.h (gfc_check_fncall_dependency): Likewise.
	(gfc_dep_resolver): Likewise.
	(gfc_are_equivalenced_arrays): Likewise.
	* expr.cc (gfc_copy_ref): Likewise.
	(gfc_kind_max): Likewise.
	(numeric_type): Likewise.
	* gfortran.h (gfc_at_end): Likewise.
	(gfc_at_eof): Likewise.
	(gfc_at_bol): Likewise.
	(gfc_at_eol): Likewise.
	(gfc_define_undef_line): Likewise.
	(gfc_wide_is_printable): Likewise.
	(gfc_wide_is_digit): Likewise.
	(gfc_wide_fits_in_byte): Likewise.
	(gfc_find_sym_tree): Likewise.
	(gfc_generic_intrinsic): Likewise.
	(gfc_specific_intrinsic): Likewise.
	(gfc_intrinsic_actual_ok): Likewise.
	(gfc_has_vector_index): Likewise.
	(gfc_numeric_ts): Likewise.
	(gfc_impure_variable): Likewise.
	(gfc_pure): Likewise.
	(gfc_implicit_pure): Likewise.
	(gfc_elemental): Likewise.
	(gfc_pure_function): Likewise.
	(gfc_implicit_pure_function): Likewise.
	(gfc_compare_array_spec): Likewise.
	(gfc_constant_ac): Likewise.
	(gfc_expanded_ac): Likewise.
	(gfc_check_digit): Likewise.
	* intrinsic.cc (gfc_find_subroutine): Likewise.
	(gfc_generic_intrinsic): Likewise.
	(gfc_specific_intrinsic): Likewise.
	* io.cc (compare_to_allowed_values): Likewise. And remove
	unneeded forward declaration.
	* misc.cc (gfc_done_2): Likewise.
	* parse.cc: Likewise.
	* parse.h (gfc_check_do_variable): Likewise.
	* primary.cc (gfc_check_digit): Likewise.
	* resolve.cc (resolve_structure_cons): Likewise.
	(pure_stmt_function): Likewise.
	(gfc_pure_function): Likewise.
	(impure_stmt_fcn): Likewise.
	(resolve_forall_iterators): Likewise.
	(resolve_data): Likewise.
	(gfc_impure_variable): Likewise.
	(gfc_pure): Likewise.
	(gfc_unset_implicit_pure): Likewise.
	* scanner.cc (wide_is_ascii): Likewise.
	(gfc_wide_toupper): Likewise.
	(gfc_open_included_file): Likewise.
	(gfc_at_end): Likewise.
	(gfc_at_eof): Likewise.
	(gfc_at_bol): Likewise.
	(skip_comment_line): Likewise.
	(gfc_gobble_whitespace): Likewise.
	* symbol.cc (gfc_find_symtree_in_proc): Likewise.
	* trans-array.cc: Likewise.
	* trans-decl.cc (gfc_set_decl_assembler_name): Likewise.
	* trans-types.cc (gfc_get_element_type): Likewise.
	(gfc_add_field_to_struct): Likewise.
	* trans-types.h (gfc_copy_dt_decls_ifequal): Likewise.
	(gfc_return_by_reference): Likewise.
	(gfc_is_nodesc_array): Likewise.
	* trans.h (gfc_can_put_var_on_stack): Likewise.
---
Bootstrapped without new warnings and regression tested on
x86_64-linux with no regressions, OK for trunk?

 gcc/fortran/array.cc       |  8 +++----
 gcc/fortran/check.cc       |  2 +-
 gcc/fortran/cpp.cc         |  3 +--
 gcc/fortran/cpp.h          |  2 +-
 gcc/fortran/dependency.cc  |  8 +++----
 gcc/fortran/dependency.h   |  6 ++---
 gcc/fortran/expr.cc        |  6 ++---
 gcc/fortran/gfortran.h     | 48 +++++++++++++++++++-------------------
 gcc/fortran/intrinsic.cc   |  6 ++---
 gcc/fortran/io.cc          | 13 ++---------
 gcc/fortran/parse.cc       |  2 +-
 gcc/fortran/parse.h        |  2 +-
 gcc/fortran/primary.cc     |  4 ++--
 gcc/fortran/resolve.cc     | 22 ++++++++---------
 gcc/fortran/scanner.cc     | 20 ++++++++--------
 gcc/fortran/symbol.cc      |  2 +-
 gcc/fortran/trans-array.cc |  2 +-
 gcc/fortran/trans-decl.cc  |  2 +-
 gcc/fortran/trans-types.cc |  6 ++---
 gcc/fortran/trans-types.h  |  6 ++---
 gcc/fortran/trans.h        |  2 +-
 21 files changed, 81 insertions(+), 91 deletions(-)

diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
index be5eb8b6a0f..4b7c1e715bf 100644
--- a/gcc/fortran/array.cc
+++ b/gcc/fortran/array.cc
@@ -994,7 +994,7 @@ compare_bounds (gfc_expr *bound1, gfc_expr *bound2)
 /* Compares two array specifications.  They must be constant or deferred
    shape.  */
 
-int
+bool
 gfc_compare_array_spec (gfc_array_spec *as1, gfc_array_spec *as2)
 {
   int i;
@@ -1039,7 +1039,7 @@ gfc_compare_array_spec (gfc_array_spec *as1, gfc_array_spec *as2)
    use the symbol as an implied-DO iterator.  Returns nonzero if a
    duplicate was found.  */
 
-static int
+static bool
 check_duplicate_iterator (gfc_constructor_base base, gfc_symbol *master)
 {
   gfc_constructor *c;
@@ -1982,7 +1982,7 @@ is_constant_element (gfc_expr *e)
    i=1,100000000) /) will take a while as* opposed to a more clever
    function that traverses the expression tree. FIXME.  */
 
-int
+bool
 gfc_constant_ac (gfc_expr *e)
 {
   expand_info expand_save;
@@ -2005,7 +2005,7 @@ gfc_constant_ac (gfc_expr *e)
 /* Returns nonzero if an array constructor has been completely
    expanded (no iterators) and zero if iterators are present.  */
 
-int
+bool
 gfc_expanded_ac (gfc_expr *e)
 {
   gfc_constructor *c;
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index b348bda6e6c..4e3aed84b9d 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -1156,7 +1156,7 @@ dim_rank_check (gfc_expr *dim, gfc_expr *array, int allow_assumed)
    dimension bi, returning 0 if they are known not to be identical,
    and 1 if they are identical, or if this cannot be determined.  */
 
-static int
+static bool
 identical_dimen_shape (gfc_expr *a, int ai, gfc_expr *b, int bi)
 {
   mpz_t a_size, b_size;
diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc
index c3b7c7f7bd9..d7890a97287 100644
--- a/gcc/fortran/cpp.cc
+++ b/gcc/fortran/cpp.cc
@@ -297,7 +297,7 @@ gfc_cpp_init_options (unsigned int decoded_options_count,
   gfc_cpp_option.deferred_opt_count = 0;
 }
 
-int
+bool
 gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED)
 {
   int result = 1;
@@ -749,7 +749,6 @@ gfc_cpp_add_include_path_after (char *path, bool user_supplied)
 
 static void scan_translation_unit_trad (cpp_reader *);
 static void account_for_newlines (const unsigned char *, size_t);
-static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
 
 static void print_line (location_t, const char *);
 static void maybe_print_line (location_t);
diff --git a/gcc/fortran/cpp.h b/gcc/fortran/cpp.h
index 886996f2784..d2fbfcf9525 100644
--- a/gcc/fortran/cpp.h
+++ b/gcc/fortran/cpp.h
@@ -39,7 +39,7 @@ void gfc_cpp_init (void);
 void gfc_cpp_init_options (unsigned int decoded_options_count,
 			   struct cl_decoded_option *decoded_options);
 
-int gfc_cpp_handle_option(size_t scode, const char *arg, int value);
+bool gfc_cpp_handle_option(size_t scode, const char *arg, int value);
 
 void gfc_cpp_post_options (bool);
 
diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
index a648d5c7903..b398b29a642 100644
--- a/gcc/fortran/dependency.cc
+++ b/gcc/fortran/dependency.cc
@@ -921,7 +921,7 @@ gfc_ref_needs_temporary_p (gfc_ref *ref)
 }
 
 
-static int
+static bool
 gfc_is_data_pointer (gfc_expr *e)
 {
   gfc_ref *ref;
@@ -1091,7 +1091,7 @@ gfc_check_argument_dependency (gfc_expr *other, sym_intent intent,
 /* Like gfc_check_argument_dependency, but check all the arguments in ACTUAL.
    FNSYM is the function being called, or NULL if not known.  */
 
-int
+bool
 gfc_check_fncall_dependency (gfc_expr *other, sym_intent intent,
 			     gfc_symbol *fnsym, gfc_actual_arglist *actual,
 			     gfc_dep_check elemental)
@@ -1137,7 +1137,7 @@ gfc_check_fncall_dependency (gfc_expr *other, sym_intent intent,
    e1->ref and e2->ref to determine whether the actually accessed
    portions of these variables/arrays potentially overlap.  */
 
-int
+bool
 gfc_are_equivalenced_arrays (gfc_expr *e1, gfc_expr *e2)
 {
   gfc_equiv_list *l;
@@ -2098,7 +2098,7 @@ ref_same_as_full_array (gfc_ref *full_ref, gfc_ref *ref)
 	    there is some kind of overlap.
 	0 : array references are identical or not overlapping.  */
 
-int
+bool
 gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
 		  bool identical)
 {
diff --git a/gcc/fortran/dependency.h b/gcc/fortran/dependency.h
index b1150316f5d..fbbede8b22c 100644
--- a/gcc/fortran/dependency.h
+++ b/gcc/fortran/dependency.h
@@ -32,13 +32,13 @@ enum gfc_dep_check
 bool gfc_ref_needs_temporary_p (gfc_ref *);
 bool gfc_full_array_ref_p (gfc_ref *, bool *);
 gfc_expr *gfc_get_noncopying_intrinsic_argument (gfc_expr *);
-int gfc_check_fncall_dependency (gfc_expr *, sym_intent, gfc_symbol *,
+bool gfc_check_fncall_dependency (gfc_expr *, sym_intent, gfc_symbol *,
 				 gfc_actual_arglist *, gfc_dep_check);
 int gfc_check_dependency (gfc_expr *, gfc_expr *, bool);
 int gfc_expr_is_one (gfc_expr *, int);
 
-int gfc_dep_resolver (gfc_ref *, gfc_ref *, gfc_reverse *,
+bool gfc_dep_resolver (gfc_ref *, gfc_ref *, gfc_reverse *,
 		      bool identical = false);
-int gfc_are_equivalenced_arrays (gfc_expr *, gfc_expr *);
+bool gfc_are_equivalenced_arrays (gfc_expr *, gfc_expr *);
 
 gfc_expr * gfc_discard_nops (gfc_expr *);
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index d91722e6ac6..aa01a4d3d22 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -798,7 +798,7 @@ gfc_copy_ref (gfc_ref *src)
 
 /* Detect whether an expression has any vector index array references.  */
 
-int
+bool
 gfc_has_vector_index (gfc_expr *e)
 {
   gfc_ref *ref;
@@ -888,7 +888,7 @@ gfc_kind_max (gfc_expr *e1, gfc_expr *e2)
 
 /* Returns nonzero if the type is numeric, zero otherwise.  */
 
-static int
+static bool
 numeric_type (bt type)
 {
   return type == BT_COMPLEX || type == BT_REAL || type == BT_INTEGER;
@@ -897,7 +897,7 @@ numeric_type (bt type)
 
 /* Returns nonzero if the typespec is a numeric type, zero otherwise.  */
 
-int
+bool
 gfc_numeric_ts (gfc_typespec *ts)
 {
   return numeric_type (ts->type);
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index ac21e1813d9..9dd6b45f112 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3220,16 +3220,16 @@ void gfc_release_include_path (void);
 void gfc_check_include_dirs (bool);
 FILE *gfc_open_included_file (const char *, bool, bool);
 
-int gfc_at_end (void);
-int gfc_at_eof (void);
-int gfc_at_bol (void);
-int gfc_at_eol (void);
+bool gfc_at_end (void);
+bool gfc_at_eof (void);
+bool gfc_at_bol (void);
+bool gfc_at_eol (void);
 void gfc_advance_line (void);
-int gfc_define_undef_line (void);
+bool gfc_define_undef_line (void);
 
-int gfc_wide_is_printable (gfc_char_t);
-int gfc_wide_is_digit (gfc_char_t);
-int gfc_wide_fits_in_byte (gfc_char_t);
+bool gfc_wide_is_printable (gfc_char_t);
+bool gfc_wide_is_digit (gfc_char_t);
+bool gfc_wide_fits_in_byte (gfc_char_t);
 gfc_char_t gfc_wide_tolower (gfc_char_t);
 gfc_char_t gfc_wide_toupper (gfc_char_t);
 size_t gfc_wide_strlen (const gfc_char_t *);
@@ -3487,7 +3487,7 @@ void gfc_release_symbol (gfc_symbol *&);
 gfc_symbol *gfc_new_symbol (const char *, gfc_namespace *);
 gfc_symtree* gfc_find_symtree_in_proc (const char *, gfc_namespace *);
 int gfc_find_symbol (const char *, gfc_namespace *, int, gfc_symbol **);
-int gfc_find_sym_tree (const char *, gfc_namespace *, int, gfc_symtree **);
+bool gfc_find_sym_tree (const char *, gfc_namespace *, int, gfc_symtree **);
 int gfc_get_symbol (const char *, gfc_namespace *, gfc_symbol **);
 bool gfc_verify_c_interop (gfc_typespec *);
 bool gfc_verify_c_interop_param (gfc_symbol *);
@@ -3567,10 +3567,10 @@ bool gfc_convert_type (gfc_expr *, gfc_typespec *, int);
 bool gfc_convert_type_warn (gfc_expr *, gfc_typespec *, int, int,
 			    bool array = false);
 bool gfc_convert_chartype (gfc_expr *, gfc_typespec *);
-int gfc_generic_intrinsic (const char *);
-int gfc_specific_intrinsic (const char *);
+bool gfc_generic_intrinsic (const char *);
+bool gfc_specific_intrinsic (const char *);
 bool gfc_is_intrinsic (gfc_symbol*, int, locus);
-int gfc_intrinsic_actual_ok (const char *, const bool);
+bool gfc_intrinsic_actual_ok (const char *, const bool);
 gfc_intrinsic_sym *gfc_find_function (const char *);
 gfc_intrinsic_sym *gfc_find_subroutine (const char *);
 gfc_intrinsic_sym *gfc_intrinsic_function_by_id (gfc_isym_id);
@@ -3648,7 +3648,7 @@ void gfc_type_convert_binary (gfc_expr *, int);
 bool gfc_is_constant_expr (gfc_expr *);
 bool gfc_simplify_expr (gfc_expr *, int);
 bool gfc_try_simplify_expr (gfc_expr *, int);
-int gfc_has_vector_index (gfc_expr *);
+bool gfc_has_vector_index (gfc_expr *);
 
 gfc_expr *gfc_get_expr (void);
 gfc_expr *gfc_get_array_expr (bt type, int kind, locus *);
@@ -3672,7 +3672,7 @@ gfc_ref* gfc_copy_ref (gfc_ref*);
 
 bool gfc_specification_expr (gfc_expr *);
 
-int gfc_numeric_ts (gfc_typespec *);
+bool gfc_numeric_ts (gfc_typespec *);
 int gfc_kind_max (gfc_expr *, gfc_expr *);
 
 bool gfc_check_conformance (gfc_expr *, gfc_expr *, const char *, ...) ATTRIBUTE_PRINTF_3;
@@ -3737,11 +3737,11 @@ void gfc_resolve (gfc_namespace *);
 void gfc_resolve_code (gfc_code *, gfc_namespace *);
 void gfc_resolve_blocks (gfc_code *, gfc_namespace *);
 void gfc_resolve_formal_arglist (gfc_symbol *);
-int gfc_impure_variable (gfc_symbol *);
-int gfc_pure (gfc_symbol *);
-int gfc_implicit_pure (gfc_symbol *);
+bool gfc_impure_variable (gfc_symbol *);
+bool gfc_pure (gfc_symbol *);
+bool gfc_implicit_pure (gfc_symbol *);
 void gfc_unset_implicit_pure (gfc_symbol *);
-int gfc_elemental (gfc_symbol *);
+bool gfc_elemental (gfc_symbol *);
 bool gfc_resolve_iterator (gfc_iterator *, bool, bool);
 bool find_forall_index (gfc_expr *, gfc_symbol *, int);
 bool gfc_resolve_index (gfc_expr *, int);
@@ -3755,8 +3755,8 @@ bool gfc_resolve_intrinsic (gfc_symbol *, locus *);
 bool gfc_explicit_interface_required (gfc_symbol *, char *, int);
 extern int gfc_do_concurrent_flag;
 const char* gfc_lookup_function_fuzzy (const char *, gfc_symtree *);
-int gfc_pure_function (gfc_expr *e, const char **name);
-int gfc_implicit_pure_function (gfc_expr *e);
+bool gfc_pure_function (gfc_expr *e, const char **name);
+bool gfc_implicit_pure_function (gfc_expr *e);
 
 
 /* array.cc */
@@ -3769,12 +3769,12 @@ bool gfc_set_array_spec (gfc_symbol *, gfc_array_spec *, locus *);
 gfc_array_spec *gfc_copy_array_spec (gfc_array_spec *);
 bool gfc_resolve_array_spec (gfc_array_spec *, int);
 
-int gfc_compare_array_spec (gfc_array_spec *, gfc_array_spec *);
+bool gfc_compare_array_spec (gfc_array_spec *, gfc_array_spec *);
 
 void gfc_simplify_iterator_var (gfc_expr *);
 bool gfc_expand_constructor (gfc_expr *, bool);
-int gfc_constant_ac (gfc_expr *);
-int gfc_expanded_ac (gfc_expr *);
+bool gfc_constant_ac (gfc_expr *);
+bool gfc_expanded_ac (gfc_expr *);
 bool gfc_resolve_character_array_constructor (gfc_expr *);
 bool gfc_resolve_array_constructor (gfc_expr *);
 bool gfc_check_constructor_type (gfc_expr *);
@@ -3859,7 +3859,7 @@ symbol_attribute gfc_expr_attr (gfc_expr *);
 symbol_attribute gfc_caf_attr (gfc_expr *, bool i = false, bool *r = NULL);
 match gfc_match_rvalue (gfc_expr **);
 match gfc_match_varspec (gfc_expr*, int, bool, bool);
-int gfc_check_digit (char, int);
+bool gfc_check_digit (char, int);
 bool gfc_is_function_return_value (gfc_symbol *, gfc_namespace *);
 bool gfc_convert_to_structure_constructor (gfc_expr *, gfc_symbol *,
 					      gfc_expr **,
diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc
index b5ef664eb33..74970e567fc 100644
--- a/gcc/fortran/intrinsic.cc
+++ b/gcc/fortran/intrinsic.cc
@@ -1107,7 +1107,7 @@ gfc_find_subroutine (const char *name)
 /* Given a string, figure out if it is the name of a generic intrinsic
    function or not.  */
 
-int
+bool
 gfc_generic_intrinsic (const char *name)
 {
   gfc_intrinsic_sym *sym;
@@ -1120,7 +1120,7 @@ gfc_generic_intrinsic (const char *name)
 /* Given a string, figure out if it is the name of a specific
    intrinsic function or not.  */
 
-int
+bool
 gfc_specific_intrinsic (const char *name)
 {
   gfc_intrinsic_sym *sym;
@@ -1132,7 +1132,7 @@ gfc_specific_intrinsic (const char *name)
 
 /* Given a string, figure out if it is the name of an intrinsic function
    or subroutine allowed as an actual argument or not.  */
-int
+bool
 gfc_intrinsic_actual_ok (const char *name, const bool subroutine_flag)
 {
   gfc_intrinsic_sym *sym;
diff --git a/gcc/fortran/io.cc b/gcc/fortran/io.cc
index 594f609cbf7..f0c605ebd80 100644
--- a/gcc/fortran/io.cc
+++ b/gcc/fortran/io.cc
@@ -2010,15 +2010,6 @@ gfc_free_open (gfc_open *open)
   free (open);
 }
 
-
-static int
-compare_to_allowed_values (const char *specifier, const char *allowed[],
-			   const char *allowed_f2003[],
-			   const char *allowed_gnu[], gfc_char_t *value,
-			   const char *statement, bool warn, locus *where,
-			   int *num = NULL);
-
-
 static bool
 check_open_constraints (gfc_open *open, locus *where);
 
@@ -2062,12 +2053,12 @@ gfc_resolve_open (gfc_open *open, locus *where)
    value if it is not allowed.  */
 
 
-static int
+static bool
 compare_to_allowed_values (const char *specifier, const char *allowed[],
 			   const char *allowed_f2003[],
 			   const char *allowed_gnu[], gfc_char_t *value,
 			   const char *statement, bool warn, locus *where,
-			   int *num)
+			   int *num = NULL)
 {
   int i;
   unsigned int len;
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index f1e55316e5b..5e2a95688d2 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -4710,7 +4710,7 @@ done:
    context that causes it to become redefined.  If the symbol is an
    iterator, we generate an error message and return nonzero.  */
 
-int
+bool
 gfc_check_do_variable (gfc_symtree *st)
 {
   gfc_state_data *s;
diff --git a/gcc/fortran/parse.h b/gcc/fortran/parse.h
index 75aac8bb2a1..cc57e7d5729 100644
--- a/gcc/fortran/parse.h
+++ b/gcc/fortran/parse.h
@@ -63,7 +63,7 @@ extern gfc_state_data *gfc_state_stack;
 #define gfc_comp_struct(s) \
   ((s) == COMP_DERIVED || (s) == COMP_STRUCTURE || (s) == COMP_MAP)
 
-int gfc_check_do_variable (gfc_symtree *);
+bool gfc_check_do_variable (gfc_symtree *);
 bool gfc_find_state (gfc_compile_state);
 gfc_state_data *gfc_enclosing_unit (gfc_compile_state *);
 const char *gfc_ascii_statement (gfc_statement, bool strip_sentinel = false) ;
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 077489ab96e..3099f82850c 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -109,10 +109,10 @@ get_kind (int *is_iso_c)
 /* Given a character and a radix, see if the character is a valid
    digit in that radix.  */
 
-int
+bool
 gfc_check_digit (char c, int radix)
 {
-  int r;
+  bool r;
 
   switch (radix)
     {
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 58f05a3e74a..9c92958a397 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -1585,7 +1585,7 @@ resolve_structure_cons (gfc_expr *expr, int init)
 /* Returns 0 if a symbol was not declared with a type or
    attribute declaration statement, nonzero otherwise.  */
 
-static int
+static bool
 was_declared (gfc_symbol *sym)
 {
   symbol_attribute a;
@@ -3091,13 +3091,13 @@ is_external_proc (gfc_symbol *sym)
 /* Figure out if a function reference is pure or not.  Also set the name
    of the function for a potential error message.  Return nonzero if the
    function is PURE, zero if not.  */
-static int
+static bool
 pure_stmt_function (gfc_expr *, gfc_symbol *);
 
-int
+bool
 gfc_pure_function (gfc_expr *e, const char **name)
 {
-  int pure;
+  bool pure;
   gfc_component *comp;
 
   *name = NULL;
@@ -3137,7 +3137,7 @@ gfc_pure_function (gfc_expr *e, const char **name)
 
 /* Check if the expression is a reference to an implicitly pure function.  */
 
-int
+bool
 gfc_implicit_pure_function (gfc_expr *e)
 {
   gfc_component *comp = gfc_get_proc_ptr_comp (e);
@@ -3168,7 +3168,7 @@ impure_stmt_fcn (gfc_expr *e, gfc_symbol *sym,
 }
 
 
-static int
+static bool
 pure_stmt_function (gfc_expr *e, gfc_symbol *sym)
 {
   return gfc_traverse_expr (e, sym, impure_stmt_fcn, 0) ? 0 : 1;
@@ -7630,7 +7630,7 @@ resolve_forall_iterators (gfc_forall_iterator *it)
    PRIVATE.  The search is recursive if necessary.  Returns zero if no
    inaccessible components are found, nonzero otherwise.  */
 
-static int
+static bool
 derived_inaccessible (gfc_symbol *sym)
 {
   gfc_component *c;
@@ -17126,7 +17126,7 @@ resolve_data (gfc_data *d)
 /* Determines if a variable is not 'pure', i.e., not assignable within a pure
    procedure.  Returns zero if assignment is OK, nonzero if there is a
    problem.  */
-int
+bool
 gfc_impure_variable (gfc_symbol *sym)
 {
   gfc_symbol *proc;
@@ -17161,7 +17161,7 @@ gfc_impure_variable (gfc_symbol *sym)
 /* Test whether a symbol is pure or not.  For a NULL pointer, checks if the
    current namespace is inside a pure procedure.  */
 
-int
+bool
 gfc_pure (gfc_symbol *sym)
 {
   symbol_attribute attr;
@@ -17193,7 +17193,7 @@ gfc_pure (gfc_symbol *sym)
    checks if the current namespace is implicitly pure.  Note that this
    function returns false for a PURE procedure.  */
 
-int
+bool
 gfc_implicit_pure (gfc_symbol *sym)
 {
   gfc_namespace *ns;
@@ -17247,7 +17247,7 @@ gfc_unset_implicit_pure (gfc_symbol *sym)
 
 /* Test whether the current procedure is elemental or not.  */
 
-int
+bool
 gfc_elemental (gfc_symbol *sym)
 {
   symbol_attribute attr;
diff --git a/gcc/fortran/scanner.cc b/gcc/fortran/scanner.cc
index 4f45da44607..9f0d9a7dc5e 100644
--- a/gcc/fortran/scanner.cc
+++ b/gcc/fortran/scanner.cc
@@ -56,7 +56,7 @@ gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
 
 static gfc_file *file_head, *current_file;
 
-static int continue_flag, end_flag, gcc_attribute_flag;
+static bool continue_flag, end_flag, gcc_attribute_flag;
 /* If !$omp/!$acc occurred in current comment line.  */
 static int openmp_flag, openacc_flag;
 static int continue_count, continue_line;
@@ -86,7 +86,7 @@ static gfc_char_t *last_error_char;
 /* Functions dealing with our wide characters (gfc_char_t) and
    sequences of such characters.  */
 
-int
+bool
 gfc_wide_fits_in_byte (gfc_char_t c)
 {
   return (c <= UCHAR_MAX);
@@ -98,7 +98,7 @@ wide_is_ascii (gfc_char_t c)
   return (gfc_wide_fits_in_byte (c) && ((unsigned char) c & ~0x7f) == 0);
 }
 
-int
+bool
 gfc_wide_is_printable (gfc_char_t c)
 {
   return (gfc_wide_fits_in_byte (c) && ISPRINT ((unsigned char) c));
@@ -116,7 +116,7 @@ gfc_wide_toupper (gfc_char_t c)
   return (wide_is_ascii (c) ? (gfc_char_t) TOUPPER((unsigned char) c) : c);
 }
 
-int
+bool
 gfc_wide_is_digit (gfc_char_t c)
 {
   return (c >= '0' && c <= '9');
@@ -518,7 +518,7 @@ gfc_open_included_file (const char *name, bool include_cwd, bool module)
 
 /* Test to see if we're at the end of the main source file.  */
 
-int
+bool
 gfc_at_end (void)
 {
   return end_flag;
@@ -527,7 +527,7 @@ gfc_at_end (void)
 
 /* Test to see if we're at the end of the current file.  */
 
-int
+bool
 gfc_at_eof (void)
 {
   if (gfc_at_end ())
@@ -545,7 +545,7 @@ gfc_at_eof (void)
 
 /* Test to see if we're at the beginning of a new line.  */
 
-int
+bool
 gfc_at_bol (void)
 {
   if (gfc_at_eof ())
@@ -557,7 +557,7 @@ gfc_at_bol (void)
 
 /* Test to see if we're at the end of a line.  */
 
-int
+bool
 gfc_at_eol (void)
 {
   if (gfc_at_eof ())
@@ -702,7 +702,7 @@ skip_comment_line (void)
 }
 
 
-int
+bool
 gfc_define_undef_line (void)
 {
   char *tmp;
@@ -1803,7 +1803,7 @@ gfc_gobble_whitespace (void)
 	 easily report line and column numbers consistent with other 
 	 parts of gfortran.  */
 
-static int
+static bool
 load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
 {
   int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index 221165d6dac..b4b36e27d75 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
@@ -3216,7 +3216,7 @@ gfc_find_symtree_in_proc (const char* name, gfc_namespace* ns)
    any parent namespaces if requested by a nonzero parent_flag.
    Returns nonzero if the name is ambiguous.  */
 
-int
+bool
 gfc_find_sym_tree (const char *name, gfc_namespace *ns, int parent_flag,
 		   gfc_symtree **result)
 {
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 785cf504816..9f8aa09673a 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -4982,7 +4982,7 @@ done:
 /* Return true if both symbols could refer to the same data object.  Does
    not take account of aliasing due to equivalence statements.  */
 
-static int
+static bool
 symbols_could_alias (gfc_symbol *lsym, gfc_symbol *rsym, bool lsym_pointer,
 		     bool lsym_target, bool rsym_pointer, bool rsym_target)
 {
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 18e2b8b78b4..cd32542eb86 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -483,7 +483,7 @@ gfc_set_decl_assembler_name (tree decl, tree name)
 
 /* Returns true if a variable of specified size should go on the stack.  */
 
-int
+bool
 gfc_can_put_var_on_stack (tree size)
 {
   unsigned HOST_WIDE_INT low;
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index fc5c221a301..d718f28cc86 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -1374,7 +1374,7 @@ gfc_get_element_type (tree type)
 
 /* Returns true if the array sym does not require a descriptor.  */
 
-int
+bool
 gfc_is_nodesc_array (gfc_symbol * sym)
 {
   symbol_attribute *array_attr;
@@ -2451,7 +2451,7 @@ gfc_add_field_to_struct (tree context, tree name, tree type, tree **chain)
    the two derived type symbols are "equal", as described
    in 4.4.2 and resolved by gfc_compare_derived_types.  */
 
-int
+bool
 gfc_copy_dt_decls_ifequal (gfc_symbol *from, gfc_symbol *to,
 			   bool from_gsym)
 {
@@ -2940,7 +2940,7 @@ copy_derived_types:
 }
 
 
-int
+bool
 gfc_return_by_reference (gfc_symbol * sym)
 {
   if (!sym->attr.function)
diff --git a/gcc/fortran/trans-types.h b/gcc/fortran/trans-types.h
index 2dc692325cf..d5746ca4366 100644
--- a/gcc/fortran/trans-types.h
+++ b/gcc/fortran/trans-types.h
@@ -88,7 +88,7 @@ tree gfc_get_character_type_len_for_eltype (tree, tree);
 tree gfc_sym_type (gfc_symbol *, bool is_bind_c_arg = false);
 tree gfc_get_cfi_type (int dimen, bool restricted);
 tree gfc_typenode_for_spec (gfc_typespec *, int c = 0);
-int gfc_copy_dt_decls_ifequal (gfc_symbol *, gfc_symbol *, bool);
+bool gfc_copy_dt_decls_ifequal (gfc_symbol *, gfc_symbol *, bool);
 
 tree gfc_get_function_type (gfc_symbol *, gfc_actual_arglist *args = NULL,
 			    const char *fnspec = NULL);
@@ -109,10 +109,10 @@ tree gfc_add_field_to_struct (tree, tree, tree, tree **);
 void gfc_finish_type (tree);
 
 /* Some functions have an extra parameter for the return value.  */
-int gfc_return_by_reference (gfc_symbol *);
+bool gfc_return_by_reference (gfc_symbol *);
 
 /* Returns true if the array sym does not require a descriptor.  */
-int gfc_is_nodesc_array (gfc_symbol *);
+bool gfc_is_nodesc_array (gfc_symbol *);
 
 /* Return the DTYPE for an array.  */
 tree gfc_get_dtype_rank_type (int, tree);
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 1ad6d944fcf..0c8d004736d 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -670,7 +670,7 @@ void gfc_restore_sym (gfc_symbol *, gfc_saved_var *);
 void gfc_set_decl_assembler_name (tree, tree);
 
 /* Returns true if a variable of specified size should go on the stack.  */
-int gfc_can_put_var_on_stack (tree);
+bool gfc_can_put_var_on_stack (tree);
 
 /* Set GFC_DECL_SCALAR_* on decl from sym if needed.  */
 void gfc_finish_decl_attrs (tree, symbol_attribute *);
-- 
2.30.2


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2] Fortran: Narrow return types [PR78798]
  2023-05-10 16:47           ` [PATCH v2] " Bernhard Reutner-Fischer
@ 2023-05-14 12:27             ` Mikael Morin
  2023-05-14 13:04               ` Thomas Koenig
  2023-05-18 19:52               ` Bernhard Reutner-Fischer
  0 siblings, 2 replies; 20+ messages in thread
From: Mikael Morin @ 2023-05-14 12:27 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer, fortran; +Cc: gcc-patches, Bernhard Reutner-Fischer

Le 10/05/2023 à 18:47, Bernhard Reutner-Fischer via Fortran a écrit :
> From: Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
> 
> gcc/fortran/ChangeLog:
> 
> 	PR fortran/78798
> 	* array.cc (compare_bounds): Use narrower return type.
> 	(gfc_compare_array_spec): Likewise.
> 	(is_constant_element): Likewise.
> 	(gfc_constant_ac): Likewise.
(...)
> ---
> Bootstrapped without new warnings and regression tested on
> x86_64-linux with no regressions, OK for trunk?
> 
(...)
> diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
> index b348bda6e6c..4e3aed84b9d 100644
> --- a/gcc/fortran/check.cc
> +++ b/gcc/fortran/check.cc
> @@ -1156,7 +1156,7 @@ dim_rank_check (gfc_expr *dim, gfc_expr *array, int allow_assumed)
>      dimension bi, returning 0 if they are known not to be identical,
>      and 1 if they are identical, or if this cannot be determined.  */
>   
> -static int
> +static bool
>   identical_dimen_shape (gfc_expr *a, int ai, gfc_expr *b, int bi)
>   {
>     mpz_t a_size, b_size;

To be consistent, please change as well the local variable "ret" used as 
return value from int to bool.

> diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc
> index c3b7c7f7bd9..d7890a97287 100644
> --- a/gcc/fortran/cpp.cc
> +++ b/gcc/fortran/cpp.cc
> @@ -297,7 +297,7 @@ gfc_cpp_init_options (unsigned int decoded_options_count,
>     gfc_cpp_option.deferred_opt_count = 0;
>   }
>   
> -int
> +bool
>   gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED)
>   {
>     int result = 1;

Same here, change the type of variable "result".

(...)
> diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
> index a648d5c7903..b398b29a642 100644
> --- a/gcc/fortran/dependency.cc
> +++ b/gcc/fortran/dependency.cc
(...)

> @@ -1091,7 +1091,7 @@ gfc_check_argument_dependency (gfc_expr *other, sym_intent intent,
>   /* Like gfc_check_argument_dependency, but check all the arguments in ACTUAL.
>      FNSYM is the function being called, or NULL if not known.  */
>   
> -int
> +bool
>   gfc_check_fncall_dependency (gfc_expr *other, sym_intent intent,
>   			     gfc_symbol *fnsym, gfc_actual_arglist *actual,
>   			     gfc_dep_check elemental)

Why not change the associated subfunctions 
(gfc_check_argument_dependency, gfc_check_argument_var_dependency) as well ?

(...)
> @@ -2098,7 +2098,7 @@ ref_same_as_full_array (gfc_ref *full_ref, gfc_ref *ref)
>   	    there is some kind of overlap.
>   	0 : array references are identical or not overlapping.  */
>   
> -int
> +bool
>   gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
>   		  bool identical)
>   {

The function comment states that the function may return 2, which 
doesn't seem to be the case any more.  So please update the comment.

(...)> diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
> index 221165d6dac..b4b36e27d75 100644
> --- a/gcc/fortran/symbol.cc
> +++ b/gcc/fortran/symbol.cc
> @@ -3216,7 +3216,7 @@ gfc_find_symtree_in_proc (const char* name, gfc_namespace* ns)
>      any parent namespaces if requested by a nonzero parent_flag.
>      Returns nonzero if the name is ambiguous.  */
>   
> -int
> +bool
>   gfc_find_sym_tree (const char *name, gfc_namespace *ns, int parent_flag,
>   		   gfc_symtree **result)
>   {

Maybe change nonzero to true in the comment?

(...)

OK with all the above fixed.

Thanks.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2] Fortran: Narrow return types [PR78798]
  2023-05-14 12:27             ` Mikael Morin
@ 2023-05-14 13:04               ` Thomas Koenig
  2023-05-14 15:24                 ` Bernhard Reutner-Fischer
  2023-05-18 19:52               ` Bernhard Reutner-Fischer
  1 sibling, 1 reply; 20+ messages in thread
From: Thomas Koenig @ 2023-05-14 13:04 UTC (permalink / raw)
  To: Mikael Morin, Bernhard Reutner-Fischer, fortran
  Cc: gcc-patches, Bernhard Reutner-Fischer

On 14.05.23 14:27, Mikael Morin wrote:
> 
> (...)
>> @@ -2098,7 +2098,7 @@ ref_same_as_full_array (gfc_ref *full_ref, 
>> gfc_ref *ref)
>>           there is some kind of overlap.
>>       0 : array references are identical or not overlapping.  */
>> -int
>> +bool
>>   gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
>>             bool identical)
>>   {
> 
> The function comment states that the function may return 2, which 
> doesn't seem to be the case any more.

Hm, this makes me a litte suspicious.  Was functionality for reversing
loops lost,  maybe unintentionally?  I assume that, at some time, we did
use the '2' as return value (or did we?)

Best regards

	Thomas

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2] Fortran: Narrow return types [PR78798]
  2023-05-14 13:04               ` Thomas Koenig
@ 2023-05-14 15:24                 ` Bernhard Reutner-Fischer
  2023-05-14 18:06                   ` Mikael Morin
  0 siblings, 1 reply; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2023-05-14 15:24 UTC (permalink / raw)
  To: Thomas Koenig
  Cc: Mikael Morin, fortran, gcc-patches, Bernhard Reutner-Fischer

On Sun, 14 May 2023 15:04:15 +0200
Thomas Koenig <tkoenig@netcologne.de> wrote:

> On 14.05.23 14:27, Mikael Morin wrote:
> > 
> > (...)  
> >> @@ -2098,7 +2098,7 @@ ref_same_as_full_array (gfc_ref *full_ref, 
> >> gfc_ref *ref)
> >>           there is some kind of overlap.
> >>       0 : array references are identical or not overlapping.  */
> >> -int
> >> +bool
> >>   gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
> >>             bool identical)
> >>   {  
> > 
> > The function comment states that the function may return 2, which 
> > doesn't seem to be the case any more.  
> 
> Hm, this makes me a litte suspicious.  Was functionality for reversing
> loops lost,  maybe unintentionally?  I assume that, at some time, we did
> use the '2' as return value (or did we?)

There was 7c428aa29d75ef163c334cf3974f87b3630d8b8b (a revert because it
miscompiled spec2k) which might have associated the comment of the
former static gfc_dependency dep_ref (gfc_ref *lref, gfc_ref *rref,
gfc_reverse *reverse) to the current gfc_dep_resolver.

The commit which introduced the return value 2 documentation was
3d03ead0b8273efde57f6194617b35111a84b05d 
"re PR fortran/24524 (Fortran dependency checking should reverse loops)"

but TBH i don't see how it returned 2 in that revision?
Looks like when writing that patch it deemed useful to return 2 for
this specific situation but in the end it was dropped but the comment
survived.

I will update the comment to document the true / false return values.

And Mikael, do you want me to cleanup 1/0 to true/false assignments for
the boolean variables, or can we do that in a separate patch (or not at
all right now)?

many thanks for the reviews!

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2] Fortran: Narrow return types [PR78798]
  2023-05-14 15:24                 ` Bernhard Reutner-Fischer
@ 2023-05-14 18:06                   ` Mikael Morin
  0 siblings, 0 replies; 20+ messages in thread
From: Mikael Morin @ 2023-05-14 18:06 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer, Thomas Koenig
  Cc: fortran, gcc-patches, Bernhard Reutner-Fischer

Le 14/05/2023 à 17:24, Bernhard Reutner-Fischer a écrit :
> On Sun, 14 May 2023 15:04:15 +0200
> Thomas Koenig <tkoenig@netcologne.de> wrote:
> 
>> On 14.05.23 14:27, Mikael Morin wrote:
>>>
>>> (...)
>>>> @@ -2098,7 +2098,7 @@ ref_same_as_full_array (gfc_ref *full_ref,
>>>> gfc_ref *ref)
>>>>            there is some kind of overlap.
>>>>        0 : array references are identical or not overlapping.  */
>>>> -int
>>>> +bool
>>>>    gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
>>>>              bool identical)
>>>>    {
>>>
>>> The function comment states that the function may return 2, which
>>> doesn't seem to be the case any more.
>>
>> Hm, this makes me a litte suspicious.  Was functionality for reversing
>> loops lost,  maybe unintentionally?  I assume that, at some time, we did
>> use the '2' as return value (or did we?)
> 
> There was 7c428aa29d75ef163c334cf3974f87b3630d8b8b (a revert because it
> miscompiled spec2k) which might have associated the comment of the
> former static gfc_dependency dep_ref (gfc_ref *lref, gfc_ref *rref,
> gfc_reverse *reverse) to the current gfc_dep_resolver.
> 
> The commit which introduced the return value 2 documentation was
> 3d03ead0b8273efde57f6194617b35111a84b05d
> "re PR fortran/24524 (Fortran dependency checking should reverse loops)"
> 
> but TBH i don't see how it returned 2 in that revision?
> Looks like when writing that patch it deemed useful to return 2 for
> this specific situation but in the end it was dropped but the comment
> survived.
>
Yes, I came to the same conclusion that we never returned 2 here.

The information that reversal is needed is already provided on a per 
dimension basis by the gfc_reverse pointer passed as argument, so 
providing the information in the return value would be redundant anyway.


> I will update the comment to document the true / false return values.
> 
> And Mikael, do you want me to cleanup 1/0 to true/false assignments for
> the boolean variables, or can we do that in a separate patch (or not at
> all right now)?
> 
I don't mind too much either way.
As long as the variables are not assigned integer values outside of the 
[0,1] range, and we consistently use true/false or 0/1, not a mix of 
them, it's fine with me.




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2] Fortran: Narrow return types [PR78798]
  2023-05-14 12:27             ` Mikael Morin
  2023-05-14 13:04               ` Thomas Koenig
@ 2023-05-18 19:52               ` Bernhard Reutner-Fischer
  1 sibling, 0 replies; 20+ messages in thread
From: Bernhard Reutner-Fischer @ 2023-05-18 19:52 UTC (permalink / raw)
  To: Mikael Morin; +Cc: fortran, gcc-patches, Bernhard Reutner-Fischer

On Sun, 14 May 2023 14:27:42 +0200
Mikael Morin <morin-mikael@orange.fr> wrote:

> Le 10/05/2023 à 18:47, Bernhard Reutner-Fischer via Fortran a écrit :
> > From: Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
> > 
> > gcc/fortran/ChangeLog:
> > 
> > 	PR fortran/78798
> > 	* array.cc (compare_bounds): Use narrower return type.
> > 	(gfc_compare_array_spec): Likewise.
> > 	(is_constant_element): Likewise.
> > 	(gfc_constant_ac): Likewise.  
> (...)
> > ---
> > Bootstrapped without new warnings and regression tested on
> > x86_64-linux with no regressions, OK for trunk?
> >   
> (...)
> > diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
> > index b348bda6e6c..4e3aed84b9d 100644
> > --- a/gcc/fortran/check.cc
> > +++ b/gcc/fortran/check.cc
> > @@ -1156,7 +1156,7 @@ dim_rank_check (gfc_expr *dim, gfc_expr *array, int allow_assumed)
> >      dimension bi, returning 0 if they are known not to be identical,
> >      and 1 if they are identical, or if this cannot be determined.  */
> >   
> > -static int
> > +static bool
> >   identical_dimen_shape (gfc_expr *a, int ai, gfc_expr *b, int bi)
> >   {
> >     mpz_t a_size, b_size;  
> 
> To be consistent, please change as well the local variable "ret" used as 
> return value from int to bool.
> 
> > diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc
> > index c3b7c7f7bd9..d7890a97287 100644
> > --- a/gcc/fortran/cpp.cc
> > +++ b/gcc/fortran/cpp.cc
> > @@ -297,7 +297,7 @@ gfc_cpp_init_options (unsigned int decoded_options_count,
> >     gfc_cpp_option.deferred_opt_count = 0;
> >   }
> >   
> > -int
> > +bool
> >   gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED)
> >   {
> >     int result = 1;  
> 
> Same here, change the type of variable "result".
> 
> (...)
> > diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
> > index a648d5c7903..b398b29a642 100644
> > --- a/gcc/fortran/dependency.cc
> > +++ b/gcc/fortran/dependency.cc  
> (...)
> 
> > @@ -1091,7 +1091,7 @@ gfc_check_argument_dependency (gfc_expr *other, sym_intent intent,
> >   /* Like gfc_check_argument_dependency, but check all the arguments in ACTUAL.
> >      FNSYM is the function being called, or NULL if not known.  */
> >   
> > -int
> > +bool
> >   gfc_check_fncall_dependency (gfc_expr *other, sym_intent intent,
> >   			     gfc_symbol *fnsym, gfc_actual_arglist *actual,
> >   			     gfc_dep_check elemental)  
> 
> Why not change the associated subfunctions 
> (gfc_check_argument_dependency, gfc_check_argument_var_dependency) as well ?

I have left these subfunctions alone for now to get the other hunks out
of the way. I have adjusted the patch according to your other comments
and pushed it as r14-973-gc072df1ab14450.

Thanks!

> 
> (...)
> > @@ -2098,7 +2098,7 @@ ref_same_as_full_array (gfc_ref *full_ref, gfc_ref *ref)
> >   	    there is some kind of overlap.
> >   	0 : array references are identical or not overlapping.  */
> >   
> > -int
> > +bool
> >   gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
> >   		  bool identical)
> >   {  
> 
> The function comment states that the function may return 2, which 
> doesn't seem to be the case any more.  So please update the comment.
> 
> (...)> diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
> > index 221165d6dac..b4b36e27d75 100644
> > --- a/gcc/fortran/symbol.cc
> > +++ b/gcc/fortran/symbol.cc
> > @@ -3216,7 +3216,7 @@ gfc_find_symtree_in_proc (const char* name, gfc_namespace* ns)
> >      any parent namespaces if requested by a nonzero parent_flag.
> >      Returns nonzero if the name is ambiguous.  */
> >   
> > -int
> > +bool
> >   gfc_find_sym_tree (const char *name, gfc_namespace *ns, int parent_flag,
> >   		   gfc_symtree **result)
> >   {  
> 
> Maybe change nonzero to true in the comment?
> 
> (...)
> 
> OK with all the above fixed.
> 
> Thanks.
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2023-05-18 19:52 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-12 23:45 [PATCH 0/5] function result decl location; type demotion Bernhard Reutner-Fischer
2022-11-12 23:45 ` [PATCH 1/5] c: Set the locus of the function result decl Bernhard Reutner-Fischer
2022-11-14 21:25   ` Joseph Myers
2022-11-12 23:45 ` [PATCH 2/5] c++: " Bernhard Reutner-Fischer
2022-11-15 23:52   ` Jason Merrill
2022-11-12 23:45 ` [PATCH 3/5] Fortran: Narrow return types [PR78798] Bernhard Reutner-Fischer
2022-11-13 10:13   ` Janne Blomqvist
2022-11-13 10:39     ` Bernhard Reutner-Fischer
2022-11-13 20:29       ` Harald Anlauf
2022-11-13 21:50         ` Bernhard Reutner-Fischer
2023-05-10 16:47           ` [PATCH v2] " Bernhard Reutner-Fischer
2023-05-14 12:27             ` Mikael Morin
2023-05-14 13:04               ` Thomas Koenig
2023-05-14 15:24                 ` Bernhard Reutner-Fischer
2023-05-14 18:06                   ` Mikael Morin
2023-05-18 19:52               ` Bernhard Reutner-Fischer
2022-11-12 23:45 ` [PATCH 4/5] value-range: Add as_string diagnostics helper Bernhard Reutner-Fischer
2022-11-12 23:55   ` Andrew Pinski
2022-11-17  3:30     ` Jeff Law
2022-11-12 23:45 ` [PATCH 5/5] gimple: Add pass to note possible type demotions; IPA pro/demotion; DO NOT MERGE Bernhard Reutner-Fischer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).