Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-12-02 Thread Bernhard Reutner-Fischer via Gcc-patches
On 2 December 2022 20:30:56 CET, Jason Merrill  wrote:

>Here's what I'm applying:

I meant to play with it during the weekend,
looks good, many thanks for taking care of this!
cheers,


Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-12-02 Thread Jason Merrill via Gcc-patches

On 11/23/22 10:28, Jason Merrill wrote:

On 11/22/22 15:25, Jason Merrill wrote:

On 11/20/22 12:06, Bernhard Reutner-Fischer wrote:

Hi Jason!

The "meh" of result-decl-plugin-test-2.C should likely be omitted,
grokdeclarator would need some changes to add richloc hints and we 
would not

be able to make a reliable guess what to remove precisely.
C.f. /* Check all other uses of type modifiers.  */
Furthermore it is unrelated to DECL_RESULT so not of direct interest
here. The other tests in test-2.C, f() and huh() should work though.

I don't know if it's acceptable to change ipa-pure-const to make the
missing noreturn warning more precise and emit a fixit-hint. At least it
would be a real test for the DECL_RESULT and would spare us the plugin.


The main problem I see with that change is that the syntax of the 
fixit might be wrong for non-C-family front-ends.


Here's a version of the patch that fixes template/method handling, and 
adjusts -Waggregate-return as well:


Actually, that broke some of the spaceship tests, fixed by this version:


Here's what I'm applying:
From d19aa6af6634b1e97f38431ad091f3b3f12baf2f Mon Sep 17 00:00:00 2001
From: Bernhard Reutner-Fischer 
Date: Sun, 20 Nov 2022 18:06:04 +0100
Subject: [PATCH] c++: Set the locus of the function result decl
To: gcc-patches@gcc.gnu.org

gcc/cp/ChangeLog:

	* decl.cc (grokdeclarator): Build RESULT_DECL.
	(start_preparsed_function): Copy location from template.
	* semantics.cc (apply_deduced_return_type): Handle
	arg != current_function_decl.
	* method.cc (implicitly_declare_fn): Use it.

gcc/ChangeLog:

	* function.cc (init_function_start): Use DECL_RESULT location
	for -Waggregate-return warning.

gcc/testsuite/ChangeLog:

	* g++.dg/diagnostic/return-type-loc1.C: New test.

Co-authored-by: Jason Merrill 
---
 gcc/cp/decl.cc| 25 +--
 gcc/cp/method.cc  |  2 +-
 gcc/cp/semantics.cc   | 15 ++-
 gcc/function.cc   |  3 ++-
 .../g++.dg/diagnostic/return-type-loc1.C  | 20 +++
 5 files changed, 53 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/return-type-loc1.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 238e72f90da..508156309d9 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -14772,6 +14772,19 @@ grokdeclarator (const cp_declarator *declarator,
 	else if (constinit_p)
 	  DECL_DECLARED_CONSTINIT_P (decl) = true;
   }
+else if (TREE_CODE (decl) == FUNCTION_DECL)
+  {
+	/* If we saw a return type, record its location.  */
+	location_t loc = declspecs->locations[ds_type_spec];
+	if (loc != UNKNOWN_LOCATION)
+	  {
+	tree restype = TREE_TYPE (TREE_TYPE (decl));
+	tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
+	DECL_ARTIFICIAL (resdecl) = 1;
+	DECL_IGNORED_P (resdecl) = 1;
+	DECL_RESULT (decl) = resdecl;
+	  }
+  }
 
 /* Record constancy and volatility on the DECL itself .  There's
no need to do this when processing a template; we'll do this
@@ -17326,9 +17339,17 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   if (DECL_RESULT (decl1) == NULL_TREE)
 {
-  tree resdecl;
+  /* In a template instantiation, copy the return type location.  When
+	 parsing, the location will be set in grokdeclarator.  */
+  location_t loc = input_location;
+  if (DECL_TEMPLATE_INSTANTIATION (decl1))
+	{
+	  tree tmpl = template_for_substitution (decl1);
+	  if (tree res = DECL_RESULT (DECL_TEMPLATE_RESULT (tmpl)))
+	loc = DECL_SOURCE_LOCATION (res);
+	}
 
