Skip to content

CWG2728 [expr.delete] The conversion to a pointer prvalue in a delete-expression should also be evaluated exactly once #309

Closed
cplusplus/draft
#7099
@frederick-vs-ja

Description

@frederick-vs-ja

Full name of submitter (unless configured in github; will be published with the issue): Jiang An

Reference (section label): [expr.delete]

Link to reflector thread (if any):

Issue description:

[expr.delete] p4 currently only says

The cast-expression in a delete-expression shall be evaluated exactly once.

When the cast-expression is a glvalue of a pointer type, it doesn't seem guaranteed that the lvalue-to-rvalue conversion from the expression is performed exactly once. Likewise, it doesn't seem guaranteed that the contextual conversion to a pointer from the cast-expression of a class type is performed exactly once. As a result, the destructor call and the operator delete call may use different pointer values, which possibly results in undefined behavior.

In the following example

struct S;
S* ptr{};

struct S {
  S() = default;
  ~S() {
    ptr = this + 1;
  }
};

int main() {
  ptr = new S;
  delete ptr;
}

even though the cast-expression (ptr) is evaluated only once, the value of the ptr object is changed by the destructor call, and thus it's not guaranteed that the operator delete will take the correct pointer value.

It seems that current implementations (correctly) perform the necessary conversions exactly once.

Suggested resolution:

Change [expr.delete] p2 as indicated (CWG1642 might render the changes in this paragraph unnecessary):

If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the. If the possibly converted operand is a glvalue of a pointer type, it is converted to a prvalue of that type by lvalue-to-rvalue conversion (7.3.2 [conv.lval]). The converted operand is used in place of the original operand for the remainder of this subclause. [...]

Change [expr.delete] p4 as indicated:

The cast-expression in a delete-expression, together with the necessary conversions to a prvalue of a pointer type (if any), shall be evaluated exactly once.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions