Bug 117614 - [14 Regression] Cannot change active member of anonymous union in constant expression since r14-4771-g1d260ab0e39ea6
Summary: [14 Regression] Cannot change active member of anonymous union in constant ex...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 14.2.1
: P2 normal
Target Milestone: 14.3
Assignee: Jakub Jelinek
URL:
Keywords: rejects-valid
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2024-11-15 21:19 UTC by Fedor Chelnokov
Modified: 2025-01-09 13:09 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 13.3.0
Known to fail: 14.1.0
Last reconfirmed: 2024-11-15 00:00:00


Attachments
gcc15-pr117614.patch (729 bytes, patch)
2024-12-09 16:09 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Fedor Chelnokov 2024-11-15 21:19:24 UTC
This program
```
constexpr int f() {
    union {
        int x{0};
        char y;
    };
    y = 1;
    return y;
}

static_assert( f() == 1 );
```
is accepted in Clang and GCC 13.3, but GCC 14.2 complains:

<source>:6:7: error: accessing 'f()::<unnamed union>::y' member instead of initialized 'f()::<unnamed union>::x' member in constant expression
    6 |     y = 1;
      |     ~~^~~
<source>:4:14: note: initializing 'f()::<unnamed union>::y' requires a member access expression as the left operand of the assignment

Online demo: https://gcc.godbolt.org/z/6h9W5fjh1
Comment 1 Drea Pinski 2024-11-15 21:26:21 UTC
Confirmed.
Comment 2 Sam James 2024-11-15 23:40:08 UTC
r14-4771-g1d260ab0e39ea6
Comment 3 Jakub Jelinek 2024-12-09 16:09:33 UTC
Created attachment 59821 [details]
gcc15-pr117614.patch

Untested fix.
Comment 4 GCC Commits 2024-12-11 16:29:22 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:337815c8bbd0fb5034223ad0e7899d1493e958a2

commit r15-6119-g337815c8bbd0fb5034223ad0e7899d1493e958a2
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Dec 11 17:28:47 2024 +0100

    c++: allow stores to anon union vars to change current union member in constexpr [PR117614]
    
    Since r14-4771 the FE tries to differentiate between cases where the lhs
    of a store allows changing the current union member and cases where it
    doesn't, and cases where it doesn't includes everything that has gone
    through the cxx_eval_constant_expression path on the lhs.
    As the testcase shows, DECL_ANON_UNION_VAR_P vars were handled like that
    too, even when stores to them are the only way how to change the current
    union member in the sources.
    
    So, the following patch just handles that case manually without calling
    cxx_eval_constant_expression and without setting evaluated to true.
    
    2024-12-11  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/117614
            * constexpr.cc (cxx_eval_store_expression): For stores to
            DECL_ANON_UNION_VAR_P vars just continue with DECL_VALUE_EXPR
            of it, without setting evaluated to true or full
            cxx_eval_constant_expression.
    
            * g++.dg/cpp2a/constexpr-union8.C: New test.
Comment 5 Jakub Jelinek 2024-12-11 16:30:30 UTC
Fixed on the trunk so far.
Comment 6 GCC Commits 2025-01-09 12:58:13 UTC
The releases/gcc-14 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:7ae55c2f73626e8a7a6871a1e4fd4cde2e6c8460

commit r14-11153-g7ae55c2f73626e8a7a6871a1e4fd4cde2e6c8460
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Dec 11 17:28:47 2024 +0100

    c++: allow stores to anon union vars to change current union member in constexpr [PR117614]
    
    Since r14-4771 the FE tries to differentiate between cases where the lhs
    of a store allows changing the current union member and cases where it
    doesn't, and cases where it doesn't includes everything that has gone
    through the cxx_eval_constant_expression path on the lhs.
    As the testcase shows, DECL_ANON_UNION_VAR_P vars were handled like that
    too, even when stores to them are the only way how to change the current
    union member in the sources.
    
    So, the following patch just handles that case manually without calling
    cxx_eval_constant_expression and without setting evaluated to true.
    
    2024-12-11  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/117614
            * constexpr.cc (cxx_eval_store_expression): For stores to
            DECL_ANON_UNION_VAR_P vars just continue with DECL_VALUE_EXPR
            of it, without setting evaluated to true or full
            cxx_eval_constant_expression.
    
            * g++.dg/cpp2a/constexpr-union8.C: New test.
    
    (cherry picked from commit 337815c8bbd0fb5034223ad0e7899d1493e958a2)
Comment 7 Jakub Jelinek 2025-01-09 13:09:35 UTC
Fixed for 14.3 as well.