Skip to content

Commit 09a275e

Browse files
authored
[clang] Use internal linkage for c23 constexpr vars. (llvm#97846)
See C23 std 6.2.2p3. Fixes llvm#97830
1 parent 402eca2 commit 09a275e

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

clang/lib/AST/Decl.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,19 +612,26 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
612612
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
613613
"Not a name having namespace scope");
614614
ASTContext &Context = D->getASTContext();
615+
const auto *Var = dyn_cast<VarDecl>(D);
615616

616617
// C++ [basic.link]p3:
617618
// A name having namespace scope (3.3.6) has internal linkage if it
618619
// is the name of
619620

620-
if (getStorageClass(D->getCanonicalDecl()) == SC_Static) {
621+
if ((getStorageClass(D->getCanonicalDecl()) == SC_Static) ||
622+
(Context.getLangOpts().C23 && Var && Var->isConstexpr())) {
621623
// - a variable, variable template, function, or function template
622624
// that is explicitly declared static; or
623625
// (This bullet corresponds to C99 6.2.2p3.)
626+
627+
// C23 6.2.2p3
628+
// If the declaration of a file scope identifier for
629+
// an object contains any of the storage-class specifiers static or
630+
// constexpr then the identifier has internal linkage.
624631
return LinkageInfo::internal();
625632
}
626633

627-
if (const auto *Var = dyn_cast<VarDecl>(D)) {
634+
if (Var) {
628635
// - a non-template variable of non-volatile const-qualified type, unless
629636
// - it is explicitly declared extern, or
630637
// - it is declared in the purview of a module interface unit
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* RUN: %clang_cc1 -std=c23 -emit-llvm -o - %s | FileCheck %s
3+
*/
4+
5+
constexpr int var_int = 1;
6+
constexpr char var_char = 'a';
7+
constexpr float var_float = 2.5;
8+
9+
const int *p_i = &var_int;
10+
const char *p_c = &var_char;
11+
const float *p_f = &var_float;
12+
13+
/*
14+
CHECK: @var_int = internal constant i32 1{{.*}}
15+
CHECK: @var_char = internal constant i8 97{{.*}}
16+
CHECK: @var_float = internal constant float 2.5{{.*}}
17+
*/
18+

0 commit comments

Comments
 (0)