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
{
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
}
}
- 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);
}