-  resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
+  tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
   DECL_ARTIFICIAL (resdecl) = 1;
   DECL_IGNORED_P (resdecl) = 1;
   DECL_RESULT (decl1) = resdecl;
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 1e962b6e3b1..7b4d5a59823 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -3079,7 +3079,7 @@ implicitly_declare_fn (special_function_kind kind, tree type,
 {
   fn = copy_operator_fn (pattern_fn, EQ_EXPR);
   DECL_ARTIFICIAL (fn) = 1;
-  TREE_TYPE (fn) = change_return_type (boolean_type_node, TREE_TYPE (fn));
+  apply_deduced_return_type (fn, boolean_type_node);
   return fn;
 }
 
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 9401b35a789..ab52e56d6c1 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12325,24 +12325,23 @@ apply_deduced_return_type (tree fco, tree return_type)
   /* We already have a DECL_RESULT from start_preparsed_function.
  Now we need to redo the work it and allocate_struct_function
  did to reflect the new type.  */
-  gcc_assert (current_function_decl == fco);
-  result = build_decl (input_location, RESULT_DECL, NULL_TREE,
+  result = build_decl (DECL_SOURCE_LOCATION (result), RESULT_DECL, NULL_TREE,
 		   TYPE_MAIN_VARIANT 

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-23 Thread Jason Merrill via Gcc-patches

On 11/22/22 15:25, Jason Merrill wrote:

On 11/20/22 12:06, Bernhard Reutner-Fischer wrote:

Hi Jason!

The "meh" of result-decl-plugin-test-2.C should likely be omitted,
grokdeclarator would need some changes to add richloc hints and we 
would not

be able to make a reliable guess what to remove precisely.
C.f. /* Check all other uses of type modifiers.  */
Furthermore it is unrelated to DECL_RESULT so not of direct interest
here. The other tests in test-2.C, f() and huh() should work though.

I don't know if it's acceptable to change ipa-pure-const to make the
missing noreturn warning more precise and emit a fixit-hint. At least it
would be a real test for the DECL_RESULT and would spare us the plugin.


The main problem I see with that change is that the syntax of the fixit 
might be wrong for non-C-family front-ends.


Here's a version of the patch that fixes template/method handling, and 
adjusts -Waggregate-return as well:


Actually, that broke some of the spaceship tests, fixed by this version:
From 3c8106c95ec07d17ff5ade173126067c540ab7cc Mon Sep 17 00:00:00 2001
From: Bernhard Reutner-Fischer 
Date: Sun, 20 Nov 2022 18:06:04 +0100
Subject: [PATCH] c++: Set the locus of the function result decl
To: gcc-patches@gcc.gnu.org

gcc/cp/ChangeLog:

	* decl.cc (grokdeclarator): Build RESULT_DECL.
	(start_preparsed_function): Copy location from template.
	* semantics.cc (apply_deduced_return_type): Handle
	arg != current_function_decl.
	* method.cc (implicitly_declare_fn): Use it.

gcc/ChangeLog:

	* function.cc (init_function_start): Use DECL_RESULT location
	for -Waggregate-return warning.
	* ipa-pure-const.cc (suggest_attribute): Add fixit-hint for the
	noreturn attribute.

gcc/testsuite/ChangeLog:

	* c-c++-common/pr68833-1.c: Adjust noreturn warning line number.
	* gcc.dg/noreturn-1.c: Likewise.
	* g++.dg/diagnostic/return-type-loc1.C: New test.
	* g++.dg/other/resultdecl-1.C: New test.

Co-authored-by: Jason Merrill 
---
 gcc/cp/decl.cc| 26 +--
 gcc/cp/method.cc  |  2 +-
 gcc/cp/semantics.cc   | 15 -
 gcc/function.cc   |  3 +-
 gcc/ipa-pure-const.cc | 14 +++-
 gcc/testsuite/c-c++-common/pr68833-1.c|  2 +-
 .../g++.dg/diagnostic/return-type-loc1.C  | 20 
 gcc/testsuite/g++.dg/other/resultdecl-1.C | 32 +++
 gcc/testsuite/gcc.dg/noreturn-1.c |  2 +-
 9 files changed, 101 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/return-type-loc1.C
 create mode 100644 gcc/testsuite/g++.dg/other/resultdecl-1.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 544efdc9914..2c5cd930e0a 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -14774,6 +14774,18 @@ grokdeclarator (const cp_declarator *declarator,
 	else if (constinit_p)
 	  DECL_DECLARED_CONSTINIT_P (decl) = true;
   }
+else if (TREE_CODE (decl) == FUNCTION_DECL)
+  {
+	location_t loc = smallest_type_location (declspecs);
+	if (loc != UNKNOWN_LOCATION)
+	  {
+	tree restype = TREE_TYPE (TREE_TYPE (decl));
+	tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
+	DECL_ARTIFICIAL (resdecl) = 1;
+	DECL_IGNORED_P (resdecl) = 1;
+	DECL_RESULT (decl) = resdecl;
+	  }
+  }
 
 /* Record constancy and volatility on the DECL itself .  There's
no need to do this when processing a template; we'll do this
@@ -17328,9 +17340,19 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   if (DECL_RESULT (decl1) == NULL_TREE)
 {
-  tree resdecl;
+  /* In a template instantiation, copy the return type location.  When
+	 parsing, the location will be set in grokdeclarator.  */
+  location_t loc = input_location;
+  if (DECL_TEMPLATE_INSTANTIATION (decl1)
+	  && !DECL_CXX_CONSTRUCTOR_P (decl1)
+	  && !DECL_CXX_DESTRUCTOR_P (decl1))
+	{
+	  tree tmpl = template_for_substitution (decl1);
+	  tree res = DECL_RESULT (DECL_TEMPLATE_RESULT (tmpl));
+	  loc = DECL_SOURCE_LOCATION (res);
+	}
 
-  resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
+  tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
   DECL_ARTIFICIAL (resdecl) = 1;
   DECL_IGNORED_P (resdecl) = 1;
   DECL_RESULT (decl1) = resdecl;
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 1e962b6e3b1..7b4d5a59823 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -3079,7 +3079,7 @@ implicitly_declare_fn (special_function_kind kind, tree type,
 {
   fn = copy_operator_fn (pattern_fn, EQ_EXPR);
   DECL_ARTIFICIAL (fn) = 1;
-  TREE_TYPE (fn) = change_return_type (boolean_type_node, TREE_TYPE (fn));
+  apply_deduced_return_type (fn, boolean_type_node);
   return fn;
 }
 
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 9401b35a789..ab52e56d6c1 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ 

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-22 Thread Jason Merrill via Gcc-patches

On 11/20/22 12:06, Bernhard Reutner-Fischer wrote:

Hi Jason!

The "meh" of result-decl-plugin-test-2.C should likely be omitted,
grokdeclarator would need some changes to add richloc hints and we would not
be able to make a reliable guess what to remove precisely.
C.f. /* Check all other uses of type modifiers.  */
Furthermore it is unrelated to DECL_RESULT so not of direct interest
here. The other tests in test-2.C, f() and huh() should work though.

I don't know if it's acceptable to change ipa-pure-const to make the
missing noreturn warning more precise and emit a fixit-hint. At least it
would be a real test for the DECL_RESULT and would spare us the plugin.


The main problem I see with that change is that the syntax of the fixit 
might be wrong for non-C-family front-ends.


Here's a version of the patch that fixes template/method handling, and 
adjusts -Waggregate-return as well:
From 5075d2ac12f655f8f83f6f3be27e2c1141e1ce99 Mon Sep 17 00:00:00 2001
From: Bernhard Reutner-Fischer 
Date: Sun, 20 Nov 2022 18:06:04 +0100
Subject: [PATCH] c++: Set the locus of the function result decl
To: gcc-patches@gcc.gnu.org

gcc/cp/ChangeLog:

	* decl.cc (grokdeclarator): Build RESULT_DECL.
	(start_preparsed_function): Copy location from template.

gcc/ChangeLog:

	* function.cc (init_function_start): Use DECL_RESULT location
	for -Waggregate-return warning.
	* ipa-pure-const.cc (suggest_attribute): Add fixit-hint for the
	noreturn attribute.

gcc/testsuite/ChangeLog:

	* c-c++-common/pr68833-1.c: Adjust noreturn warning line number.
	* gcc.dg/noreturn-1.c: Likewise.
	* g++.dg/diagnostic/return-type-loc1.C: New test.
	* g++.dg/other/resultdecl-1.C: New test.

Co-authored-by: Jason Merrill 
---
 gcc/cp/decl.cc| 26 +--
 gcc/function.cc   |  3 +-
 gcc/ipa-pure-const.cc | 14 +++-
 gcc/testsuite/c-c++-common/pr68833-1.c|  2 +-
 .../g++.dg/diagnostic/return-type-loc1.C  | 20 
 gcc/testsuite/g++.dg/other/resultdecl-1.C | 32 +++
 gcc/testsuite/gcc.dg/noreturn-1.c |  2 +-
 7 files changed, 93 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/return-type-loc1.C
 create mode 100644 gcc/testsuite/g++.dg/other/resultdecl-1.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 544efdc9914..2c5cd930e0a 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -14774,6 +14774,18 @@ grokdeclarator (const cp_declarator *declarator,
 	else if (constinit_p)
 	  DECL_DECLARED_CONSTINIT_P (decl) = true;
   }
+else if (TREE_CODE (decl) == FUNCTION_DECL)
+  {
+	location_t loc = smallest_type_location (declspecs);
+	if (loc != UNKNOWN_LOCATION)
+	  {
+	tree restype = TREE_TYPE (TREE_TYPE (decl));
+	tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
+	DECL_ARTIFICIAL (resdecl) = 1;
+	DECL_IGNORED_P (resdecl) = 1;
+	DECL_RESULT (decl) = resdecl;
+	  }
+  }
 
 /* Record constancy and volatility on the DECL itself .  There's
no need to do this when processing a template; we'll do this
@@ -17328,9 +17340,19 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   if (DECL_RESULT (decl1) == NULL_TREE)
 {
-  tree resdecl;
+  /* In a template instantiation, copy the return type location.  When
+	 parsing, the location will be set in grokdeclarator.  */
+  location_t loc = input_location;
+  if (DECL_TEMPLATE_INSTANTIATION (decl1)
+	  && !DECL_CXX_CONSTRUCTOR_P (decl1)
+	  && !DECL_CXX_DESTRUCTOR_P (decl1))
+	{
+	  tree tmpl = template_for_substitution (decl1);
+	  tree res = DECL_RESULT (DECL_TEMPLATE_RESULT (tmpl));
+	  loc = DECL_SOURCE_LOCATION (res);
+	}
 
-  resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
+  tree resdecl = build_decl (loc, RESULT_DECL, 0, restype);
   DECL_ARTIFICIAL (resdecl) = 1;
   DECL_IGNORED_P (resdecl) = 1;
   DECL_RESULT (decl1) = resdecl;
diff --git a/gcc/function.cc b/gcc/function.cc
index 9c8773bbc59..dc333c27e92 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -4997,7 +4997,8 @@ init_function_start (tree subr)
   /* Warn if this value is an aggregate type,
  regardless of which calling convention we are using for it.  */
   if (AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr
-warning (OPT_Waggregate_return, "function returns an aggregate");
+warning_at (DECL_SOURCE_LOCATION (DECL_RESULT (subr)),
+		OPT_Waggregate_return, "function returns an aggregate");
 }
 
 /* Expand code to verify the stack_protect_guard.  This is invoked at
diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc
index 572a6da274f..8f6e8f63d91 100644
--- a/gcc/ipa-pure-const.cc
+++ b/gcc/ipa-pure-const.cc
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-fnsummary.h"
 #include "symtab-thunks.h"
 #include "dbgcnt.h"
+#include "gcc-rich-location.h"
 
 /* Lattice values for const and pure 

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-20 Thread Bernhard Reutner-Fischer via Gcc-patches
Hi Jason!

The "meh" of result-decl-plugin-test-2.C should likely be omitted,
grokdeclarator would need some changes to add richloc hints and we would not
be able to make a reliable guess what to remove precisely.
C.f. /* Check all other uses of type modifiers.  */
Furthermore it is unrelated to DECL_RESULT so not of direct interest
here. The other tests in test-2.C, f() and huh() should work though.

I don't know if it's acceptable to change ipa-pure-const to make the
missing noreturn warning more precise and emit a fixit-hint. At least it
would be a real test for the DECL_RESULT and would spare us the plugin.

HTH,

gcc/cp/ChangeLog:

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

gcc/ChangeLog:

* ipa-pure-const.cc (suggest_attribute): Add fixit-hint for the
noreturn attribute.

gcc/testsuite/ChangeLog:

* c-c++-common/pr68833-1.c: Adjust noreturn warning line number.
* gcc.dg/noreturn-1.c: Likewise.
* g++.dg/plugin/plugin.exp: Add new plugin test.
* g++.dg/other/resultdecl-1.C: New test.
* g++.dg/plugin/result-decl-plugin-test-1.C: New test.
* g++.dg/plugin/result-decl-plugin-test-2.C: New test.
* g++.dg/plugin/result_decl_plugin.C: New test.
---
 gcc/cp/decl.cc| 26 +++-
 gcc/ipa-pure-const.cc | 14 -
 gcc/testsuite/c-c++-common/pr68833-1.c|  2 +-
 gcc/testsuite/g++.dg/other/resultdecl-1.C | 32 ++
 gcc/testsuite/g++.dg/plugin/plugin.exp|  3 +
 .../g++.dg/plugin/result-decl-plugin-test-1.C | 31 ++
 .../g++.dg/plugin/result-decl-plugin-test-2.C | 59 +++
 .../g++.dg/plugin/result_decl_plugin.C| 53 +
 gcc/testsuite/gcc.dg/noreturn-1.c |  2 +-
 9 files changed, 218 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/other/resultdecl-1.C
 create mode 100644 gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-1.C
 create mode 100644 gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-2.C
 create mode 100644 gcc/testsuite/g++.dg/plugin/result_decl_plugin.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index d28889ed865..0c053b6d19f 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17235,6 +17235,17 @@ start_preparsed_function (tree decl1, tree attrs, int 
flags)
   cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
 }
 
+  /* Set the result decl source location to the location of the typespec.  */
+  if (DECL_RESULT (decl1)
+  && DECL_TEMPLATE_INSTANTIATION (decl1)
+  && DECL_TEMPLATE_INFO (decl1)
+  && DECL_TI_TEMPLATE (decl1)
+  && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1))
+  && DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1
+  DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
+   = DECL_SOURCE_LOCATION (
+   DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1;
+
   /* Record the decl so that the function name is defined.
  If we already have a decl for this name, and it is a FUNCTION_DECL,
  use the old decl.  */
@@ -17532,7 +17543,20 @@ 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);
+  bool ret = start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
+
+  /* decl1 might be ggc_freed here.  */
+  decl1 = current_function_decl;
+
+  tree result;
+  /* Set the result decl source location to the location of the typespec.  */
+  if (ret
+  && 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;
 }
 
 /* Returns true iff an EH_SPEC_BLOCK should be created in the body of
diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc
index 572a6da274f..1c80034f38d 100644
--- a/gcc/ipa-pure-const.cc
+++ b/gcc/ipa-pure-const.cc
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-fnsummary.h"
 #include "symtab-thunks.h"
 #include "dbgcnt.h"
+#include "gcc-rich-location.h"
 
 /* Lattice values for const and pure functions.  Everything starts out
being const, then may drop to pure and then neither depending on
@@ -212,7 +213,18 @@ suggest_attribute (int option, tree decl, bool 
known_finite,
   if (warned_about->contains (decl))
 return warned_about;
   warned_about->add (decl);
-  warning_at (DECL_SOURCE_LOCATION (decl),
+
+  gcc_rich_location richloc (option == OPT_Wsuggest_attribute_noreturn
+? DECL_SOURCE_LOCATION (DECL_RESULT (decl))
+: 

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-19 Thread Bernhard Reutner-Fischer via Gcc-patches
Hi Jason!

Possible test.

An existing test might be to equip the existing warning for
bool unsigned double meh(void) {return 0;}
with a fix-it hint instead of the brief
 error: two or more data types in declaration of ‘meh’.
Likewise for
bool unsigned meh(void) {return 0;}
 error: ‘unsigned’ specified with ‘bool’

so we wouldn't need a plugin, and it might even be useful? ;)

cheers,

* g++.dg/plugin/plugin.exp: Add new test.
* g++.dg/plugin/result-decl-plugin-test-1.C: New test.
* g++.dg/plugin/result-decl-plugin-test-2.C: New test.
* g++.dg/plugin/result_decl_plugin.C: New test.
---
 gcc/testsuite/g++.dg/plugin/plugin.exp|  3 +
 .../g++.dg/plugin/result-decl-plugin-test-1.C | 28 +
 .../g++.dg/plugin/result-decl-plugin-test-2.C | 61 +++
 .../g++.dg/plugin/result_decl_plugin.C| 57 +
 4 files changed, 149 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-1.C
 create mode 100644 gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-2.C
 create mode 100644 gcc/testsuite/g++.dg/plugin/result_decl_plugin.C

diff --git a/gcc/testsuite/g++.dg/plugin/plugin.exp 
b/gcc/testsuite/g++.dg/plugin/plugin.exp
index b5fb42fa77a..f2b526b4704 100644
--- a/gcc/testsuite/g++.dg/plugin/plugin.exp
+++ b/gcc/testsuite/g++.dg/plugin/plugin.exp
@@ -80,6 +80,9 @@ set plugin_test_list [list \
  show-template-tree-color-labels.C \
  show-template-tree-color-no-elide-type.C } \
 { comment_plugin.c comments-1.C } \
+{ result_decl_plugin.C \
+  result-decl-plugin-test-1.C \
+  result-decl-plugin-test-2.C } \
 ]
 
 foreach plugin_test $plugin_test_list {
diff --git a/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-1.C 
b/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-1.C
new file mode 100644
index 000..bd323181d70
--- /dev/null
+++ b/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-1.C
@@ -0,0 +1,28 @@
+/* Verify that class member functions result decl have the correct location.  
*/
+// { dg-options "-fdiagnostics-generate-patch" }
+namespace std { template < typename, typename > struct pair; }
+template < typename > struct __mini_vector
+{
+  int _M_finish;
+  const
+  unsigned long
+  __attribute__((deprecated))
+  _M_space_left()
+  { return _M_finish != 0; }
+};
+ template class __mini_vector< std::pair< long, long > >;
+ template class __mini_vector< int >;
+#if 0
+{ dg-begin-multiline-output "" }
+@@ -5,7 +5,7 @@ template < typename > struct __mini_vect
+ {
+   int _M_finish;
+   const
+-  unsigned long
++  bool
+   __attribute__((deprecated))
+   _M_space_left()
+   { return _M_finish != 0; }
+
+{ dg-end-multiline-output "" }
+#endif
diff --git a/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-2.C 
b/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-2.C
new file mode 100644
index 000..385a7ef482f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-2.C
@@ -0,0 +1,61 @@
+/* Verify that template functions result decl have the correct location.  */
+// { dg-options "-fdiagnostics-generate-patch" }
+template 
+int
+f()
+{
+  return 42;
+}
+int main()
+{
+   f();
+}
+unsigned long long huh(void)
+{
+  return 1ULL;
+}
+#if 0
+{ dg-begin-multiline-output "" }
+g++.dg/plugin/result-decl-plugin-test-2.C:4:1: warning: Function ‘f’ result 
location
+4 | int
+  | ^~~
+  | bool
+g++.dg/plugin/result-decl-plugin-test-2.C:9:1: warning: Function ‘main’ result 
location
+9 | int main()
+  | ^~~
+  | bool
+g++.dg/plugin/result-decl-plugin-test-2.C:13:28: warning: Function ‘huh’ 
result location
+   13 | unsigned long long huh(void)
+  |^
+  |bool
+g++.dg/plugin/result-decl-plugin-test-2.C: In instantiation of ‘int f() [with 
T = int]’:
+g++.dg/plugin/result-decl-plugin-test-2.C:11:10:   required from here
+g++.dg/plugin/result-decl-plugin-test-2.C:4:1: warning: Function ‘f’ result 
location
+4 | int
+  | ^~~
+  | bool
+--- g++.dg/plugin/result-decl-plugin-test-2.C
 g++.dg/plugin/result-decl-plugin-test-2.C
+@@ -1,16 +1,16 @@
+ /* Verify that template functions result decl have the correct location.  */
+ // { dg-options "-fdiagnostics-generate-patch" }
+ template 
+-int
++bool
+ f()
+ {
+   return 42;
+ }
+-int main()
++bool main()
+ {
+f();
+ }
+-unsigned long long huh(void)
++unsigned long long huh(voidbool
+ {
+   return 1ULL;
+ }
+{ dg-end-multiline-output "" }
+#endif
+// Note: f() should not +bbool with an off-by-one for the start 'b' !
diff --git a/gcc/testsuite/g++.dg/plugin/result_decl_plugin.C 
b/gcc/testsuite/g++.dg/plugin/result_decl_plugin.C
new file mode 100644
index 000..40f54a6acfe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/plugin/result_decl_plugin.C
@@ -0,0 +1,57 @@
+/* A plugin example that points at the location of function decl result decl */
+/* This file is part of GCC */
+/* { dg-options "-O" } */

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-18 Thread Bernhard Reutner-Fischer via Gcc-patches
On Fri, 18 Nov 2022 11:06:29 -0500
Jason Merrill  wrote:

> Ah, so the problem is deferred parsing of methods, rather than 
> templates.  Building the DECL_RESULT sooner does seem like the right 
> approach to handling that, whether that's in grokfndecl or grokmethod.

> >> I'd like to get the template case right while we're looking at it.  I
> >> guess I can add that myself if you're done trying.

Please do, i'd be glad if you could take care of these locations.
It icks me that they are wrong, and be it just for the sake of QOI :)

> >>> Is the hunk for normal functions OK for trunk?  
> >>
> >> You also need a testcase for the desired behavior, with e.g.
> >> { dg-error "23:" }  
> > 
> > I'd have to think about how to test that with trunk, yes.
> > There are no existing warnings that want to point to the return type,
> > are there?  
> 
> Good point.  Do any of your later patches add such a warning?

I didn't mean to have that -Wtype-demotion applied in it's current
form, or at all, so no. I was curious if anybody liked the idea of
pointing out such code though. I've had no feedback but everybody is or
was busy with end of stage3 and real work, so that's expected. The only
real purpose i had for it was to find places in the Fortran FE that
could use narrower types, bools for the most part.
IMHO it would be a nice thing to have, but then, embedded software
usually is cautious to use sensible types in the first place and the
rest doesn't really care anyway, supposedly.

Maybe it would have made more sense to just do an IPA pass that does the
demotion silently where it's feasable.

As to the test, i don't think these locations in the c++ FE are changed
all that often, so chances are rather low that they would be broken
once in.
So, short of trying to use the result decl locus for any existing
-Wreturn-type, -Waggregate-return, -Wno-return-local-addr,
-Wsuggest-attribute=[pure|const|noreturn|format|malloc] or another
existing warning that would be concerned, we could, as said, have a
plugin with fix-it hints and ideally -fdiagnostics-generate-patch to
test these bits. Patch generation has the advantage that it will ICE
more often than not if asked to generate patches for locations that
have a negative relative start (think: memcpy(...,..., -7)), which you
can get easily if the locations are off IMHO.

> > Maybe a g++.dg/plugin/result_decl_plugin.c then.


Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-18 Thread Jason Merrill via Gcc-patches

On 11/18/22 05:49, Bernhard Reutner-Fischer wrote:

On Thu, 17 Nov 2022 18:52:36 -0500
Jason Merrill  wrote:


On 11/17/22 14:02, Bernhard Reutner-Fischer wrote:

On Thu, 17 Nov 2022 09:53:32 -0500
Jason Merrill  wrote:



Instead, you want to copy the location for instantiations, i.e. check
DECL_TEMPLATE_INSTANTIATION instead of !DECL_USE_TEMPLATE.


No, that makes no difference.


Hmm, when I stop there when processing the instantiation the template's
DECL_RESULT has the right location information, e.g. for

template  int f() { return 42; }

int main()
{
f();
}

#1  0x00f950e8 in instantiate_body (pattern=, args=, d=, nested_p=false) at /home/jason/gt/gcc/cp/pt.cc:26470
#0  start_preparsed_function (decl1=,
attrs=, flags=1) at /home/jason/gt/gcc/cp/decl.cc:17252
(gdb) p expand_location (input_location)
$13 = {file = 0x4962370 "wa.C", line = 1, column = 24, data = 0x0, sysp
= false}
(gdb) p expand_location (DECL_SOURCE_LOCATION (DECL_RESULT
(DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1)
$14 = {file = 0x4962370 "wa.C", line = 1, column = 20, data = 0x0, sysp
= false}


Yes, that works. Sorry if i was not clear: The thing in the cover
letter in this series does not work, the mini_vector reduced testcase
from the libstdc++-v3/include/ext/bitmap_allocator.h.
class template member function return type location, would that be it?

AFAIR the problem was that that these member functions get their result
decl late. When they get them, there are no
declspecs->locations[ds_type_spec] around anywhere to tuck that on the
resdecl. While the result decl is clear, there is no obvious way where
to store the ds_type_spec (somewhere in the template, as you told me).

Back then I tried moving the resdecl building from
start_preparsed_function to grokfndecl but that did not work out easily
IIRC and i ultimately gave up to move stuff around rather blindly.
I also tried to find a spot where i could store the ds_type_spec locus
somewhere in grokmethod, but i think the problem was the same, i had
just the type where i cannot store a locus and did not find a place
where i could smuggle the locus along.


Ah, so the problem is deferred parsing of methods, rather than 
templates.  Building the DECL_RESULT sooner does seem like the right 
approach to handling that, whether that's in grokfndecl or grokmethod.



So, to make that clear. Your template function (?) works:

$ XXX=1 ./xg++ -B. -S -o /dev/null ../tmp4/return-narrow-2j.cc
../tmp4/return-narrow-2j.cc: In function ‘int f()’:
../tmp4/return-narrow-2j.cc:1:20: warning: result decl locus sample
 1 | template  int f() { return 42; }
   |^~~
   |the return type
../tmp4/return-narrow-2j.cc: In function ‘int main()’:
../tmp4/return-narrow-2j.cc:3:1: warning: result decl locus sample
 3 | int main()
   | ^~~
   | the return type
../tmp4/return-narrow-2j.cc: In instantiation of ‘int f() [with T = int]’:
../tmp4/return-narrow-2j.cc:5:10:   required from here
../tmp4/return-narrow-2j.cc:1:20: warning: result decl locus sample
 1 | template  int f() { return 42; }
   |^~~
   |the return type


The class member fn not so much (IMHO, see attached):

$ XXX=1 ./xg++ -B. -S -o /dev/null ../tmp4/return-narrow-2.cc
../tmp4/return-narrow-2.cc: In member function ‘const long unsigned int __mini_vector< 
 >::_M_space_left()’:
../tmp4/return-narrow-2.cc:9:3: warning: result decl locus sample
 9 |   { return _M_finish != 0; }
   |   ^
   |   the return type
../tmp4/return-narrow-2.cc: In instantiation of ‘const long unsigned int __mini_vector< 
 >::_M_space_left() [with  = 
std::pair]’:
../tmp4/return-narrow-2.cc:11:17:   required from here
../tmp4/return-narrow-2.cc:9:3: warning: result decl locus sample
 9 |   { return _M_finish != 0; }
   |   ^
   |   the return type
../tmp4/return-narrow-2.cc: In instantiation of ‘const long unsigned int __mini_vector< 
 >::_M_space_left() [with  = int]’:
../tmp4/return-narrow-2.cc:12:17:   required from here
../tmp4/return-narrow-2.cc:9:3: warning: result decl locus sample
 9 |   { return _M_finish != 0; }
   |   ^
   |   the return type





But really I'm not interested in the template case, i only mentioned
them because they don't work and in case somebody wanted to have correct
locations.
I remember just frustration when i looked at those a year ago.


I'd like to get the template case right while we're looking at it.  I
guess I can add that myself if you're done trying.


Is the hunk for normal functions OK for trunk?


You also need a testcase for the desired behavior, with e.g.
{ dg-error "23:" }


I'd have to think about how to test that with trunk, yes.
There are no existing warnings that want to point to the return type,
are there?


Good point.  Do any of your later patches add such a warning?


Maybe a g++.dg/plugin/result_decl_plugin.c then.

set plugin_test_list [list
hmz. That 

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-18 Thread Bernhard Reutner-Fischer via Gcc-patches
On Thu, 17 Nov 2022 18:52:36 -0500
Jason Merrill  wrote:

> On 11/17/22 14:02, Bernhard Reutner-Fischer wrote:
> > On Thu, 17 Nov 2022 09:53:32 -0500
> > Jason Merrill  wrote:

> >> Instead, you want to copy the location for instantiations, i.e. check
> >> DECL_TEMPLATE_INSTANTIATION instead of !DECL_USE_TEMPLATE.  
> > 
> > No, that makes no difference.  
> 
> Hmm, when I stop there when processing the instantiation the template's 
> DECL_RESULT has the right location information, e.g. for
> 
> template  int f() { return 42; }
> 
> int main()
> {
>f();
> }
> 
> #1  0x00f950e8 in instantiate_body (pattern= 0x77ff5080 f>, args=, d= 0x7fffe971e600 f>, nested_p=false) at /home/jason/gt/gcc/cp/pt.cc:26470
> #0  start_preparsed_function (decl1=, 
> attrs=, flags=1) at /home/jason/gt/gcc/cp/decl.cc:17252
> (gdb) p expand_location (input_location)
> $13 = {file = 0x4962370 "wa.C", line = 1, column = 24, data = 0x0, sysp 
> = false}
> (gdb) p expand_location (DECL_SOURCE_LOCATION (DECL_RESULT 
> (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1)
> $14 = {file = 0x4962370 "wa.C", line = 1, column = 20, data = 0x0, sysp 
> = false}

Yes, that works. Sorry if i was not clear: The thing in the cover
letter in this series does not work, the mini_vector reduced testcase
from the libstdc++-v3/include/ext/bitmap_allocator.h.
class template member function return type location, would that be it?

AFAIR the problem was that that these member functions get their result
decl late. When they get them, there are no
declspecs->locations[ds_type_spec] around anywhere to tuck that on the
resdecl. While the result decl is clear, there is no obvious way where
to store the ds_type_spec (somewhere in the template, as you told me).

Back then I tried moving the resdecl building from
start_preparsed_function to grokfndecl but that did not work out easily
IIRC and i ultimately gave up to move stuff around rather blindly.
I also tried to find a spot where i could store the ds_type_spec locus
somewhere in grokmethod, but i think the problem was the same, i had
just the type where i cannot store a locus and did not find a place
where i could smuggle the locus along.

So, to make that clear. Your template function (?) works:

$ XXX=1 ./xg++ -B. -S -o /dev/null ../tmp4/return-narrow-2j.cc 
../tmp4/return-narrow-2j.cc: In function ‘int f()’:
../tmp4/return-narrow-2j.cc:1:20: warning: result decl locus sample
1 | template  int f() { return 42; }
  |^~~
  |the return type
../tmp4/return-narrow-2j.cc: In function ‘int main()’:
../tmp4/return-narrow-2j.cc:3:1: warning: result decl locus sample
3 | int main()
  | ^~~
  | the return type
../tmp4/return-narrow-2j.cc: In instantiation of ‘int f() [with T = int]’:
../tmp4/return-narrow-2j.cc:5:10:   required from here
../tmp4/return-narrow-2j.cc:1:20: warning: result decl locus sample
1 | template  int f() { return 42; }
  |^~~
  |the return type


The class member fn not so much (IMHO, see attached):

$ XXX=1 ./xg++ -B. -S -o /dev/null ../tmp4/return-narrow-2.cc 
../tmp4/return-narrow-2.cc: In member function ‘const long unsigned int 
__mini_vector<  >::_M_space_left()’:
../tmp4/return-narrow-2.cc:9:3: warning: result decl locus sample
9 |   { return _M_finish != 0; }
  |   ^
  |   the return type
../tmp4/return-narrow-2.cc: In instantiation of ‘const long unsigned int 
__mini_vector<  >::_M_space_left() [with 
 = std::pair]’:
../tmp4/return-narrow-2.cc:11:17:   required from here
../tmp4/return-narrow-2.cc:9:3: warning: result decl locus sample
9 |   { return _M_finish != 0; }
  |   ^
  |   the return type
../tmp4/return-narrow-2.cc: In instantiation of ‘const long unsigned int 
__mini_vector<  >::_M_space_left() [with 
 = int]’:
../tmp4/return-narrow-2.cc:12:17:   required from here
../tmp4/return-narrow-2.cc:9:3: warning: result decl locus sample
9 |   { return _M_finish != 0; }
  |   ^
  |   the return type


> 
> > But really I'm not interested in the template case, i only mentioned
> > them because they don't work and in case somebody wanted to have correct
> > locations.
> > I remember just frustration when i looked at those a year ago.  
> 
> I'd like to get the template case right while we're looking at it.  I 
> guess I can add that myself if you're done trying.
> 
> > Is the hunk for normal functions OK for trunk?  
> 
> You also need a testcase for the desired behavior, with e.g.
> { dg-error "23:" }

I'd have to think about how to test that with trunk, yes.
There are no existing warnings that want to point to the return type,
are there?

Maybe a g++.dg/plugin/result_decl_plugin.c then.

set plugin_test_list [list
hmz. That strikes me as not all that flexible.
We could glob *_plugin.[cC][c]*, and have foo_plugin.lst contain it's
files. Whatever.

thanks,
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-17 Thread Jason Merrill via Gcc-patches

On 11/17/22 14:02, Bernhard Reutner-Fischer wrote:

On Thu, 17 Nov 2022 09:53:32 -0500
Jason Merrill  wrote:


On 11/17/22 03:56, Bernhard Reutner-Fischer wrote:

On Tue, 15 Nov 2022 18:52:41 -0500
Jason Merrill  wrote:
   

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 
Cc: Jason Merrill 
---
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.


Moved. Ok like attached? Bootstrapped and regtested fine.
   

  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, );
  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)))


Well, that would probably work if something would set the location of
that template result decl properly, which nothing does out of the box.


Hmm, it should get set by your patch, since templates go through
start_function like normal functions.


diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index ed7226b82f0..65d78c82a2d 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17230,6 +17231,17 @@ start_preparsed_function (tree decl1, tree attrs, int 
flags)
 cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
   }
   
+  /* Set the result decl source location to the location of the typespec.  */

+  if (DECL_RESULT (decl1)
+  && !DECL_USE_TEMPLATE (decl1)
+  && DECL_TEMPLATE_INFO (decl1)
+  && DECL_TI_TEMPLATE (decl1)
+  && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1))
+  && DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1


This condition is true only for the template definition, for which you
haven't gotten to your start_function change yet.

Instead, you want to copy the location for instantiations, i.e. check
DECL_TEMPLATE_INSTANTIATION instead of !DECL_USE_TEMPLATE.


No, that makes no difference.


Hmm, when I stop there when processing the instantiation the template's 
DECL_RESULT has the right location information, e.g. for


template  int f() { return 42; }

int main()
{
  f();
}

#1  0x00f950e8 in instantiate_body (pattern=0x77ff5080 f>, args=, d=0x7fffe971e600 f>, nested_p=false) at /home/jason/gt/gcc/cp/pt.cc:26470
#0  start_preparsed_function (decl1=, 
attrs=, flags=1) at /home/jason/gt/gcc/cp/decl.cc:17252

(gdb) p expand_location (input_location)
$13 = {file = 0x4962370 "wa.C", line = 1, column = 24, data = 0x0, sysp 
= false}
(gdb) p expand_location (DECL_SOURCE_LOCATION (DECL_RESULT 
(DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1)
$14 = {file = 0x4962370 "wa.C", line = 1, column = 20, data = 0x0, sysp 
= false}



But really I'm not interested in the template case, i only mentioned
them because they don't work and in case somebody wanted to have correct
locations.
I remember just frustration when i looked at those a year ago.


I'd like to get the template case right while we're looking at it.  I 
guess I can add that myself if you're done trying.



Is the hunk for normal functions OK for trunk?


You also need a testcase for the desired behavior, with e.g.
{ dg-error "23:" }


thanks,




+  DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
+   = DECL_SOURCE_LOCATION (


Open paren goes on the new line.


+   DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1; >   
  /* Record the decl so that the function name is defined.

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-17 Thread Bernhard Reutner-Fischer via Gcc-patches
On Thu, 17 Nov 2022 09:53:32 -0500
Jason Merrill  wrote:

> On 11/17/22 03:56, Bernhard Reutner-Fischer wrote:
> > On Tue, 15 Nov 2022 18:52:41 -0500
> > Jason Merrill  wrote:
> >   
> >> 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 
> >>> Cc: Jason Merrill 
> >>> ---
> >>>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.  
> > 
> > Moved. Ok like attached? Bootstrapped and regtested fine.
> >   
> >>>  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, );
> >>>  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)))  
> > 
> > Well, that would probably work if something would set the location of
> > that template result decl properly, which nothing does out of the box.  
> 
> Hmm, it should get set by your patch, since templates go through 
> start_function like normal functions.
> 
> > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> > index ed7226b82f0..65d78c82a2d 100644
> > --- a/gcc/cp/decl.cc
> > +++ b/gcc/cp/decl.cc
> > @@ -17230,6 +17231,17 @@ start_preparsed_function (tree decl1, tree attrs, 
> > int flags)
> > cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
> >   }
> >   
> > +  /* Set the result decl source location to the location of the typespec.  
> > */
> > +  if (DECL_RESULT (decl1)
> > +  && !DECL_USE_TEMPLATE (decl1)
> > +  && DECL_TEMPLATE_INFO (decl1)
> > +  && DECL_TI_TEMPLATE (decl1)
> > +  && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1))
> > +  && DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1  
> 
> This condition is true only for the template definition, for which you 
> haven't gotten to your start_function change yet.
> 
> Instead, you want to copy the location for instantiations, i.e. check 
> DECL_TEMPLATE_INSTANTIATION instead of !DECL_USE_TEMPLATE.

No, that makes no difference.
But really I'm not interested in the template case, i only mentioned
them because they don't work and in case somebody wanted to have correct
locations.
I remember just frustration when i looked at those a year ago.

Is the hunk for normal functions OK for trunk?

thanks,

> 
> > +  DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
> > +   = DECL_SOURCE_LOCATION (  
> 
> Open paren goes on the new line.
> 
> > +   DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1; >   
> >   /* Record the decl so that the function name is defined.
> >If we already have a decl for this name, and it is a FUNCTION_DECL,
> >use the old decl.  */
> > 
> > (gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result 
> > locus before")
> > ../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus before
> >  7 |   { return _M_finish != 0; }
> >|   ^
> > (gdb) n
> > (gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result 
> > locus from TI")
> > ../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus from TI
> > (gdb) p DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
> > $1 = 

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-17 Thread Jason Merrill via Gcc-patches

On 11/17/22 03:56, Bernhard Reutner-Fischer wrote:

On Tue, 15 Nov 2022 18:52:41 -0500
Jason Merrill  wrote:


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 
Cc: Jason Merrill 
---
   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.


Moved. Ok like attached? Bootstrapped and regtested fine.


 decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, );
 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)))


Well, that would probably work if something would set the location of
that template result decl properly, which nothing does out of the box.


Hmm, it should get set by your patch, since templates go through 
start_function like normal functions.



diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index ed7226b82f0..65d78c82a2d 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17230,6 +17231,17 @@ start_preparsed_function (tree decl1, tree attrs, int 
flags)
cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
  }
  
+  /* Set the result decl source location to the location of the typespec.  */

+  if (DECL_RESULT (decl1)
+  && !DECL_USE_TEMPLATE (decl1)
+  && DECL_TEMPLATE_INFO (decl1)
+  && DECL_TI_TEMPLATE (decl1)
+  && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1))
+  && DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1


This condition is true only for the template definition, for which you 
haven't gotten to your start_function change yet.


Instead, you want to copy the location for instantiations, i.e. check 
DECL_TEMPLATE_INSTANTIATION instead of !DECL_USE_TEMPLATE.



+  DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
+   = DECL_SOURCE_LOCATION (


Open paren goes on the new line.


+   DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1; >   
  /* Record the decl so that the function name is defined.
   If we already have a decl for this name, and it is a FUNCTION_DECL,
   use the old decl.  */

(gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result locus 
before")
../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus before
 7 |   { return _M_finish != 0; }
   |   ^
(gdb) n
(gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result locus 
from TI")
../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus from TI
(gdb) p DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
$1 = 267168

I'm leaving the template case alone for now, maybe i'm motivated later
on to again look at grokfndecl and/or grokmethod to fill in the proper
location. For starters i only need normal functions.
But many thanks for the hint on where the template stuff is, i thought
i would not need it at all but had hoped that there is a spot where
both declspec are at hand and something is "derived" from the templates.




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








Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-17 Thread Bernhard Reutner-Fischer via Gcc-patches
On Tue, 15 Nov 2022 18:52:41 -0500
Jason Merrill  wrote:

> 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 
> > Cc: Jason Merrill 
> > ---
> >   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.

Moved. Ok like attached? Bootstrapped and regtested fine.

> > decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, );
> > 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)))

Well, that would probably work if something would set the location of
that template result decl properly, which nothing does out of the box.

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index ed7226b82f0..65d78c82a2d 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17230,6 +17231,17 @@ start_preparsed_function (tree decl1, tree attrs, int 
flags)
   cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
 }
 
+  /* Set the result decl source location to the location of the typespec.  */
+  if (DECL_RESULT (decl1)
+  && !DECL_USE_TEMPLATE (decl1)
+  && DECL_TEMPLATE_INFO (decl1)
+  && DECL_TI_TEMPLATE (decl1)
+  && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1))
+  && DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1
+  DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
+   = DECL_SOURCE_LOCATION (
+   DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1;
+
   /* Record the decl so that the function name is defined.
  If we already have a decl for this name, and it is a FUNCTION_DECL,
  use the old decl.  */

(gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result 
locus before")
../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus before
7 |   { return _M_finish != 0; }
  |   ^
(gdb) n
(gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result 
locus from TI")
../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus from TI
(gdb) p DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
$1 = 267168

I'm leaving the template case alone for now, maybe i'm motivated later
on to again look at grokfndecl and/or grokmethod to fill in the proper
location. For starters i only need normal functions.
But many thanks for the hint on where the template stuff is, i thought
i would not need it at all but had hoped that there is a spot where
both declspec are at hand and something is "derived" from the templates.

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

>From 5595eb2d3056f6bca3d2b80bc8b2796d86da0ce8 Mon Sep 17 00:00:00 2001
From: Bernhard Reutner-Fischer 
Date: Sun, 13 Nov 2022 00:45:40 +0100
Subject: [PATCH 2/5] c++: Set the locus of the function result decl

gcc/cp/ChangeLog:

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

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 890cfcabd35..ed7226b82f0 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17527,7 +17527,19 @@ start_function (cp_decl_specifier_seq *declspecs,
 

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-15 Thread Jason Merrill via Gcc-patches

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 
Cc: Jason Merrill 
---
  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, );
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;
  }
  
  /* Returns true iff an EH_SPEC_BLOCK should be created in the body of