aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Chestnykh <dm.chestnykh@gmail.com>2024-07-08 20:09:42 +0300
committerGitHub <noreply@github.com>2024-07-08 13:09:42 -0400
commit09a275e8a4c2cea22bb67c7247fc892d5e73eb42 (patch)
tree802524ab25f48a82f9061a716ad462b6fb625ed2
parent402eca265f7162e26b8b74d18297fd76c9f100de (diff)
downloadllvm-09a275e8a4c2cea22bb67c7247fc892d5e73eb42.zip
llvm-09a275e8a4c2cea22bb67c7247fc892d5e73eb42.tar.gz
llvm-09a275e8a4c2cea22bb67c7247fc892d5e73eb42.tar.bz2
[clang] Use internal linkage for c23 constexpr vars. (#97846)
See C23 std 6.2.2p3. Fixes #97830
-rw-r--r--clang/lib/AST/Decl.cpp11
-rw-r--r--clang/test/CodeGen/constexpr-c23-internal-linkage.c18
2 files changed, 27 insertions, 2 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 16ed6d8..490c4a2 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -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
diff --git a/clang/test/CodeGen/constexpr-c23-internal-linkage.c b/clang/test/CodeGen/constexpr-c23-internal-linkage.c
new file mode 100644
index 0000000..1236062
--- /dev/null
+++ b/clang/test/CodeGen/constexpr-c23-internal-linkage.c
@@ -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{{.*}}
+*/
+