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

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>);
-- 
2.25.1.460.g2f268890c2

Reply via email to