Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions gen/tollvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,15 @@ LLGlobalValue::LinkageTypes DtoLinkageOnly(Dsymbol *sym) {
return LLGlobalValue::InternalLinkage;

/* Function (incl. delegate) literals are emitted into each referencing
* compilation unit, so use internal linkage for all lambdas and all global
* compilation unit, so use linkonce_odr for all lambdas and all global
* variables they define.
* This makes sure these symbols don't accidentally collide when linking
* object files compiled by different compiler invocations (lambda mangles
* aren't stable - see https://issues.dlang.org/show_bug.cgi?id=23722).
*/
auto potentialLambda = sym;
if (auto vd = sym->isVarDeclaration())
if (vd->isDataseg())
potentialLambda = vd->toParent2();
if (potentialLambda->isFuncLiteralDeclaration())
return LLGlobalValue::InternalLinkage;
return LLGlobalValue::LinkOnceODRLinkage;

if (sym->isInstantiated())
return templateLinkage;
Expand Down
18 changes: 9 additions & 9 deletions tests/codegen/lambdas_gh3648.d
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Tests that lambdas and contained globals are emitted with internal linkage.
// Tests that lambdas and contained globals are emitted as linkonce_odr.

// RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll

Expand All @@ -25,22 +25,22 @@ void foo()
}(123);
}

// the global variables should be defined as internal:
// CHECK: _D14lambdas_gh364815__lambda_L5_C12FZ10global_bari{{.*}} = internal thread_local global
// CHECK: _D14lambdas_gh364816__lambda_L10_C20FZ18global_bar_inlinedOi{{.*}} = internal global
// CHECK: _D14lambdas_gh36483fooFZ__T15__lambda_L21_C5TiZQuFiZ12lambda_templi{{.*}} = internal global
// the global variables should be defined as linkonce_odr:
// CHECK: _D14lambdas_gh364815__lambda_L5_C12FZ10global_bari{{.*}} = linkonce_odr {{(hidden )?}}thread_local global
// CHECK: _D14lambdas_gh364816__lambda_L10_C20FZ18global_bar_inlinedOi{{.*}} = linkonce_odr {{(hidden )?}}global
// CHECK: _D14lambdas_gh36483fooFZ__T15__lambda_L21_C5TiZQuFiZ12lambda_templi{{.*}} = linkonce_odr {{(hidden )?}}global

// foo() should only call two lambdas:
// CHECK: define {{.*}}_D14lambdas_gh36483fooFZv
// CHECK-NEXT: call {{.*}}__lambda_L5_C12
// CHECK-NEXT: call {{.*}}__T15__lambda_L21_C5
// CHECK-NEXT: ret void

// bar() should be defined as internal:
// CHECK: define internal {{.*}}__lambda_L5_C12
// bar() should be defined as linkonce_odr:
// CHECK: define linkonce_odr {{.*}}__lambda_L5_C12

// bar_inlined() should NOT have made it to the .ll:
// CHECK-NOT: define {{.*}}__lambda_L10_C20

// the template lambda instance should be defined as internal:
// CHECK: define internal {{.*}}__T15__lambda_L21_C5
// the template lambda instance should be defined as linkonce_odr:
// CHECK: define linkonce_odr {{.*}}__T15__lambda_L21_C5
12 changes: 6 additions & 6 deletions tests/codegen/lambdas_gh3648b.d
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Tests that *imported* lambdas and contained globals are emitted with internal linkage.
// Tests that *imported* lambdas and contained globals are emitted as linkonce_odr.

// RUN: %ldc -output-ll -of=%t.ll %s -I%S && FileCheck %s < %t.ll

Expand All @@ -10,17 +10,17 @@ void foo()
bar_inlined();
}

// the global variables should be defined as internal:
// CHECK: _D14lambdas_gh364815__lambda_L5_C12FZ10global_bari{{.*}} = internal thread_local global
// CHECK: _D14lambdas_gh364816__lambda_L10_C20FZ18global_bar_inlinedOi{{.*}} = internal global
// the global variables should be defined as linkonce_odr:
// CHECK: _D14lambdas_gh364815__lambda_L5_C12FZ10global_bari{{.*}} = linkonce_odr {{(hidden )?}}thread_local global
// CHECK: _D14lambdas_gh364816__lambda_L10_C20FZ18global_bar_inlinedOi{{.*}} = linkonce_odr {{(hidden )?}}global

// foo() should only call one lambda:
// CHECK: define {{.*}}_D15lambdas_gh3648b3fooFZv
// CHECK-NEXT: call {{.*}}__lambda_L5_C12
// CHECK-NEXT: ret void

// bar() should be defined as internal:
// CHECK: define internal {{.*}}__lambda_L5_C12
// bar() should be defined as linkonce_odr:
// CHECK: define linkonce_odr {{.*}}__lambda_L5_C12

// bar_inlined() should NOT have made it to the .ll:
// CHECK-NOT: define {{.*}}__lambda_L10_C20