This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/82336, ICE with init-list default arg


As analyzed by Nathan and Paolo, the problem here is that the test
conversion in check_default_arg is changing the expression, but then
we discard the result.  Excessive sharing of CONSTRUCTORs is an
ongoing issue, due to past decisions motivated by memory savings.  For
the time being, we can specifically unshare the default argument if it
is an initializer-list, since that's the problematic case.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit f905470ca5ccda134972fdab07f7ed9a0380bf25
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Mar 13 19:34:54 2018 -0400

            PR c++/82336 - link error with list-init default argument.
    
            * decl.c (check_default_argument): Unshare an initializer list.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index afd04cea630..6c113f25a3d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -12661,7 +12661,9 @@ check_default_argument (tree decl, tree arg, tsubst_flags_t complain)
      A default argument expression is implicitly converted to the
      parameter type.  */
   ++cp_unevaluated_operand;
-  perform_implicit_conversion_flags (decl_type, arg, complain,
+  /* Avoid digest_init clobbering the initializer.  */
+  tree carg = BRACE_ENCLOSED_INITIALIZER_P (arg) ? unshare_expr (arg): arg;
+  perform_implicit_conversion_flags (decl_type, carg, complain,
 				     LOOKUP_IMPLICIT);
   --cp_unevaluated_operand;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-defarg2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-defarg2.C
new file mode 100644
index 00000000000..65240355fc3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-defarg2.C
@@ -0,0 +1,8 @@
+// PR c++/82336
+// { dg-do link { target c++11 } }
+
+struct foo { int x = 5; };
+struct bar : foo { bar() = default; };
+struct baz { bar x; };
+void qux(baz = {}){}
+int main() { qux(); }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]