Issue 178349
Summary (C23) Acessing a constexpr struct through the dot operator does not yield a constant.
Labels new issue
Assignees
Reporter bragabreno
    ```
#include <stdio.h>

#define comptime_if(predicate, on_true, on_false)       \
	_Generic                                        \
        (                                               \
                (char (*)[ 1 + !!(predicate) ]){0},     \
                                                        \
                char (*)[2]: (on_true),                 \
                char (*)[1]: (on_false)                 \
        )


struct S { int x, y; };
constexpr struct S s = {0, 1};

int main(void)
{                                     
    int arr[s.y] = { }; 

    static_assert(s.y);

    comptime_if(s.x, puts("true\n"), puts("false\n"));
    
    return 0;
}
```
On Clang, unlike GCC, accessing constexpr structs through the dot operator does not seem to yield a constant. 

In the [example above](https://godbolt.org/z/fE787anhq), `arr` is a constant-sized array in GCC but, in Clang, it is a VLA that gets folded into the former (through an extension).
A similar thing happens to the _expression_ in `static_assert` (integer constant in GCC, but non-constant folded into constant in Clang). 

This can be seen more clearly in the `comptime_if` macro: such a conversion does not happen there, so the `_Generic` operand has a VLA type which matches both `char (*)[1]` `char (*)[2]`, causing a compilation error (in Clang, but not in GCC).

If I understand it correctly [N3220](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf) seems to agree with the behavior of GCC:

§ 6.6p7:

> An identifier that is:
> — an enumeration constant,
> — a predefined constant, or
> — declared with storage-class specifier constexpr and has an object type,
> is a named constant, as is a postfix _expression_ that applies the . member access operator to a named
> constant of structure or union type, even recursively. For enumeration and predefined constants,
> their value and type are defined in the respective clauses; for constexpr objects, such a named
> constant is a constant _expression_ with the type and value of the declared object.

§ 6.6p13:

> A structure or union constant is a named constant or compound literal constant with structure or
> union type, respectively

§ 6.6p15:

> Starting from a structure or union constant, the member-access . operator may be used to form a
> named constant or compound literal constant as described previously in this subclause




_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to