This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/82336, ICE with init-list default arg
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Cc: Paolo Carlini <paolo dot carlini at oracle dot com>
- Date: Tue, 13 Mar 2018 21:02:35 -0400
- Subject: C++ PATCH for c++/82336, ICE with init-list default arg
- Authentication-results: sourceware.org; auth=none
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(); }