aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/method.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-02-09 02:53:41 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2005-02-09 02:53:41 +0000
commit9f4faeaee1e2571c77323f7b2570639c466b248c (patch)
tree4a26d3c40b76aa9d12fd1b7d9aea782111229fc6 /gcc/cp/method.c
parentec2cd8b20cb5c3fad017df6eb91a3210c3ec69f5 (diff)
downloadgcc-9f4faeaee1e2571c77323f7b2570639c466b248c.zip
gcc-9f4faeaee1e2571c77323f7b2570639c466b248c.tar.gz
gcc-9f4faeaee1e2571c77323f7b2570639c466b248c.tar.bz2
re PR c++/19733 (ICE on invalid destructor call)
PR c++/19733 * class.c (add_method): Don't set TYPE_HAS_DESTRUCTOR. (check_bases): Give warnings about a base class with a non-virtual destructor, even if it is implicit. (finish_struct_bits): Don't copy TYPE_HAS_DESTRUCTOR. (maybe_warn_about_overly_private_class): Don't use TYPE_HAS_DESTRUCTOR. (finish_struct_methods): Don't set TYPE_HAS_DESTRUCTOR. (check_for_override): Give it external linkage. (add_implicitly_declared_members): Generate destructors lazily. (check_field_decls): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR, not TYPE_HAS_DESTRUCTOR. (check_bases_and_members): Call check_methods before check_field_decls. (check_bases_and_members): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR, not TYPE_HAS_DESTRUCTOR. (finish_struct_1): Do not use TYPE_HAS_DESTRUCTOR. * cp-tree.def (PSEUDO_DTOR_EXPR): Document. * cp-tree.h (TYPE_HAS_DESTRUCTOR): Remove. (lang_type_class): Add lazy_destructor. (CLASSTYPE_LAZY_DESTRUCTOR): New macro. (CLASSTYPE_DESTRUCTORS): Robustify. (TYPE_HAS_DESTRUCTOR): Remove. (check_for_override): Declare. (build_vbase_delete): Remove. * cvt.c (convert_to_void): Issue errors about pseudo-destructor expressions. * decl.c (cxx_maybe_build_cleanup): Remove dead code. * except.c (dtor_nothrow): Lazily create destructors if necessary. (build_throw): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR. * init.c (build_delete): Lazily create destructors, if necessary. (build_vbase_delete): Remove. * method.c (locate_dtor): Simplify. (implicitly_declare_fn): Add support for destructors. * parser.c (cp_parser_lookup_name): Lazily create destructors, if necessary. * pt.c (check_explicit_specialization): Don't use TYPE_HAS_DESTRUCTOR. (instantiate_class_template): Likewise. * ptree.c (cxx_print_type): Don't print TYPE_HAS_DESTRUCTOR. * rtti.c (emit_support_tinfos): Robustify. * search.c (lookup_fnfields_1): Lazily create destructors. * typeck.c (build_class_member_access_expr): Remove PSEUDO_DTOR_EXPR handling. (lookup_destructor): Likewise. PR c++/19733 * g++.dg/parse/crash23.C: New test. * g++.dg/warn/Weff1.C: New test. From-SVN: r94759
Diffstat (limited to 'gcc/cp/method.c')
-rw-r--r--gcc/cp/method.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 09317a7..fadbf39 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -823,9 +823,7 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
static tree
locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
{
- return (CLASSTYPE_METHOD_VEC (type)
- ? CLASSTYPE_DESTRUCTORS (type)
- : NULL_TREE);
+ return CLASSTYPE_DESTRUCTORS (type);
}
/* Locate the default ctor of TYPE. */
@@ -1035,7 +1033,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
DECL_DECLARED_INLINE_P (fn) = 1;
DECL_INLINE (fn) = 1;
gcc_assert (!TREE_USED (fn));
-
+
return fn;
}
@@ -1060,24 +1058,46 @@ lazily_declare_fn (special_function_kind sfk, tree type)
const_p = false;
/* Declare the function. */
fn = implicitly_declare_fn (sfk, type, const_p);
+ /* A destructor may be virtual. */
+ if (sfk == sfk_destructor)
+ check_for_override (fn, type);
/* Add it to CLASSTYPE_METHOD_VEC. */
add_method (type, fn);
/* Add it to TYPE_METHODS. */
- TREE_CHAIN (fn) = TYPE_METHODS (type);
- TYPE_METHODS (type) = fn;
+ if (sfk == sfk_destructor
+ && DECL_VIRTUAL_P (fn)
+ && abi_version_at_least (2))
+ /* The ABI requires that a virtual destructor go at the end of the
+ vtable. */
+ TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn);
+ else
+ {
+ /* G++ 3.2 put the implicit destructor at the *beginning* of the
+ TYPE_METHODS list, which cause the destructor to be emitted
+ in an incorrect location in the vtable. */
+ if (warn_abi && DECL_VIRTUAL_P (fn))
+ warning ("vtable layout for class %qT may not be ABI-compliant"
+ "and may change in a future version of GCC due to "
+ "implicit virtual destructor",
+ type);
+ TREE_CHAIN (fn) = TYPE_METHODS (type);
+ TYPE_METHODS (type) = fn;
+ }
maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
- if (sfk == sfk_constructor || sfk == sfk_copy_constructor)
+ if (sfk == sfk_assignment_operator)
+ CLASSTYPE_LAZY_ASSIGNMENT_OP (type) = 0;
+ else
{
/* Remember that the function has been created. */
if (sfk == sfk_constructor)
CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
- else
+ else if (sfk == sfk_copy_constructor)
CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
+ else if (sfk == sfk_destructor)
+ CLASSTYPE_LAZY_DESTRUCTOR (type) = 0;
/* Create appropriate clones. */
clone_function_decl (fn, /*update_method_vec=*/true);
}
- else if (sfk == sfk_assignment_operator)
- CLASSTYPE_LAZY_ASSIGNMENT_OP (type) = 0;
return fn;
}