aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/NaCl/GlobalCleanup.cpp11
-rw-r--r--test/Transforms/NaCl/globalcleanup.ll14
2 files changed, 23 insertions, 2 deletions
diff --git a/lib/Transforms/NaCl/GlobalCleanup.cpp b/lib/Transforms/NaCl/GlobalCleanup.cpp
index 55886f8f7d..d3c58b400a 100644
--- a/lib/Transforms/NaCl/GlobalCleanup.cpp
+++ b/lib/Transforms/NaCl/GlobalCleanup.cpp
@@ -44,7 +44,9 @@ namespace {
char GlobalCleanup::ID = 0;
INITIALIZE_PASS(GlobalCleanup, "nacl-global-cleanup",
- "GlobalValue cleanup for PNaCl", false, false)
+ "GlobalValue cleanup for PNaCl "
+ "(assumes all of the binary is linked statically)",
+ false, false)
static bool CleanUpLinkage(GlobalValue *GV) {
// TODO(dschuff): handle the rest of the linkage types as necessary without
@@ -82,7 +84,12 @@ bool GlobalCleanup::runOnModule(Module &M) {
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ) {
GlobalVariable *GV = I++;
- Modified |= CleanUpLinkage(GV);
+ if (GV->use_empty()) {
+ GV->eraseFromParent();
+ Modified = true;
+ } else {
+ Modified |= CleanUpLinkage(GV);
+ }
}
for (Module::iterator I = M.begin(), E = M.end(); I != E; ) {
diff --git a/test/Transforms/NaCl/globalcleanup.ll b/test/Transforms/NaCl/globalcleanup.ll
index 44e5b45e16..7e1fa3d8a5 100644
--- a/test/Transforms/NaCl/globalcleanup.ll
+++ b/test/Transforms/NaCl/globalcleanup.ll
@@ -16,6 +16,14 @@
; CHECK: @weak_gv = internal global
@weak_gv = weak global i32 0
+; Libc++'s declarations of iostream values are purely ``extern`` and
+; unused otherwise which led to a bug when used as ``(void)std::clog``:
+; the global would survive as ``external global`` post-link but without
+; a proper definition. Global cleanup should take care of it.
+; GV-NOT: ostream
+%"class.fake_ostream" = type { i32 }
+@ostream = external global %"class.fake_ostream"
+
; CHECK: define void @_start
define void @_start() {
ret void
@@ -35,6 +43,12 @@ define i32* @ewc() {
ret i32* @extern_weak_gv
}
+; Make sure @weak_gv is actually used.
+define i32* @wgv() {
+; CHECK: ret i32* @weak_gv
+ ret i32* @weak_gv
+}
+
; GV-NOT: @extern_weak_func
declare extern_weak i32 @extern_weak_func()
; CHECK: @ewf