Commit 45e2bf2e by Nathan Sidwell Committed by Nathan Sidwell

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
parent be845b04
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
......
......@@ -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,
......
......@@ -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;
......
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.
......
// { 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" }
// { 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" }
{ }
// { 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" }
// { 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;
// { 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 ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment