Skip to content

Commit 839c4e0

Browse files
committed
Bug fix: Emit code for C++ inline function called from another inline function.
Adds a test that fails without the fix. The fix consists simply of removing a return statement; as a result, we now always emit code for functions referenced from the function we are currently emitting. Previously, this was not done for externally visible functions. This goes all the way back to when `GenClangDecl.cpp` was originally introduced here: swiftlang@ee22004 I speculate that the reason for doing this was that in C and Objective-C, we can assume that an externally visible function will be provided by some `.o` file we're linking against (though I'm not sure if this is in fact true for C99 inline functions). At any rate, this assumption is no longer true for C++ inline functions.
1 parent 4265835 commit 839c4e0

File tree

4 files changed

+25
-1
lines changed

4 files changed

+25
-1
lines changed

lib/IRGen/GenClangDecl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ void IRGenModule::emitClangDecl(const clang::Decl *decl) {
4141
if (!valueDecl || valueDecl->isExternallyVisible()) {
4242
ClangCodeGen->HandleTopLevelDecl(
4343
clang::DeclGroupRef(const_cast<clang::Decl*>(decl)));
44-
return;
4544
}
4645

4746
if (!GlobalClangDecls.insert(decl->getCanonicalDecl()).second)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
inline int bar() {
2+
return 42;
3+
}
4+
5+
inline int foo() {
6+
return bar();
7+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module EmitCalledFunction {
2+
header "EmitCalledFunction.h"
3+
export *
4+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// This is a reproducer for a bug where Swift was not emitting code for a
2+
// C++ inline function called from another inline function.
3+
//
4+
// In our example, inline function foo() calls inline function bar(). The bug
5+
// resulted in bar() not being emitted.
6+
7+
// RUN: %empty-directory(%t)
8+
// RUN: %target-swift-frontend %s -I %S/Inputs -enable-cxx-interop -emit-ir -o - | %FileCheck %s
9+
10+
import EmitCalledFunction
11+
12+
// CHECK-DAG: define linkonce_odr i32 @_Z3foov() #{{[0-9]+}} comdat {
13+
// CHECK-DAG: define linkonce_odr i32 @_Z3barv() #{{[0-9]+}} comdat {
14+
foo()

0 commit comments

Comments
 (0)