aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2016-10-07 20:01:17 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2016-10-07 20:01:17 +0000
commit45e2bf2e5e370e62c3cef575b6726dc936a45599 (patch)
tree78bc0aa76089b14017a65f3d962a9887be116e09 /gcc
parentbe845b04a8e13e91e7ecd76b60254c7d0acfda2e (diff)
downloadgcc-45e2bf2e5e370e62c3cef575b6726dc936a45599.zip
gcc-45e2bf2e5e370e62c3cef575b6726dc936a45599.tar.gz
gcc-45e2bf2e5e370e62c3cef575b6726dc936a45599.tar.bz2
re PR c++/64433 (Segmentation fault while compiling)
cp/ PR c++/64433 DR1658, DR1611 * init.c (emit_mem_initializers): Don't construct vbases of abstract classes. (push_base_cleanups): Don't push vbase cleanups for abstract class when in C++14 mode. * method.c (synthethesized_method_walk): Don't walk vbases of abstract classes when in C++14 mode. testsuite/ PR c++/66443 * g++.dg/cpp0x/pr66443-cxx11.C: New. * g++.dg/cpp0x/pr66443-cxx11-2.C: New. * g++.dg/cpp1y/pr66443-cxx14.C: New * g++.dg/cpp1y/pr66443-cxx14-2.C: New. * g++.dg/cpp1y/pr66443-cxx14-3.C: New. From-SVN: r240874
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/init.c11
-rw-r--r--gcc/cp/method.c20
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr66443-cxx11-2.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr66443-cxx11.C30
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14-2.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14-3.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14.C47
9 files changed, 193 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ce875ce..da2ca07 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2016-10-07 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/64433
+ DR1658, DR1611
+ * init.c (emit_mem_initializers): Don't construct vbases of
+ abstract classes.
+ (push_base_cleanups): Don't push vbase cleanups for abstract class
+ when in C++14 mode.
+ * method.c (synthethesized_method_walk): Don't walk vbases of
+ abstract classes when in C++14 mode.
+
2016-10-07 Jakub Jelinek <jakub@redhat.com>
Implement LWG2296 helper intrinsic
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 63c3dab..a873bb1 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1154,9 +1154,7 @@ emit_mem_initializers (tree mem_inits)
}
/* Initialize the base. */
- if (BINFO_VIRTUAL_P (subobject))
- construct_virtual_base (subobject, arguments);
- else
+ if (!BINFO_VIRTUAL_P (subobject))
{
tree base_addr;
@@ -1170,6 +1168,10 @@ emit_mem_initializers (tree mem_inits)
tf_warning_or_error);
expand_cleanup_for_base (subobject, NULL_TREE);
}
+ else if (!ABSTRACT_CLASS_TYPE_P (current_class_type))
+ /* C++14 DR1658 Means we do not have to construct vbases of
+ abstract classes. */
+ construct_virtual_base (subobject, arguments);
}
in_base_initializer = 0;
@@ -4536,7 +4538,8 @@ push_base_cleanups (void)
vec<tree, va_gc> *vbases;
/* Run destructors for all virtual baseclasses. */
- if (CLASSTYPE_VBASECLASSES (current_class_type))
+ if (!ABSTRACT_CLASS_TYPE_P (current_class_type)
+ && CLASSTYPE_VBASECLASSES (current_class_type))
{
tree cond = (condition_conversion
(build2 (BIT_AND_EXPR, integer_type_node,
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index bbbf59b..73a670b 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1319,12 +1319,12 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
}
}
-/* The caller wants to generate an implicit declaration of SFK for CTYPE
- which is const if relevant and CONST_P is set. If spec_p, trivial_p and
- deleted_p are non-null, set their referent appropriately. If diag is
- true, we're either being called from maybe_explain_implicit_delete to
- give errors, or if constexpr_p is non-null, from
- explain_invalid_constexpr_fn. */
+/* The caller wants to generate an implicit declaration of SFK for
+ CTYPE which is const if relevant and CONST_P is set. If SPEC_P,
+ TRIVIAL_P, DELETED_P or CONSTEXPR_P are non-null, set their
+ referent appropriately. If DIAG is true, we're either being called
+ from maybe_explain_implicit_delete to give errors, or if
+ CONSTEXPR_P is non-null, from explain_invalid_constexpr_fn. */
static void
synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
@@ -1534,9 +1534,13 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
}
vbases = CLASSTYPE_VBASECLASSES (ctype);
- if (vec_safe_is_empty (vbases))
+ if (assign_p)
+ /* No need to examine vbases here. */;
+ else if (vec_safe_is_empty (vbases))
/* No virtual bases to worry about. */;
- else if (!assign_p)
+ else if (ABSTRACT_CLASS_TYPE_P (ctype) && cxx_dialect >= cxx14)
+ /* Vbase cdtors are not relevant. */;
+ else
{
if (constexpr_p)
*constexpr_p = false;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 07cfac4..4d79c78 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2016-10-07 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/66443
+ * g++.dg/cpp0x/pr66443-cxx11.C: New.
+ * g++.dg/cpp0x/pr66443-cxx11-2.C: New.
+ * g++.dg/cpp1y/pr66443-cxx14.C: New
+ * g++.dg/cpp1y/pr66443-cxx14-2.C: New.
+ * g++.dg/cpp1y/pr66443-cxx14-3.C: New.
+
2016-10-07 Jakub Jelinek <jakub@redhat.com>
* g++.dg/cpp0x/addressof1.C: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr66443-cxx11-2.C b/gcc/testsuite/g++.dg/cpp0x/pr66443-cxx11-2.C
new file mode 100644
index 0000000..4bd641d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr66443-cxx11-2.C
@@ -0,0 +1,23 @@
+// { dg-do compile { target c++11_only } }
+
+class C;
+
+
+struct A {
+ A ();
+private:
+ ~A (){ }
+ friend class C;
+};
+
+struct B : virtual A { // { dg-error "is private" }
+ B ();
+ virtual bool Ok () = 0; // abstract
+};
+
+struct C : B { // { dg-error "use of deleted" }
+ C ();
+ virtual bool Ok ();
+};
+
+C c; // { dg-error "use of deleted" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr66443-cxx11.C b/gcc/testsuite/g++.dg/cpp0x/pr66443-cxx11.C
new file mode 100644
index 0000000..7ba0074
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr66443-cxx11.C
@@ -0,0 +1,30 @@
+// { dg-do compile { target c++11_only } }
+
+// pr c++/66443 it is still ill-formed in C++ 11 for a synthesized
+// ctor that's deleted only because of virtual base construction
+
+static bool a_made;
+
+struct A { // { dg-message "candidate" }
+ A( int ) { a_made = true; } // { dg-message "candidate" }
+};
+
+struct B: virtual A { // { dg-message "no matching function" }
+ int m;
+ virtual void Frob () = 0;
+};
+
+class C: public B {
+public:
+ C();
+ virtual void Frob ();
+};
+
+void C::Frob ()
+{
+}
+
+C::C ()
+ : A( 1 ) // { dg-error "deleted function" }
+{ }
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14-2.C b/gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14-2.C
new file mode 100644
index 0000000..e033f1f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14-2.C
@@ -0,0 +1,29 @@
+// { dg-do compile { target c++14 } }
+
+// pr c++/66443 a synthesized ctor of an abstract class that's deleted
+// only because of virtual base construction doesn't stop a derived
+// class using it as a base object constructor (provided it has a
+// suitable ctor invocation of the virtual base).
+
+// However we should still complain if the intermediate base is a
+// non-abstract type.
+
+static int a_made;
+
+struct A {
+ A *m_a = this;
+ A (int) { a_made++; }
+};
+
+struct B : virtual A { // { dg-error "no matching function" }
+ A *m_b = this;
+ virtual bool Ok (); // not abstract
+};
+
+bool B::Ok ()
+{
+ return false;
+}
+
+
+B b; // { dg-error "deleted" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14-3.C b/gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14-3.C
new file mode 100644
index 0000000..b335c4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14-3.C
@@ -0,0 +1,25 @@
+// { dg-do compile { target c++14 } }
+
+// DR 1658, inaccessible dtor of virtual base doesn't affect an
+// abstract class
+
+int a_unmade;
+
+class C;
+
+
+struct A {
+private:
+ ~A (){ a_unmade++; }
+ friend class C;
+};
+
+struct B : virtual A {
+ virtual bool Ok () = 0; // abstract
+};
+
+struct C : B {
+ virtual bool Ok ();
+};
+
+C c;
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14.C b/gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14.C
new file mode 100644
index 0000000..5834808
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr66443-cxx14.C
@@ -0,0 +1,47 @@
+// { dg-do run { target c++14 } }
+
+// pr c++/66443 a synthesized ctor of an abstract class that's deleted
+// only because of virtual base construction doesn't stop a derived
+// class using it as a base object constructor (provided it has a
+// suitable ctor invocation of the virtual base).
+
+static int a_made;
+
+struct A {
+ A *m_a = this;
+ A (int) { a_made++; }
+};
+
+struct B : virtual A {
+ A *m_b = this;
+ virtual bool Ok () = 0; // abstract
+};
+
+struct C : B {
+ // C::m_c is placed where a complete B object would put A
+ int m_c = 1729;
+public:
+ C();
+ virtual bool Ok ();
+};
+
+bool C::Ok ()
+{
+ // check everyone agreed on where A is
+ return a_made == 1 && m_a == this && m_b == this && m_c == 1729;
+}
+
+C::C ()
+ : A (1) // Explicit call of A's ctor
+{ }
+
+bool Ok (C &c)
+{
+}
+
+int main ()
+{
+ C c;
+
+ return !c.Ok ();
+}