Skip to content

Commit 16b3c7e

Browse files
authored
ImportC: Fix static linkage (#4487)
Fixes #4484.
1 parent db9323d commit 16b3c7e

File tree

3 files changed

+42
-26
lines changed

3 files changed

+42
-26
lines changed

gen/tollvm.cpp

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -227,32 +227,39 @@ LLValue *DtoDelegateEquals(EXP op, LLValue *lhs, LLValue *rhs) {
227227

228228
////////////////////////////////////////////////////////////////////////////////
229229

230-
LinkageWithCOMDAT DtoLinkage(Dsymbol *sym) {
231-
LLGlobalValue::LinkageTypes linkage = LLGlobalValue::ExternalLinkage;
232-
if (hasWeakUDA(sym)) {
233-
linkage = LLGlobalValue::WeakAnyLinkage;
234-
} else {
235-
/* Function (incl. delegate) literals are emitted into each referencing
236-
* compilation unit, so use internal linkage for all lambdas and all global
237-
* variables they define.
238-
* This makes sure these symbols don't accidentally collide when linking
239-
* object files compiled by different compiler invocations (lambda mangles
240-
* aren't stable - see https://issues.dlang.org/show_bug.cgi?id=23722).
241-
*/
242-
auto potentialLambda = sym;
243-
if (auto vd = sym->isVarDeclaration()) {
244-
if (vd->isDataseg())
245-
potentialLambda = vd->toParent2();
246-
}
230+
namespace {
231+
LLGlobalValue::LinkageTypes DtoLinkageOnly(Dsymbol *sym) {
232+
if (hasWeakUDA(sym))
233+
return LLGlobalValue::WeakAnyLinkage;
234+
235+
// static in ImportC translates to internal linkage
236+
if (auto decl = sym->isDeclaration())
237+
if ((decl->storage_class & STCstatic) && decl->isCsymbol())
238+
return LLGlobalValue::InternalLinkage;
239+
240+
/* Function (incl. delegate) literals are emitted into each referencing
241+
* compilation unit, so use internal linkage for all lambdas and all global
242+
* variables they define.
243+
* This makes sure these symbols don't accidentally collide when linking
244+
* object files compiled by different compiler invocations (lambda mangles
245+
* aren't stable - see https://issues.dlang.org/show_bug.cgi?id=23722).
246+
*/
247+
auto potentialLambda = sym;
248+
if (auto vd = sym->isVarDeclaration())
249+
if (vd->isDataseg())
250+
potentialLambda = vd->toParent2();
251+
if (potentialLambda->isFuncLiteralDeclaration())
252+
return LLGlobalValue::InternalLinkage;
247253

248-
if (potentialLambda->isFuncLiteralDeclaration()) {
249-
linkage = LLGlobalValue::InternalLinkage;
250-
} else if (sym->isInstantiated()) {
251-
linkage = templateLinkage;
252-
}
253-
}
254+
if (sym->isInstantiated())
255+
return templateLinkage;
254256

255-
return {linkage, needsCOMDAT()};
257+
return LLGlobalValue::ExternalLinkage;
258+
}
259+
}
260+
261+
LinkageWithCOMDAT DtoLinkage(Dsymbol *sym) {
262+
return {DtoLinkageOnly(sym), needsCOMDAT()};
256263
}
257264

258265
bool needsCOMDAT() {

tests/codegen/importc_static.i

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Makes sure static in ImportC translates to `internal` IR linkage.
2+
// See https://github.com/ldc-developers/ldc/issues/4484.
3+
4+
// RUN: %ldc -output-ll %s -of=%t.ll && FileCheck %s < %t.ll
5+
6+
// CHECK: myPrivateGlobal = internal global i32 0
7+
static int myPrivateGlobal;
8+
9+
// CHECK: define internal void {{.*}}myPrivateFunc
10+
static void myPrivateFunc() {}

tests/lit.site.cfg.in

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ config.test_format = lit.formats.ShTest(execute_external=False)
4545

4646
# suffixes: A list of file extensions to treat as test files. This is overriden
4747
# by individual lit.local.cfg files in the test subdirectories.
48-
config.suffixes = ['.d',
49-
]
48+
config.suffixes = ['.d', '.i']
5049

5150
# excludes: A list of directories to exclude from the testsuite. The 'inputs'
5251
# subdirectories contain auxiliary inputs for various tests in their parent

0 commit comments

Comments
 (0)