Skip to content

C++26: A reference bound to a reference parameter is wrong #525

Description

@mborland

Issue Summary

Summary

In --c++26 mode, a reference whose initializer is the name of a
reference parameter is bound to the address of the parameter itself
(the pointer slot), not to the object the parameter refers to. Reads give
garbage and writes go to the wrong place. No diagnostic.

This is P1061, and was found while working on the CIR backend

Reproducing Source Code

struct T3 { int a; long b; char c; };
long typed_cref(const T3 &s) { const T3 &r = s; return (long)r.a + r.b + r.c; }

Command-line Options

cpfe --c++26 test.cpp

Type of Issue

[Front End] This code SHOULD compile with these options.

Additional Details

--c++17, --c++20 and --c++23 compile it correctly; only --c++26 is wrong.

Reproducing (Standard) Configuration(s)

macos-arm-clang-debug

Reproducing (Non-standard) Configuration

The generated code

The reference cpfe, --c++26, for typed_cref above (eccp -k):

long _Z10typed_crefRK2T3( const struct T3 *__4_27_s) {
  auto const struct T3 *__4_42_r = ((const struct T3 *)(&__4_27_s));
  return (((long)(__4_42_r->a)) + (__4_42_r->b)) + ((long)(__4_42_r->c)); }

The initializer is &__4_27_s, the address of the parameter, cast to the
referent's pointer type. It should be __4_27_s. The structured binding
forms show the same thing in the binding container:

auto const struct T3 *__T5 = ((const struct T3 *)(&__4_45_s));

So the initializer expression seems to reach the reference-binding code as
an lvalue for the parameter variable, without the implicit dereference a
reference-typed entity gets, and only in C++26 mode. Where that happens has
not been looked for; the cast suggests the binding code then forces the
type instead of noticing the mismatch.

I acknowledge that:

  • I have checked open issues and existing discussions before filing this report.
  • The reproducing source code that I have provided does not depend on headers that I have not included with my submission.
  • I have reduced the reproducing source code to the best of my ability.
  • I have selected at least one standard configuration or uploaded a non-standard configuration dump.
  • I understand code shared via this form is NOT confidential.
  • I have permission to share the reproducing source code and grant permission for the project to use the source code (or derivatives of the source code) to create tests.
  • I agree that any tests created using the reproducing source code (or deriatives of it) will be licensed under project license unless I included a LICENSE.txt file in my .zip or .tar.gz upload. If I included a LICENSE.txt file, any tests created using the reproducing source code will be governed by the terms of the license I provided instead.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions