diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 978df516d00..58210f12e64 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2012-01-13 Jason Merrill + + PR c++/51620 + * class.c (build_vtbl_initializer): Use __cxa_deleted_virtual. + 2012-01-12 Jason Merrill PR c++/51714 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 58c89d3dafa..9b957fec36f 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -8352,6 +8352,18 @@ build_vtbl_initializer (tree binfo, init = abort_fndecl_addr; } } + /* Likewise for deleted virtuals. */ + else if (DECL_DELETED_FN (fn_original)) + { + fn = get_identifier ("__cxa_deleted_virtual"); + if (!get_global_value_if_present (fn, &fn)) + fn = push_library_fn (fn, (build_function_type_list + (void_type_node, NULL_TREE)), + NULL_TREE); + if (!TARGET_VTABLE_USES_DESCRIPTORS) + init = fold_convert (vfunc_ptr_type_node, + build_fold_addr_expr (fn)); + } else { if (!integer_zerop (delta) || vcall_index) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cbee6be3d5d..2778556b8e3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-01-13 Jason Merrill + + PR c++/51620 + * g++.dg/cpp0x/defaulted34.C: New. + * g++.dg/template/virtual3.C: New. + 2012-01-13 Richard Guenther PR middle-end/8081 diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted34.C b/gcc/testsuite/g++.dg/cpp0x/defaulted34.C new file mode 100644 index 00000000000..08219926739 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/defaulted34.C @@ -0,0 +1,10 @@ +// { dg-options -std=c++0x } +// { dg-final { scan-assembler "__cxa_deleted_virtual" } } + +struct A +{ + virtual void f(); + virtual ~A() = delete; +}; + +void A::f() {} diff --git a/gcc/testsuite/g++.dg/template/virtual3.C b/gcc/testsuite/g++.dg/template/virtual3.C new file mode 100644 index 00000000000..9fcfc455b7e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/virtual3.C @@ -0,0 +1,11 @@ +// PR c++/51620 + +template class A +{ + virtual ~A(); // { dg-error "non-deleted|private" } +}; + +struct B : A<0>, A<1> // { dg-error "deleted|context" } +{ + B() {} // { dg-error "context" } +};