c++: Pseudo-destructor ends object lifetime.
P0593R6 is mostly about a new object model whereby malloc and the like are treated as implicitly starting the lifetime of whatever trivial types are necessary to give the program well-defined semantics; that seems only relevant to TBAA, and is not implemented here. The paper also specifies that a pseudo-destructor call (a destructor call for a non-class type) ends the lifetime of the object like a destructor call for an object of class type, even though it doesn't call a destructor; this patch implements that change. The paper was voted as a DR, so I'm applying this change to all standard levels. Like class end-of-life clobbers, it is controlled by -flifetime-dse. gcc/cp/ChangeLog: * pt.c (type_dependent_expression_p): A pseudo-dtor can be dependent. * semantics.c (finish_call_expr): Use build_trivial_dtor_call for pseudo-destructor. (finish_pseudo_destructor_expr): Leave type NULL for dependent arg. gcc/testsuite/ChangeLog: * g++.dg/opt/flifetime-dse7.C: New test.
This commit is contained in:
parent
812798917c
commit
e443d82138
3 changed files with 31 additions and 9 deletions
|
@ -26729,8 +26729,7 @@ type_dependent_expression_p (tree expression)
|
|||
return true;
|
||||
|
||||
/* Some expression forms are never type-dependent. */
|
||||
if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
|
||||
|| TREE_CODE (expression) == SIZEOF_EXPR
|
||||
if (TREE_CODE (expression) == SIZEOF_EXPR
|
||||
|| TREE_CODE (expression) == ALIGNOF_EXPR
|
||||
|| TREE_CODE (expression) == AT_ENCODE_EXPR
|
||||
|| TREE_CODE (expression) == NOEXCEPT_EXPR
|
||||
|
|
|
@ -2707,12 +2707,16 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
|
|||
{
|
||||
if (!vec_safe_is_empty (*args))
|
||||
error ("arguments to destructor are not allowed");
|
||||
/* Mark the pseudo-destructor call as having side-effects so
|
||||
that we do not issue warnings about its use. */
|
||||
result = build1 (NOP_EXPR,
|
||||
void_type_node,
|
||||
TREE_OPERAND (fn, 0));
|
||||
TREE_SIDE_EFFECTS (result) = 1;
|
||||
/* C++20/DR: If the postfix-expression names a pseudo-destructor (in
|
||||
which case the postfix-expression is a possibly-parenthesized class
|
||||
member access), the function call destroys the object of scalar type
|
||||
denoted by the object expression of the class member access. */
|
||||
tree ob = TREE_OPERAND (fn, 0);
|
||||
if (obvalue_p (ob))
|
||||
result = build_trivial_dtor_call (ob);
|
||||
else
|
||||
/* No location to clobber. */
|
||||
result = convert_to_void (ob, ICV_STATEMENT, complain);
|
||||
}
|
||||
else if (CLASS_TYPE_P (TREE_TYPE (fn)))
|
||||
/* If the "function" is really an object of class type, it might
|
||||
|
@ -2845,7 +2849,10 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor,
|
|||
}
|
||||
}
|
||||
|
||||
return build3_loc (loc, PSEUDO_DTOR_EXPR, void_type_node, object,
|
||||
tree type = (type_dependent_expression_p (object)
|
||||
? NULL_TREE : void_type_node);
|
||||
|
||||
return build3_loc (loc, PSEUDO_DTOR_EXPR, type, object,
|
||||
scope, destructor);
|
||||
}
|
||||
|
||||
|
|
16
gcc/testsuite/g++.dg/opt/flifetime-dse7.C
Normal file
16
gcc/testsuite/g++.dg/opt/flifetime-dse7.C
Normal file
|
@ -0,0 +1,16 @@
|
|||
// { dg-options "-O3 -flifetime-dse" }
|
||||
// { dg-do run }
|
||||
|
||||
template <class T>
|
||||
void f()
|
||||
{
|
||||
T t = 42;
|
||||
t.~T();
|
||||
if (t == 42) __builtin_abort();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
f<int>();
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue