LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 45157 - Clang and gcc disagree on whether a `const struct` is a compile-time constant
Summary: Clang and gcc disagree on whether a `const struct` is a compile-time constant
Status: NEW
Alias: None
Product: clang
Classification: Unclassified
Component: C (show other bugs)
Version: trunk
Hardware: PC All
: P enhancement
Assignee: Nick Desaulniers
URL:
Keywords:
Depends on:
Blocks: 4068
  Show dependency tree
 
Reported: 2020-03-09 11:00 PDT by Nick Desaulniers
Modified: 2020-03-12 13:51 PDT (History)
10 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Desaulniers 2020-03-09 11:00:10 PDT
```
struct foo {};
struct bar{
    struct foo foo;
};

static const struct foo my_foo = {};
static const struct bar my_bar = {
    .foo = my_foo,
};
```
Clang produces:
```
<source>:8:12: error: initializer element is not a compile-time constant

    .foo = my_foo,

           ^~~~~~
```
GCC has no error.

A recent CI run on the Linux kernel failed for Clang on this patch:
https://cgit.freedesktop.org/~jani/drm/commit/?h=device-info-inheritance-v3&id=329fec687c7310f3a68ae1c6fd3638274484f149
Comment 1 Nick Desaulniers 2020-03-09 11:15:45 PDT
If I change the `foo` member of `struct bar` from a `struct foo` to an `int`, then initialize `my_bar`'s `.foo` member with a `const int` Clang is happy.  So it seems like a discontinuity that a `const struct` is not allowed.

Both compilers error if the RHS of the initializer is not declared const.

Also, changing the original defintion of `struct bar` to have a `const` qualified `struct foo` makes no difference.
Comment 2 Eli Friedman 2020-03-09 16:18:50 PDT
Any use of a "const" variable in a global initializer is an extension in C.  It's one of the few extensions that's actually allowed by the C standard, though.  Probably makes sense to be compatible with gcc here.
Comment 3 Nick Desaulniers 2020-03-12 13:10:54 PDT
Eli, can you help me find the relevant portion of the standard you're referring to?

From the C11 draft, I'm looking at §6.6.7 and §6.7.9.  Also, I'm having trouble finding any documentation of this feature on the GCC side.
https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html

I have this all working, just adding more tests for initializer lists vs designated initialization.
Comment 4 Eli Friedman 2020-03-12 13:23:09 PDT
6.6 paragraph 10 says "An implementation may accept other forms of constant expressions".

I'm not surprised it isn't documented in gcc; I think gcc implemented the extension by accident, and never formalized it later on.  gcc accepts all sorts of weird stuff in global initializers (for example, "int x = x-3-x;").
Comment 5 Nick Desaulniers 2020-03-12 13:51:43 PDT
Thanks Eli! https://reviews.llvm.org/D76096