Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clang and gcc disagree on whether a const struct is a compile-time constant #44502

Closed
nickdesaulniers opened this issue Mar 9, 2020 · 10 comments · Fixed by llvm/llvm-project-release-prs#517
Assignees
Labels
bugzilla Issues migrated from bugzilla c clang:frontend Language frontend issues, e.g. anything involving "Sema" release:backport release:merged

Comments

@nickdesaulniers
Copy link
Member

Bugzilla Link 45157
Version trunk
OS All
Blocks #4440
CC @DougGregor,@efriedma-quic,@isanbard,@jyknight,@lalozano,@zygoloid,@stephenhines

Extended Description

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

@nickdesaulniers
Copy link
Member Author

assigned to @nickdesaulniers

@nickdesaulniers
Copy link
Member Author

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.

@efriedma-quic
Copy link
Collaborator

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.

@nickdesaulniers
Copy link
Member Author

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.

@efriedma-quic
Copy link
Collaborator

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;").

@nickdesaulniers
Copy link
Member Author

Thanks Eli! https://reviews.llvm.org/D76096

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
@nickdesaulniers nickdesaulniers added this to the LLVM 17.0.X Release milestone Jul 25, 2023
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status Jul 25, 2023
@nickdesaulniers
Copy link
Member Author

nickdesaulniers commented Jul 25, 2023

@EugeneZelenko EugeneZelenko added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Jul 25, 2023
@llvmbot
Copy link
Member

llvmbot commented Jul 25, 2023

@llvm/issue-subscribers-clang-frontend

@nikic nikic moved this from Needs Triage to Needs Fix in LLVM Release Status Jul 28, 2023
@nickdesaulniers
Copy link
Member Author

/branch ClangBuiltLinux/llvm-project/17_const

llvmbot pushed a commit to llvm/llvm-project-release-prs that referenced this issue Aug 2, 2023
…for C

For code like:
struct foo { ... };
struct bar { struct foo foo; };
const struct foo my_foo = { ... };
struct bar my_bar = { .foo = my_foo };

Eli Friedman points out the relevant part of the C standard seems to
have some flexibility in what is considered a constant expression:

6.6 paragraph 10:
An implementation may accept other forms of constant expressions.

GCC 8 added support for these, so clang not supporting them has been a
constant thorn in the side of source code portability within the Linux
kernel.

Fixes: llvm/llvm-project#44502

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D76096

(cherry picked from commit 610ec95)
@llvmbot
Copy link
Member

llvmbot commented Aug 2, 2023

/pull-request llvm/llvm-project-release-prs#517

@tru tru moved this from Needs Fix to Needs Review in LLVM Release Status Aug 3, 2023
tru pushed a commit to llvm/llvm-project-release-prs that referenced this issue Aug 3, 2023
…for C

For code like:
struct foo { ... };
struct bar { struct foo foo; };
const struct foo my_foo = { ... };
struct bar my_bar = { .foo = my_foo };

Eli Friedman points out the relevant part of the C standard seems to
have some flexibility in what is considered a constant expression:

6.6 paragraph 10:
An implementation may accept other forms of constant expressions.

GCC 8 added support for these, so clang not supporting them has been a
constant thorn in the side of source code portability within the Linux
kernel.

Fixes: llvm/llvm-project#44502

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D76096

(cherry picked from commit 610ec95)
@tru tru moved this from Needs Review to Done in LLVM Release Status Aug 3, 2023
doru1004 pushed a commit to doru1004/llvm-project that referenced this issue Aug 3, 2023
…for C

For code like:
struct foo { ... };
struct bar { struct foo foo; };
const struct foo my_foo = { ... };
struct bar my_bar = { .foo = my_foo };

Eli Friedman points out the relevant part of the C standard seems to
have some flexibility in what is considered a constant expression:

6.6 paragraph 10:
An implementation may accept other forms of constant expressions.

GCC 8 added support for these, so clang not supporting them has been a
constant thorn in the side of source code portability within the Linux
kernel.

Fixes: llvm#44502

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D76096
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c clang:frontend Language frontend issues, e.g. anything involving "Sema" release:backport release:merged
Projects
Development

Successfully merging a pull request may close this issue.

4 participants