Hi,
in this ICE on invalid regression, after a sensible error message about
the invalid base type we crash in implicit_declare_fn at the gcc_assert:
else if (trivial_p && cxx_dialect >= cxx11
&& (kind == sfk_copy_constructor
|| kind == sfk_move_constructor))
gcc_assert (constexpr_p);
This happens because synthesized_method_walk sets *trivial_p to true and
then envisages to check the vbases with:
if (vbases == NULL)
/* No virtual bases to worry about. */;
else if (!assign_p)
{
if (constexpr_p)
*constexpr_p = false;
FOR_EACH_VEC_ELT (*vbases, i, base_binfo)
the loop doesn't execute at all, vbases->is_empty is true, and
*constexpr_p remains false, inconsistently with *trivial_p.
Normally, that is outside error recovery, either vbases is null or the
vector is non-empty, but in the cases at issue, when xref_basetypes
bails out early with an error about the invalid base type, that isn't
true, the vector is allocated in xref_basetypes but remains empty.
I tried to figure out a way to completely avoid such circumstances, but
rearranging the loop in xref_basetypes doesn't seem easy, or at least
not completely safe at this stage, thus the below.
Thanks,
Paolo.
//////////////////////////
/cp
2014-02-03 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/58871
* method.c (synthesized_method_walk): If vbases is non-null but
is_empty is true, likewise don't worry about the virtual bases.
/testsuite
2014-02-03 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/58871
* g++.dg/cpp0x/pr58871.C: New.
Index: cp/method.c
===================================================================
--- cp/method.c (revision 207422)
+++ cp/method.c (working copy)
@@ -1366,7 +1366,9 @@ synthesized_method_walk (tree ctype, special_funct
}
vbases = CLASSTYPE_VBASECLASSES (ctype);
- if (vbases == NULL)
+ if (vbases == NULL
+ /* Can happen for invalid base types (c++/58871). */
+ || vbases->is_empty ())
/* No virtual bases to worry about. */;
else if (!assign_p)
{
Index: testsuite/g++.dg/cpp0x/pr58871.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr58871.C (revision 0)
+++ testsuite/g++.dg/cpp0x/pr58871.C (working copy)
@@ -0,0 +1,12 @@
+// PR c++/59111
+// { dg-do compile { target c++11 } }
+
+template<typename T> struct A : virtual T // { dg-error "base type" }
+{
+ A();
+ A(const A&);
+};
+
+template<typename T> A<T>::A(const A<T>&) = default;
+
+A<int> a = A<int>();