[PATCH] D156726: Make globals with mutable members non-constant, even in custom sections

Eduard Zingerman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 16 04:07:56 PDT 2023


eddyz87 added a comment.

Hi @dblaikie,

After this revision landed yesterday one BPF kernel selftest (written in C) stopped building. I narrowed the issue to the following example:

  #define SEC(n) __attribute__((section(n)))
  
  const int with_init SEC("foo") = 1;
  const int no_init SEC("foo");

It fails with the following error:

  $ clang -c t.c -o -
  t.c:4:11: error: 'no_init' causes a section type conflict with 'with_init'
      4 | const int no_init SEC("foo");
        |           ^
  t.c:3:11: note: declared here
      3 | const int with_init SEC("foo") = 1;
        |           ^
  1 error generated.

The error occurs because clang infers `PSF_Read` attribute for section "foo" when `with_init` is processed and `PSF_Read | PSF_Write` attributes for section "foo" when `no_init` is processed, thus reporting `diag::err_section_conflict`. The behavior changed because of the following lines introduced in this revision:

  void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
    ...
    if (GlobalStorage && var->isThisDeclarationADefinition() &&
        !inTemplateInstantiation()) {
      ...
      if (var->hasInit() && HasConstInit && !(Reason =
          var->getType().isNonConstantStorage(Context, true, false))) {
        Stack = &ConstSegStack;
      } else {
        SectionFlags |= ASTContext::PSF_Write;
        Stack = var->hasInit() && HasConstInit ? &DataSegStack : &BSSSegStack;
      }
      ...
    }
    ...
  }

Because of the `var->hasInit()` check any global w/o initializer gets a `PSF_Write` flag, which was not the case before this revision. So, now if one wants to have some `const` globals in the same section, these globals need to have an initializer.

I checked C language standard (N3088, section "6.7.3 Type qualifiers") and it does not offer much to tell if my example is correct or not, so I guess it is implementation dependent. GCC accepts my example w/o errors or warnings.

So, a question: might it be the case that `var->hasInit()` check is too restrictive?
(I do understand that w/o some custom linker behavior `const` globals w/o initializer don't make much sense).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156726/new/

https://reviews.llvm.org/D156726



More information about the cfe-commits mailing list