llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.84k stars 11.47k forks source link

Unexpected internal linkage of const/constexpr variable within extern "C++" #99825

Closed kamrann closed 1 month ago

kamrann commented 1 month ago

clang rejects the following with error: declaration of 'x' with internal linkage cannot be exported:

export module mod;

extern "C++"
{
    export constexpr auto x = 10;
}

Compiler explorer: https://godbolt.org/z/a6nhazoKr

According to [basic.link] 3.2, const (or constexpr ) implies internal linkage for a namespace scope variable, with some exceptions, and 3.2.1 states that one such exception is if the declaration is in the purview of a module interface. clang appears to respect this generally, but in the case of extern "C++" it seems to not apply this exception, as if it considers the contents of such a block to not be part of the module's purview. This feels like a corner case, since obviously the symbols are not attached to the module; but the purview is nonetheless defined as all tokens following the module declaration and I can't see anywhere that states a linkage block is exempt.

Note that MSVC accepts the code.

llvmbot commented 1 month ago

@llvm/issue-subscribers-clang-frontend

Author: Cameron Angus (kamrann)

clang rejects the following with `error: declaration of 'x' with internal linkage cannot be exported`: ``` export module mod; extern "C++" { export constexpr auto x = 10; } ``` Compiler explorer: https://godbolt.org/z/a6nhazoKr According to [[basic.link] 3.2](https://eel.is/c++draft/basic.link#3.2), `const` (or `constexpr` ) implies internal linkage for a namespace scope variable, with some exceptions, and 3.2.1 states that one such exception is if the declaration is in the purview of a module interface. clang appears to respect this generally, but in the case of `extern "C++"` it seems to not apply this exception, as if it considers the contents of such a block to not be part of the module's purview. This feels like a corner case, since obviously the symbols are not attached to the module; but the purview is nonetheless defined as all tokens following the module declaration and I can't see anywhere that states a linkage block is exempt. Note that MSVC accepts the code.
llvmbot commented 1 month ago

@llvm/issue-subscribers-clang-modules

Author: Cameron Angus (kamrann)

clang rejects the following with `error: declaration of 'x' with internal linkage cannot be exported`: ``` export module mod; extern "C++" { export constexpr auto x = 10; } ``` Compiler explorer: https://godbolt.org/z/a6nhazoKr According to [[basic.link] 3.2](https://eel.is/c++draft/basic.link#3.2), `const` (or `constexpr` ) implies internal linkage for a namespace scope variable, with some exceptions, and 3.2.1 states that one such exception is if the declaration is in the purview of a module interface. clang appears to respect this generally, but in the case of `extern "C++"` it seems to not apply this exception, as if it considers the contents of such a block to not be part of the module's purview. This feels like a corner case, since obviously the symbols are not attached to the module; but the purview is nonetheless defined as all tokens following the module declaration and I can't see anywhere that states a linkage block is exempt. Note that MSVC accepts the code.