Title
Bad value representations should cause undefined behavior
Status
ready
Section
7.3.2 [conv.lval]
Submitter
Jan Schultke

Created on 2024-06-05.00:00:00 last changed yesterday

Messages

Date: 2024-08-16.19:33:32

Proposed resolution (approved by CWG 2024-08-16):

Change in 7.3.2 [conv.lval] paragraph 3 as follows:

The result of the conversion is determined according to the following rules:
  • If T is cv std::nullptr_t, the result is a null pointer constant (7.3.12 [conv.ptr]). [Note 1: Since the conversion does not access the object to which the glvalue refers, there is no side effect even if T is volatile-qualified (6.9.1 [intro.execution]), and the glvalue can refer to an inactive member of a union (11.5 [class.union]). —end note]
  • Otherwise, if T has a class type, the conversion copy-initializes the result object from the glvalue.
  • Otherwise, if the object to which the glvalue refers contains an invalid pointer value (6.7.5.5.3 [basic.stc.dynamic.deallocation]), the behavior is implementation-defined.
  • Otherwise, if the bits in the value representation of the object to which the glvalue refers are not valid for the object's type, the behavior is undefined. [ Example:
    bool f() {
      bool b = true;
      char c = 42;
      memcpy(&b, &c, 1);
      return b;           // undefined behavior if 42 is not a valid value representation for bool
    }
    
    -- end example ]
  • Otherwise, the object indicated by the glvalue is read (3.1 [defns.access]), and the value contained in the object is the prvalue result. If the result is an erroneous value (6.7.4 [basic.indet]) and the bits in the value representation are not valid for the object's type, the behavior is undefined.
Date: 2024-08-16.19:33:32

(From editorial issue #7051.)

Consider:

static_assert(sizeof(bool) == 1);  // assumption for the example
bool f() {
  char c = 2;
  bool b = true;
  memcpy(&b, &c, 1);     // #1
  return b;              // #2
}

Assuming that false and true are represented as 0 and 1, the value representation of b now has a bad value. This should, but does not, result in undefined behavior during the lvalue-to-rvalue conversion at #2.

History
Date User Action Args
2024-11-19 11:51:56adminsetstatus: tentatively ready -> ready
2024-08-16 19:33:32adminsetmessages: + msg7796
2024-08-16 19:33:32adminsetstatus: open -> tentatively ready
2024-06-05 00:00:00admincreate