[pushed] c++: defaulted op== for incomplete class [PR107291]

Message ID 20240206022925.850651-1-jason@redhat.com
State Accepted
Headers
Series [pushed] c++: defaulted op== for incomplete class [PR107291] |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Jason Merrill Feb. 6, 2024, 2:29 a.m. UTC
  Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

After complaining about lack of friendship, we should not try to go on and
define the defaulted comparison operator anyway.

	PR c++/107291

gcc/cp/ChangeLog:

	* method.cc (early_check_defaulted_comparison): Fail if not friend.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/spaceship-eq17.C: New test.
---
 gcc/cp/method.cc                            | 6 +++++-
 gcc/testsuite/g++.dg/cpp2a/spaceship-eq17.C | 5 +++++
 2 files changed, 10 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-eq17.C


base-commit: d49780c08aade447953bfe4e877d386f5757f165
  

Comments

Marek Polacek Feb. 6, 2024, 2:55 a.m. UTC | #1
On Mon, Feb 05, 2024 at 09:29:08PM -0500, Jason Merrill wrote:
> Tested x86_64-pc-linux-gnu, applying to trunk.
> 
> -- 8< --
> 
> After complaining about lack of friendship, we should not try to go on and
> define the defaulted comparison operator anyway.
> 
> 	PR c++/107291
> 
> gcc/cp/ChangeLog:
> 
> 	* method.cc (early_check_defaulted_comparison): Fail if not friend.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/cpp2a/spaceship-eq17.C: New test.
> ---
>  gcc/cp/method.cc                            | 6 +++++-
>  gcc/testsuite/g++.dg/cpp2a/spaceship-eq17.C | 5 +++++
>  2 files changed, 10 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-eq17.C
> 
> diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
> index d49e5a565e8..3b8dc75d198 100644
> --- a/gcc/cp/method.cc
> +++ b/gcc/cp/method.cc
> @@ -1228,7 +1228,11 @@ early_check_defaulted_comparison (tree fn)
>  	  /* Defaulted outside the class body.  */
>  	  ctx = TYPE_MAIN_VARIANT (parmtype);
>  	  if (!is_friend (ctx, fn))
> -	    error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
> +	    {
> +	      error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
> +	      inform (location_of (ctx), "declared here");
> +	      ok = false;

Can I push this?

gcc/cp/ChangeLog:

	* method.cc (early_check_defaulted_comparison): Add
	auto_diagnostic_group.
---
 gcc/cp/method.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 3b8dc75d198..957496d3e18 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -1229,6 +1229,7 @@ early_check_defaulted_comparison (tree fn)
 	  ctx = TYPE_MAIN_VARIANT (parmtype);
 	  if (!is_friend (ctx, fn))
 	    {
+	      auto_diagnostic_group d;
 	      error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
 	      inform (location_of (ctx), "declared here");
 	      ok = false;

base-commit: c5d34912ad576be1ef19be92f7eabde54b9089eb
  
Jason Merrill Feb. 6, 2024, 4:31 a.m. UTC | #2
On 2/5/24 21:55, Marek Polacek wrote:
> On Mon, Feb 05, 2024 at 09:29:08PM -0500, Jason Merrill wrote:
>> Tested x86_64-pc-linux-gnu, applying to trunk.
>>
>> -- 8< --
>>
>> After complaining about lack of friendship, we should not try to go on and
>> define the defaulted comparison operator anyway.
>>
>> 	PR c++/107291
>>
>> gcc/cp/ChangeLog:
>>
>> 	* method.cc (early_check_defaulted_comparison): Fail if not friend.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	* g++.dg/cpp2a/spaceship-eq17.C: New test.
>> ---
>>   gcc/cp/method.cc                            | 6 +++++-
>>   gcc/testsuite/g++.dg/cpp2a/spaceship-eq17.C | 5 +++++
>>   2 files changed, 10 insertions(+), 1 deletion(-)
>>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-eq17.C
>>
>> diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
>> index d49e5a565e8..3b8dc75d198 100644
>> --- a/gcc/cp/method.cc
>> +++ b/gcc/cp/method.cc
>> @@ -1228,7 +1228,11 @@ early_check_defaulted_comparison (tree fn)
>>   	  /* Defaulted outside the class body.  */
>>   	  ctx = TYPE_MAIN_VARIANT (parmtype);
>>   	  if (!is_friend (ctx, fn))
>> -	    error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
>> +	    {
>> +	      error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
>> +	      inform (location_of (ctx), "declared here");
>> +	      ok = false;
> 
> Can I push this?
> 
> gcc/cp/ChangeLog:
> 
> 	* method.cc (early_check_defaulted_comparison): Add
> 	auto_diagnostic_group.

Oops, yes, please.  In the future, adding missing auto_diagnostic_group 
can be pushed as obvious.

> ---
>   gcc/cp/method.cc | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
> index 3b8dc75d198..957496d3e18 100644
> --- a/gcc/cp/method.cc
> +++ b/gcc/cp/method.cc
> @@ -1229,6 +1229,7 @@ early_check_defaulted_comparison (tree fn)
>   	  ctx = TYPE_MAIN_VARIANT (parmtype);
>   	  if (!is_friend (ctx, fn))
>   	    {
> +	      auto_diagnostic_group d;
>   	      error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
>   	      inform (location_of (ctx), "declared here");
>   	      ok = false;
> 
> base-commit: c5d34912ad576be1ef19be92f7eabde54b9089eb
  

Patch

diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index d49e5a565e8..3b8dc75d198 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -1228,7 +1228,11 @@  early_check_defaulted_comparison (tree fn)
 	  /* Defaulted outside the class body.  */
 	  ctx = TYPE_MAIN_VARIANT (parmtype);
 	  if (!is_friend (ctx, fn))
-	    error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
+	    {
+	      error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
+	      inform (location_of (ctx), "declared here");
+	      ok = false;
+	    }
 	}
       else if (!same_type_ignoring_top_level_qualifiers_p (parmtype, ctx))
 	saw_bad = true;
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq17.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq17.C
new file mode 100644
index 00000000000..039bfac387c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq17.C
@@ -0,0 +1,5 @@ 
+// PR c++/107291
+// { dg-do compile { target c++20 } }
+
+struct S4;					   // { dg-message "declared here" }
+bool operator==(S4 const &, S4 const &) = default; // { dg-error "not a friend" }