[clang] Use internal linkage for c23 constexpr vars. (#97846)

See C23 std 6.2.2p3.
Fixes #97830
This commit is contained in:
Dmitriy Chestnykh 2024-07-08 20:09:42 +03:00 committed by GitHub
parent 402eca265f
commit 09a275e8a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 2 deletions

View File

@ -612,19 +612,26 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
"Not a name having namespace scope");
ASTContext &Context = D->getASTContext();
const auto *Var = dyn_cast<VarDecl>(D);
// C++ [basic.link]p3:
// A name having namespace scope (3.3.6) has internal linkage if it
// is the name of
if (getStorageClass(D->getCanonicalDecl()) == SC_Static) {
if ((getStorageClass(D->getCanonicalDecl()) == SC_Static) ||
(Context.getLangOpts().C23 && Var && Var->isConstexpr())) {
// - a variable, variable template, function, or function template
// that is explicitly declared static; or
// (This bullet corresponds to C99 6.2.2p3.)
// C23 6.2.2p3
// If the declaration of a file scope identifier for
// an object contains any of the storage-class specifiers static or
// constexpr then the identifier has internal linkage.
return LinkageInfo::internal();
}
if (const auto *Var = dyn_cast<VarDecl>(D)) {
if (Var) {
// - a non-template variable of non-volatile const-qualified type, unless
// - it is explicitly declared extern, or
// - it is declared in the purview of a module interface unit

View File

@ -0,0 +1,18 @@
/*
* RUN: %clang_cc1 -std=c23 -emit-llvm -o - %s | FileCheck %s
*/
constexpr int var_int = 1;
constexpr char var_char = 'a';
constexpr float var_float = 2.5;
const int *p_i = &var_int;
const char *p_c = &var_char;
const float *p_f = &var_float;
/*
CHECK: @var_int = internal constant i32 1{{.*}}
CHECK: @var_char = internal constant i8 97{{.*}}
CHECK: @var_float = internal constant float 2.5{{.*}}
*/