diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp index 112a001dd01..e2b665a3cb5 100644 --- a/src/tools/wasm-split/wasm-split.cpp +++ b/src/tools/wasm-split/wasm-split.cpp @@ -424,42 +424,41 @@ void multiSplitModule(const WasmSplitOptions& options) { bool newSection = true; std::unordered_set moduleNameSet; while (std::getline(manifest, line)) { - if (line.empty()) { - newSection = true; - if (currFuncs->empty() && !options.quiet) { - std::cerr << "warning: Module " << currModule << " will be empty\n"; - } - continue; - } - Name name = line; if (newSection) { - if (name.endsWith(":")) { - name = name.substr(0, name.size() - 1); - if (name.size() == 0) { - Fatal() << "Module name is empty\n"; - } + Name moduleName = line; + if (moduleName.endsWith(":")) { + moduleName = moduleName.substr(0, moduleName.size() - 1); + } + if (moduleName.size() == 0) { + Fatal() << "Module name is empty\n"; } - if (moduleNameSet.contains(name)) { - Fatal() << "Module name " << name << " is listed more than once\n"; + if (moduleNameSet.contains(moduleName)) { + Fatal() << "Module name " << moduleName + << " is listed more than once\n"; } - currModule = name; + currModule = moduleName; moduleNameSet.insert(currModule); config.secondaryNames.push_back(currModule); config.secondaryFuncs.emplace_back(std::set()); currFuncs = &config.secondaryFuncs.back(); newSection = false; - continue; - } - assert(currFuncs); - if (!canSplitFunc(name, wasm, options)) { - continue; - } - currFuncs->insert(name); - auto [it, inserted] = funcModules.insert({name, currModule}); - if (!inserted && it->second != currModule) { - Fatal() << "Function " << name << "cannot be assigned to module " - << currModule << "; it is already assigned to module " - << it->second << '\n'; + } else if (line.empty()) { + newSection = true; + if (currFuncs->empty() && !options.quiet) { + std::cerr << "warning: Module " << currModule << " will be empty\n"; + } + } else { + assert(currFuncs); + Name funcName = line; + if (canSplitFunc(funcName, wasm, options)) { + currFuncs->insert(funcName); + auto [it, inserted] = funcModules.try_emplace(funcName, currModule); + if (!inserted && it->second != currModule) { + Fatal() << "Function " << funcName << " cannot be assigned to module " + << currModule << "; it is already assigned to module " + << it->second << '\n'; + } + } } } diff --git a/test/lit/wasm-split/multi-split-errors.wast b/test/lit/wasm-split/multi-split-errors.wast new file mode 100644 index 00000000000..80ebc9e9d6a --- /dev/null +++ b/test/lit/wasm-split/multi-split-errors.wast @@ -0,0 +1,53 @@ +;; Check that a manifest starting with a blank line produces an error rather +;; than crashing. +;; RUN: echo "" > %t.blank.manifest +;; RUN: echo "1:" >> %t.blank.manifest +;; RUN: echo "foo" >> %t.blank.manifest +;; RUN: not wasm-split --multi-split %s --manifest %t.blank.manifest --out-prefix=%t -o %t.wasm 2>&1 \ +;; RUN: | filecheck %s --check-prefix=EMPTY-NAME + +;; Also check a module name consisting only of a colon. +;; RUN: echo ":" > %t.colon.manifest +;; RUN: echo "foo" >> %t.colon.manifest +;; RUN: not wasm-split --multi-split %s --manifest %t.colon.manifest --out-prefix=%t -o %t.wasm 2>&1 \ +;; RUN: | filecheck %s --check-prefix=EMPTY-NAME + +;; Check that an empty module followed by two blank lines warns about the empty +;; module and then errors on the second blank line. +;; RUN: echo "1:" > %t.empty-mod.manifest +;; RUN: echo "" >> %t.empty-mod.manifest +;; RUN: echo "" >> %t.empty-mod.manifest +;; RUN: not wasm-split --multi-split %s --manifest %t.empty-mod.manifest --out-prefix=%t -o %t.wasm 2>&1 \ +;; RUN: | filecheck %s --check-prefix=EMPTY-MOD + +;; Check that duplicate module names are rejected. +;; RUN: echo "1:" > %t.dup-mod.manifest +;; RUN: echo "foo" >> %t.dup-mod.manifest +;; RUN: echo "" >> %t.dup-mod.manifest +;; RUN: echo "1:" >> %t.dup-mod.manifest +;; RUN: echo "bar" >> %t.dup-mod.manifest +;; RUN: not wasm-split --multi-split %s --manifest %t.dup-mod.manifest --out-prefix=%t -o %t.wasm 2>&1 \ +;; RUN: | filecheck %s --check-prefix=DUP-MOD + +;; Check that assigning the same function to two modules is rejected. +;; RUN: echo "1:" > %t.dup-func.manifest +;; RUN: echo "foo" >> %t.dup-func.manifest +;; RUN: echo "" >> %t.dup-func.manifest +;; RUN: echo "2:" >> %t.dup-func.manifest +;; RUN: echo "foo" >> %t.dup-func.manifest +;; RUN: not wasm-split --multi-split %s --manifest %t.dup-func.manifest --out-prefix=%t -o %t.wasm 2>&1 \ +;; RUN: | filecheck %s --check-prefix=DUP-FUNC + +;; EMPTY-NAME: Fatal: Module name is empty + +;; EMPTY-MOD: warning: Module 1 will be empty +;; EMPTY-MOD: Fatal: Module name is empty + +;; DUP-MOD: Fatal: Module name 1 is listed more than once + +;; DUP-FUNC: Fatal: Function foo cannot be assigned to module 2; it is already assigned to module 1 + +(module + (func $foo) + (func $bar) +)