summaryrefslogtreecommitdiff
path: root/src/passes/SignatureRefining.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-04-22 10:56:40 -0700
committerGitHub <noreply@github.com>2022-04-22 10:56:40 -0700
commite16f1e7f250a832742397a1f082c9ea161619ca8 (patch)
treece433a68075350520dae08c2ff77565b3c38d530 /src/passes/SignatureRefining.cpp
parent2ab19d9ac528ff11fa14b184a84c92e72d5b0163 (diff)
downloadbinaryen-e16f1e7f250a832742397a1f082c9ea161619ca8.tar.gz
binaryen-e16f1e7f250a832742397a1f082c9ea161619ca8.tar.bz2
binaryen-e16f1e7f250a832742397a1f082c9ea161619ca8.zip
[NominalFuzzing] SignatureRefining: Ignore exported functions (#4601)
This hits the fuzzer when it tries to call reference exports with a null.
Diffstat (limited to 'src/passes/SignatureRefining.cpp')
-rw-r--r--src/passes/SignatureRefining.cpp25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/passes/SignatureRefining.cpp b/src/passes/SignatureRefining.cpp
index 37ca091df..d094382c7 100644
--- a/src/passes/SignatureRefining.cpp
+++ b/src/passes/SignatureRefining.cpp
@@ -26,6 +26,7 @@
// type, and all call_refs using it).
//
+#include "ir/export-utils.h"
#include "ir/find_all.h"
#include "ir/lubs.h"
#include "ir/module-utils.h"
@@ -69,6 +70,10 @@ struct SignatureRefining : public Pass {
// A possibly improved LUB for the results.
LUBFinder resultsLUB;
+
+ // Normally we can optimize, but some cases prevent a particular signature
+ // type from being changed at all, see below.
+ bool canModify = true;
};
ModuleUtils::ParallelFunctionAnalysis<Info> analysis(
@@ -106,6 +111,20 @@ struct SignatureRefining : public Pass {
allInfo[func->type].resultsLUB.combine(info.resultsLUB);
}
+ // We cannot alter the signature of an exported function, as the outside may
+ // notice us doing so. For example, if we turn a parameter from nullable
+ // into non-nullable then callers sending a null will break. Put another
+ // way, we need to see all callers to refine types, and for exports we
+ // cannot do so.
+ // TODO If a function type is passed we should also mark the types used
+ // there, etc., recursively. For now this code just handles the top-
+ // level type, which is enough to keep the fuzzer from erroring. More
+ // generally, we need to decide about adding a "closed-world" flag of
+ // some kind.
+ for (auto* exportedFunc : ExportUtils::getExportedFunctions(*module)) {
+ allInfo[exportedFunc->type].canModify = false;
+ }
+
bool refinedResults = false;
// Compute optimal LUBs.
@@ -116,6 +135,11 @@ struct SignatureRefining : public Pass {
continue;
}
+ auto& info = allInfo[type];
+ if (!info.canModify) {
+ continue;
+ }
+
auto sig = type.getSignature();
auto numParams = sig.params.size();
@@ -127,7 +151,6 @@ struct SignatureRefining : public Pass {
}
};
- auto& info = allInfo[type];
for (auto* call : info.calls) {
updateLUBs(call->operands);
}