[pushed] c++: drop in-charge for dtors without vbases
Checks
Commit Message
Tested x86_64-pc-linux-gnu, applying to trunk.
-- 8< --
Constructors and destructors use the in-charge parameter to decide whether
they're responsible for recursing into virtual bases. Historically all
destructors had this parameter in order to also distinguish the deleting
destructor. But r151673 in GCC 4.5 changed the deleting destructor to just
call the complete destructor and then operator delete, making the in-charge
parameter no longer relevant for destructors in classes without virtual
bases. Having it causes confusion in constexpr evaluation, which assumes
that clones will have the same parameters as the cloned 'tor.
gcc/cp/ChangeLog:
* cp-tree.h (base_ctor_identifier): Adjust comment.
* call.cc (in_charge_arg_for_name): Abort on deleting dtor.
* decl2.cc (maybe_retrofit_in_chrg): Don't add it for
destructors without vbases, either.
* constexpr.cc (cxx_eval_call_expression): Remove workaround.
gcc/testsuite/ChangeLog:
* g++.dg/debug/dwarf2/array-3.C: No more 'int' for in-chrg parm.
* g++.dg/debug/dwarf2/array-4.C: Likewise.
---
gcc/cp/cp-tree.h | 3 +--
gcc/cp/call.cc | 4 +++-
gcc/cp/constexpr.cc | 20 +++++++-------------
gcc/cp/decl2.cc | 12 ++++--------
gcc/testsuite/g++.dg/debug/dwarf2/array-3.C | 6 +++---
gcc/testsuite/g++.dg/debug/dwarf2/array-4.C | 2 +-
6 files changed, 19 insertions(+), 28 deletions(-)
base-commit: 76ca6e1f8b1524b82a871ce29cf58c79e5e77e2b
@@ -289,8 +289,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
/* The name of a constructor that does not construct virtual base classes. */
#define base_ctor_identifier cp_global_trees[CPTI_BASE_CTOR_IDENTIFIER]
/* The name of a destructor that takes an in-charge parameter to
- decide whether or not to destroy virtual base classes and whether
- or not to delete the object. */
+ decide whether or not to destroy virtual base classes. */
#define dtor_identifier cp_global_trees[CPTI_DTOR_IDENTIFIER]
/* The name of a destructor that destroys virtual base classes. */
#define complete_dtor_identifier cp_global_trees[CPTI_COMPLETE_DTOR_IDENTIFIER]
@@ -11167,7 +11167,9 @@ in_charge_arg_for_name (tree name)
if (name == complete_dtor_identifier)
return integer_two_node;
else if (name == deleting_dtor_identifier)
- return integer_three_node;
+ /* The deleting dtor should now be handled by
+ build_delete_destructor_body. */
+ gcc_unreachable ();
gcc_checking_assert (name == base_dtor_identifier);
}
@@ -3243,19 +3243,13 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
ctx->global->put_value (remapped, arg);
remapped = DECL_CHAIN (remapped);
}
- for (; remapped; remapped = TREE_CHAIN (remapped))
- if (DECL_NAME (remapped) == in_charge_identifier)
- {
- /* FIXME destructors unnecessarily have in-charge parameters
- even in classes without vbases, map it to 0 for now. */
- gcc_assert (!CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun)));
- ctx->global->put_value (remapped, integer_zero_node);
- }
- else
- {
- gcc_assert (seen_error ());
- *non_constant_p = true;
- }
+ if (remapped)
+ {
+ /* We shouldn't have any parms without args, but fail gracefully
+ in error recovery. */
+ gcc_checking_assert (seen_error ());
+ *non_constant_p = true;
+ }
/* Add the RESULT_DECL to the values map, too. */
gcc_assert (!DECL_BY_REFERENCE (res));
ctx->global->put_value (res, NULL_TREE);
@@ -275,11 +275,8 @@ build_artificial_parm (tree fn, tree name, tree type)
return parm;
}
-/* Constructors for types with virtual baseclasses need an "in-charge" flag
- saying whether this constructor is responsible for initialization of
- virtual baseclasses or not. All destructors also need this "in-charge"
- flag, which additionally determines whether or not the destructor should
- free the memory for the object.
+/* 'structors for types with virtual baseclasses need an "in-charge" flag
+ saying whether this function is responsible for virtual baseclasses or not.
This function adds the "in-charge" flag to member function FN if
appropriate. It is called from grokclassfn and tsubst.
@@ -302,10 +299,9 @@ maybe_retrofit_in_chrg (tree fn)
if (processing_template_decl)
return;
- /* We don't need an in-charge parameter for constructors that don't
+ /* We don't need an in-charge parameter for 'structors that don't
have virtual bases. */
- if (DECL_CONSTRUCTOR_P (fn)
- && !CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
+ if (!CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
return;
arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
@@ -12,9 +12,9 @@ const S S::array[2] = { S(), S() };
/* Verify that we get only one DW_TAG_subrange_type (plus the abbrev),
and one DW_AT_upper_bound (non-abbrev), because the array
definition loses the readonly wrapper for the array type because of
- the dynamic initializers. The const types are 4: S, S*, int, and
- S[4], plus the abbrev. A const version of S[4] doesn't make sense,
+ the dynamic initializers. The const types are 3: S, S*, and
+ S[2], plus the abbrev. A const version of S[2] doesn't make sense,
but we output it. */
-/* { dg-final { scan-assembler-times " DW_TAG_const_type" 5 } } */
+/* { dg-final { scan-assembler-times " DW_TAG_const_type" 4 } } */
/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */
/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */
@@ -11,6 +11,6 @@ const S array[2] = { S(), S() };
/* Like array-3, but with a non-member array without a separate
declaration, to check that we don't issue the nonsensical
DW_TAG_const_type used by the member array declaration there. */
-/* { dg-final { scan-assembler-times " DW_TAG_const_type" 4 } } */
+/* { dg-final { scan-assembler-times " DW_TAG_const_type" 3 } } */
/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */
/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */