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>);


Reply via email to