Bug 103732 - Incorrect constexpr evaluation of runtime expression
Summary: Incorrect constexpr evaluation of runtime expression
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2021-12-15 11:43 UTC by gnzlbg
Modified: 2024-07-03 17:18 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-07-03 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description gnzlbg 2021-12-15 11:43:15 UTC
GCC 11.2 accepts the following example:

struct S { static constexpr int C = 5; };

void f() {
    S s0{}, s1{};
    S* a[] = {&s0, &s1};

    for (int i = 0; i < 2; ++i) {
        constexpr int x = S::C;
        constexpr int y = s0.C;
        constexpr int z = a[i]->C;
    }
}

According to http://eel.is/c++draft/class.static#general-1, the object expression of s0.C and a[i]->C are evaluated, but for example, a[i] is not a constant expression. 

I think GCC is incorrectly accepting this code.

Clang produces the following error:

<source>:10:23: error: constexpr variable 'z' must be initialized by a constant expression
        constexpr int z = a[i]->C;
                      ^   ~~~~~~~
<source>:10:29: note: read of non-const variable 'i' is not allowed in a constant expression
        constexpr int z = a[i]->C;
                            ^
<source>:7:14: note: declared here
    for (int i = 0; i < 2; ++i) {
             ^
Comment 1 Drea Pinski 2021-12-15 11:47:48 UTC
ICC and MSVC both accept it like GCC ....
Comment 2 gnzlbg 2021-12-15 19:45:50 UTC
> ICC and MSVC both accept it like GCC ....

That's correct, please feel free to report the bug to them as well.
Comment 3 Drea Pinski 2024-07-03 16:59:48 UTC
>        constexpr int y = s0.C;


The above is now valid due to https://wg21.link/p2280r2 (which was acecpted as a defect report against all C++ versions).

>constexpr int z = a[i]->C;

I think this is invalid still because it is a pointer (not a this pointer) and not a reference.
Comment 4 Drea Pinski 2024-07-03 17:07:57 UTC
(In reply to Andrew Pinski from comment #3)
> >        constexpr int y = s0.C;
> 
> 
> The above is now valid due to https://wg21.link/p2280r2 (which was acecpted
> as a defect report against all C++ versions).

Note the paper in the end is https://wg21.link/p2280 .
Comment 5 Drea Pinski 2024-07-03 17:18:24 UTC
So confirmed for the pointer case since that is still invalid.