Skip to content

[GNATS 29059] Lifetime extension #90

Open

Description

@jhsedg

Description

​From: 'Momin Arafa [C]' via support support@edg.com
​To: EDG support
​Cc: Evgeny Abramovich, Ayman Hanna, Mariam Flayyan [C]
​Subject: RE: Possible issue in EDG: Temporary lifetime not extended when reference is bound to a subobject via member access and subscript [EDGcpfe/29032]
​Date: Thursday, September 17, 2026 at 7:41:40 AM
​
​Hi EDG Support,
​
​Following up on EDGcpfe/29032 � we are still seeing a lifetime extension issue with a simpler case not covered by that patch.
​
​Consider:
​int d;
​struct A { int b; ~A() { ++d; } };
​int main() {
​ const int &r = A().b;
​ assert(d == 0); // fails � destructor already called
​}
​
​GCC and Clang correctly extend the lifetime of A() through r. EDG instead copies the value of A().b into a fresh int temporary and binds r to that, then immediately destroys A() at the end of the full-expression.
​
​Best regards,
​Momin Arafa

Notes

​daveed, 2026-09-22:
​This is a sequel to EDGcpfe/29032, which I'm moving to a new entry because we want to make a release.
​I had the fix below, but it introduces regressions, including in Clang's test suite (SemaCXX/constant-expression-cxx2a.cpp). The cmd_line.c change is correct (i.e., it's pretty clear that those versions of Clang and GCC added support for CWG 616), but there is something off with the rest of the change.
​
​
​lin2:~/Dev/cpfe/src$ git diff e7d793320efe920c57c7d1821e1846944f36bf45
​diff --git a/src/cmd_line.c b/src/cmd_line.c
​index 2e8b276058..fa48a6e010 100644
​--- a/src/cmd_line.c
​+++ b/src/cmd_line.c
​@@ -4319,9 +4319,7 @@ default mode (e.g., exception handling).
​ if (!option_kind_used[(int)optk_digit_separators]) {
​ digit_separators_enabled = TRUE;
​ } /* if /
​- if (rvalue_references_enabled &&
​- !gpp_version_is(<90000) && !clangcpp_version_is(<40000)) {
​- /
A field selection on a class prvalue is an xvalue (CWG 616). /
​+ if (rvalue_references_enabled && !gpp_mode && !clang_mode) {
​ selection_from_prvalue_is_xvalue = TRUE;
​ } /
if /
​ relaxed_constexpr_enabled = TRUE;
​diff --git a/src/exprutil.c b/src/exprutil.c
​index 83453da56f..9b2fa13a58 100644
​--- a/src/exprutil.c
​+++ b/src/exprutil.c
​@@ -25273,10 +25273,6 @@ is_temp can be NULL if that information is not needed.
​ clear_expr_or_stmt_traversal_block(&tblock);
​ tblock.process_expr = examine_expr_for_auto_object;
​ tblock.follow_addressing_path = TRUE;
​- /
A prvalue.field xvalue (CWG 616) names a subobject of the class
​- prvalue, so the class object must be considered as well. */
​- tblock.follow_class_rvalue_addressing_path =
​- selection_from_prvalue_is_xvalue;
​ traverse_expr(expr, &tblock);
​ is_auto_object = tblock.result;
​ if (is_temp != NULL) *is_temp = tblock.is_temp;
​@@ -25327,10 +25323,6 @@ underlying entity is a temporary, return is_temp set to TRUE.
​ clear_expr_or_stmt_traversal_block(&tblock);
​ tblock.process_expr = examine_expr_for_auto_object;
​ tblock.follow_addressing_path = TRUE;
​- /
A pointer into a prvalue.field xvalue (CWG 616) addresses a
​- subobject of the class prvalue. */
​- tblock.follow_class_rvalue_addressing_path =
​- selection_from_prvalue_is_xvalue;
​ traverse_expr(expr, &tblock);
​ is_addr_of_auto = tblock.result;
​ *is_temp = tblock.is_temp;

Activity

  1. 1 remaining item

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions