In C++17 mode we check to make sure that we are initializing directly
from class prvalues rather than copying them, which hit an issue
with packed fields: we create a temporary for binding a
reference to a packed field, and then pass that temporary to the copy
constructor.  This isn't actually a problem, since the packed field
must support trivial copy, so let's just allow it.

Tested x86_64-pc-linux-gnu, applying to trunk and 7.
commit 298b21a24bd9fbfac20a6dca12df2b64655e4f42
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Jun 19 14:44:02 2017 -0400

            PR c++/80972 - C++17 ICE with attribute packed.
    
            * call.c (build_over_call): Allow a TARGET_EXPR from reference
            binding.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index d1f27dd..b56da35 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8025,6 +8025,8 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
         subobject.  */
       if (CHECKING_P && cxx_dialect >= cxx1z)
        gcc_assert (TREE_CODE (arg) != TARGET_EXPR
+                   /* It's from binding the ref parm to a packed field. */
+                   || convs[0]->need_temporary_p
                    || seen_error ()
                    /* See unsafe_copy_elision_p.  */
                    || DECL_BASE_CONSTRUCTOR_P (fn));
diff --git a/gcc/testsuite/g++.dg/ext/packed12.C 
b/gcc/testsuite/g++.dg/ext/packed12.C
new file mode 100644
index 0000000..2ad14de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/packed12.C
@@ -0,0 +1,6 @@
+// PR c++/80972
+
+struct A { int i; };
+struct B { A a; } __attribute__((packed));
+
+A a = B().a;

Reply via email to