Opened 5 months ago

#307 new defect

Rvalue-reference promotion missed temporaries

Reported by: mlbrooks Owned by:
Priority: major Component: cfa-cc
Version: 1.0 Keywords: reference double-reference rvalue temporary
Cc:

Description

Another issue when building references and double-references. Possibly related to #301 and #282. Peter found while trying to reproduce #305. Team discussed at meeting 2025-03-12.

#include <fstream.hfa>

struct S {};
void ?{}( S & s ) { sout | 'C'; }
void ^?{}( S & s ) { sout | 'D'; }

void foo( S && rrs ) {}

int main() {
	const int & xxx = 42; // A, ok
        int && rri = 3;       // B, warning
        S s;
        S & rs = s;
        S & rs2 = (S){};
        S && rrs = rs;
        S && rrs2 = (S){};    // C, error
        foo( s );             // D, error
}

Actual:

CFA Version 1.0.0 (debug)
[Line B] warning: rvalue to reference conversion of rvalue: Constant Expression (3: signed int)
... with resolved type:
  signed int.
[Line C] error: Attempt to take address of non-lvalue expression pointer to instance of struct S with body
[Line D] error: Attempt to take address of non-lvalue expression pointer to instance of struct S with body

Expected outcome is undecided; we are reconsidering how much implicit rvalue-to-reference promotion is appropriate. Assuming a maximum amount of promotion being appropriate, the example should compile, perhaps with warnings.

Note Line A is valid in modern C++. Issue #305 is about a variation of Line A, where the type has RAII.

On the call, we speculated that Line B, if allowed, translates correctly like

int rri_obj = 3;
int * rri_temp = & rri_obj;
int ** rri = & rri_temp;

while Line C is actually translating like

struct S ** rrs2 = &&(S){};

though Line C, if allowed, should translate like:

struct S * rrs2_temp = &(S){};
struct S ** rrs2 = &rrs2_temp;

Change History (0)

Note: See TracTickets for help on using tickets.