summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-10-19 09:13:45 -0700
committerGitHub <noreply@github.com>2020-10-19 09:13:45 -0700
commite382c577bc7df6f26933a7b7627757ad32bca842 (patch)
tree769a36ca891edbd41bc394d929c89684ebb24754
parent8d8e1c53aa1b03ad4285437a6c41bc86f86731ca (diff)
downloadbinaryen-e382c577bc7df6f26933a7b7627757ad32bca842.tar.gz
binaryen-e382c577bc7df6f26933a7b7627757ad32bca842.tar.bz2
binaryen-e382c577bc7df6f26933a7b7627757ad32bca842.zip
Inlining fuzz fix: Notice ref.func function references in global inits (#3252)
Such a reference may mean we cannot remove a function after inlining it.
-rw-r--r--src/passes/Inlining.cpp8
-rw-r--r--test/passes/inlining_all-features.txt12
-rw-r--r--test/passes/inlining_all-features.wast11
3 files changed, 30 insertions, 1 deletions
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp
index d7f132879..43addff8b 100644
--- a/src/passes/Inlining.cpp
+++ b/src/passes/Inlining.cpp
@@ -326,7 +326,6 @@ struct Inlining : public Pass {
PassRunner runner(module);
FunctionInfoScanner(&infos).run(&runner, module);
// fill in global uses
- // anything exported or used in a table should not be inlined
for (auto& ex : module->exports) {
if (ex->kind == ExternalKind::Function) {
infos[ex->value].usedGlobally = true;
@@ -337,6 +336,13 @@ struct Inlining : public Pass {
infos[name].usedGlobally = true;
}
}
+ for (auto& global : module->globals) {
+ if (!global->imported()) {
+ for (auto* ref : FindAll<RefFunc>(global->init).list) {
+ infos[ref->func].usedGlobally = true;
+ }
+ }
+ }
}
bool iteration(PassRunner* runner, Module* module) {
diff --git a/test/passes/inlining_all-features.txt b/test/passes/inlining_all-features.txt
index b2f483d3d..2141d3d34 100644
--- a/test/passes/inlining_all-features.txt
+++ b/test/passes/inlining_all-features.txt
@@ -47,3 +47,15 @@
)
)
)
+(module
+ (type $none_=>_i32 (func (result i32)))
+ (global $global$0 (mut funcref) (ref.func $0))
+ (func $0 (result i32)
+ (i32.const 1337)
+ )
+ (func $1 (result i32)
+ (block $__inlined_func$0 (result i32)
+ (i32.const 1337)
+ )
+ )
+)
diff --git a/test/passes/inlining_all-features.wast b/test/passes/inlining_all-features.wast
index 47ac3ddb9..f86ad8926 100644
--- a/test/passes/inlining_all-features.wast
+++ b/test/passes/inlining_all-features.wast
@@ -36,3 +36,14 @@
)
)
)
+(module
+ ;; a function reference in a global's init should be noticed, and prevent us
+ ;; from removing an inlined function
+ (global $global$0 (mut funcref) (ref.func $0))
+ (func $0 (result i32)
+ (i32.const 1337)
+ )
+ (func $1 (result i32)
+ (call $0)
+ )
+)