Skip to content

[SR-521] Public symbols are never dead stripped #5326

Closed
@allevato

Description

@allevato
Previous ID SR-521
Radar None
Original Reporter @allevato
Type Bug
Status Resolved
Resolution Done
Environment

Tested on OS X:
Swift version 2.2-dev (LLVM 46be9ff861, Clang 4deb154edc, Swift 51a9cea5cd)
Target: x86_64-apple-macosx10.9

Tested on Linux:
Swift version 2.2-dev (LLVM 3ebdbb2c7e, Clang f66c5bb67b, Swift 1f2908b4f7)
Target: x86_64-unknown-linux-gnu

Additional Detail from JIRA
Votes 0
Component/s Compiler, Package Manager
Labels Bug
Assignee None
Priority Medium

md5: 58e0a16182b3604b18df177057c9bc29

relates to:

  • SR-1021 Don't export public symbols from static libraries by default

Issue Description:

Symbols declared with public visibility are never dead stripped by the linker, even when linking an executable where there is no expectation that the result would be linked into anything else (and thus unused symbols could be safely discarded).

Stripping these symbols is important when building an executable that links to a large library that it only uses a portion of, to prevent code bloat.

STEPS TO REPRODUCE

1. Create functions.swift, first using internal visibility:

func foo() { print("foo") }
func bar() { print("bar") }

2. Create main.swift:

bar()

3. Build an executable (example provided is for OS X):
swiftc functions.swift main.swift -Xlinker -dead_strip

4. Run nm main and observe that foo has been stripped from the executable.

5. Modify functions.swift to declare the functions with public visibility:

public func foo() { print("foo") }
public func bar() { print("bar") }

6. Build the executable again:
swiftc functions.swift main.swift -Xlinker -dead_strip

7. Run nm main and observe that foo is still present.

EXPECTED BEHAVIOR

foo should be removed because we are building an executable and it is never referenced within that binary.

OTHER NOTES

On OS X, adding the -whole-module-optimization option to swiftc has no effect.

On Linux, the behavior differs. -Xlinker -dead_strip doesn't apply here; instead, we see the following based on -whole-module-optimization:

1. Internal visibility compiled without -whole-module-optimization: foo is not stripped
2. Internal visibility compiled with -whole-module-optimization: foo is stripped
3. Public visibility regardless of the presence of -whole-module-optimization: foo is not stripped

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions