Skip to content

deleting a pointer when the static type and dynamic types are similar is potentially UB CWG2474 #4305

Description

@leni536

http://eel.is/c++draft/expr.delete#3

In a single-object delete expression, if the static type of the object to be deleted is different from its dynamic type and the selected deallocation function (see below) is not a destroying operator delete, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.
In an array delete expression, if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.

"static type" and "dynamic type" includes cv qualification. By the standard wording invoking foo and bar is undefined behavior in the following code:

struct A {};
void foo() {
    A* ptr = new A{};
    const A* cptr = ptr;
    delete cptr;
}

void bar() {
    int i = 42;
    int ** ptr1 = new int*(&i);
    int const * const* ptr2 = ptr1;
    delete ptr2; 
}

Proposed changes:

In a single-object delete expression, if the static type of the object to be deleted is different from not similar to its dynamic type and the selected deallocation function (see below) is not a destroying operator delete, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.
In an array delete expression, if the dynamic type of the object to be deleted differs from is not similar to its static type, the behavior is undefined.

Activity

  1. jensmaurer commented on Dec 6, 2020

    @jensmaurer
    Member

    This does not seem editorial to me.

  2. added
    cwgIssue must be reviewed by CWG.
    not-editorialIssue is not deemed editorial; the editorial issue is kept open for tracking.
    on Dec 6, 2020
  3. jensmaurer commented on Dec 7, 2020

    @jensmaurer
    Member

    CWG 2020-12-07: Differences in cv-qualifiers should not cause UB, but missing array bounds are problematic. Thus, "similar" is not the right property to apply. This will be addressed in a core issue.

  4. leni536 commented on Jul 10, 2021

    @leni536
    Author

    I see that this become CWG2474, and the change is already applied to the current draft. As this wasn't an editorial issue anyway, I feel it is appropriate to close this.

    My thoughts on arrays of unknown bound:

    I think they only cause an issue when the operand of the delete expression is a pointer to an array of unknown bound, they don't cause a problem when they are deeper in the type (like int (**)[]).

    In general the problem is when the operand of the delete expression is a pointer to an incomplete type, however the standard only discusses deleting an object of incomplete class type.

    If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.

    I think an array delete expression with an operand of type T (*)[N] is similarly problematic, if T is an incomplete class type.

    I think the following wording would resolve this:

    If the operand is a pointer to an incomplete type and the type of the deleted object is not trivially destructible, or it has a deallocation function, the behavior is undefined.

  5. changed the title [-]deleting a pointer when the static type and dynamic types are similar is potentially UB[/-] [+]deleting a pointer when the static type and dynamic types are similar is potentially UB CWG2474[/+] on Jul 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    cwgIssue must be reviewed by CWG.not-editorialIssue is not deemed editorial; the editorial issue is kept open for tracking.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions