diff mbox series

c++: Fix missing SFINAE when binding a bit-field to a reference (PR 93729)

Message ID 20200306184137.3926946-2-ppalka@redhat.com
State New
Headers show
Series c++: Fix missing SFINAE when binding a bit-field to a reference (PR 93729) | expand

Commit Message

Patrick Palka March 6, 2020, 6:41 p.m. UTC
We are unconditionally emitting an error here, without first checking complain.

This is not a regression, though I guess it could loosely be considered to be a
concepts bug, and the fix seems to be relatively harmless.  Does this maybe look
OK for trunk, or should it wait for stage 1?

gcc/cp/ChangeLog:

	PR c++/93729
	* call.c (convert_like_real): Check complain before emitting an error
	about binding a bit-field to a reference.

gcc/testsuite/ChangeLog:

	PR c++/93729
	* g++.dg/concepts/pr93729.C: New test.
---
 gcc/cp/call.c                           | 21 ++++++++++++---------
 gcc/testsuite/g++.dg/concepts/pr93729.C | 15 +++++++++++++++
 2 files changed, 27 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/concepts/pr93729.C

Comments

Jason Merrill March 7, 2020, 12:41 a.m. UTC | #1
On 3/6/20 1:41 PM, Patrick Palka wrote:
> We are unconditionally emitting an error here, without first checking complain.
> 
> This is not a regression, though I guess it could loosely be considered to be a
> concepts bug, and the fix seems to be relatively harmless.  Does this maybe look
> OK for trunk, or should it wait for stage 1?

This looks obvious enough to be OK for trunk.

> gcc/cp/ChangeLog:
> 
> 	PR c++/93729
> 	* call.c (convert_like_real): Check complain before emitting an error
> 	about binding a bit-field to a reference.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/93729
> 	* g++.dg/concepts/pr93729.C: New test.
> ---
>   gcc/cp/call.c                           | 21 ++++++++++++---------
>   gcc/testsuite/g++.dg/concepts/pr93729.C | 15 +++++++++++++++
>   2 files changed, 27 insertions(+), 9 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/concepts/pr93729.C
> 
> diff --git a/gcc/cp/call.c b/gcc/cp/call.c
> index 85bbd043a1d..c0340d96f3c 100644
> --- a/gcc/cp/call.c
> +++ b/gcc/cp/call.c
> @@ -7730,15 +7730,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
>   	      {
>   		/* If the reference is volatile or non-const, we
>   		   cannot create a temporary.  */
> -		if (lvalue & clk_bitfield)
> -		  error_at (loc, "cannot bind bit-field %qE to %qT",
> -			    expr, ref_type);
> -		else if (lvalue & clk_packed)
> -		  error_at (loc, "cannot bind packed field %qE to %qT",
> -			    expr, ref_type);
> -		else
> -		  error_at (loc, "cannot bind rvalue %qE to %qT",
> -			    expr, ref_type);
> +		if (complain & tf_error)
> +		  {
> +		    if (lvalue & clk_bitfield)
> +		      error_at (loc, "cannot bind bit-field %qE to %qT",
> +				expr, ref_type);
> +		    else if (lvalue & clk_packed)
> +		      error_at (loc, "cannot bind packed field %qE to %qT",
> +				expr, ref_type);
> +		    else
> +		      error_at (loc, "cannot bind rvalue %qE to %qT",
> +				expr, ref_type);
> +		  }
>   		return error_mark_node;
>   	      }
>   	    /* If the source is a packed field, and we must use a copy
> diff --git a/gcc/testsuite/g++.dg/concepts/pr93729.C b/gcc/testsuite/g++.dg/concepts/pr93729.C
> new file mode 100644
> index 00000000000..7397edb311d
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/concepts/pr93729.C
> @@ -0,0 +1,15 @@
> +// { dg-do compile { target c++2a } }
> +
> +// PR c++/93729
> +
> +struct B
> +{
> +  int a:4;
> +  int b:4;
> +};
> +
> +template<typename T>
> +concept c1
> +  = requires(T x, void(f)(int &)) { f(x.a); }; // { dg-bogus "cannot bind" }
> +
> +static_assert(!c1<B>);
>
diff mbox series

Patch

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 85bbd043a1d..c0340d96f3c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7730,15 +7730,18 @@  convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 	      {
 		/* If the reference is volatile or non-const, we
 		   cannot create a temporary.  */
-		if (lvalue & clk_bitfield)
-		  error_at (loc, "cannot bind bit-field %qE to %qT",
-			    expr, ref_type);
-		else if (lvalue & clk_packed)
-		  error_at (loc, "cannot bind packed field %qE to %qT",
-			    expr, ref_type);
-		else
-		  error_at (loc, "cannot bind rvalue %qE to %qT",
-			    expr, ref_type);
+		if (complain & tf_error)
+		  {
+		    if (lvalue & clk_bitfield)
+		      error_at (loc, "cannot bind bit-field %qE to %qT",
+				expr, ref_type);
+		    else if (lvalue & clk_packed)
+		      error_at (loc, "cannot bind packed field %qE to %qT",
+				expr, ref_type);
+		    else
+		      error_at (loc, "cannot bind rvalue %qE to %qT",
+				expr, ref_type);
+		  }
 		return error_mark_node;
 	      }
 	    /* If the source is a packed field, and we must use a copy
diff --git a/gcc/testsuite/g++.dg/concepts/pr93729.C b/gcc/testsuite/g++.dg/concepts/pr93729.C
new file mode 100644
index 00000000000..7397edb311d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/pr93729.C
@@ -0,0 +1,15 @@ 
+// { dg-do compile { target c++2a } }
+
+// PR c++/93729
+
+struct B
+{
+  int a:4;
+  int b:4;
+};
+
+template<typename T>
+concept c1
+  = requires(T x, void(f)(int &)) { f(x.a); }; // { dg-bogus "cannot bind" }
+
+static_assert(!c1<B>);