Skip to content

WITH_NORM=ON fails to build with gcc-14: pinned OpenFST assigns a raw pointer to unique_ptr #5

Description

@localai-bot

Building with -DNEMO_SPEECH_WITH_NORM=ON fails when the runtime is compiled with gcc-14:

.deps/itn/include/fst/fst.h:690:59: error: no match for 'operator=' (operand types are
  'std::unique_ptr<fst::SymbolTable, std::default_delete<fst::SymbolTable> >' and 'fst::SymbolTable*')
.deps/itn/include/fst/fst.h:691:59: error: (same, next line)
FAILED: src/common/CMakeFiles/nemo_speech_text_normalization.dir/text_normalization/fst_normalizer.cpp.o

Cause

scripts/build_itn_deps.sh pins https://github.com/sarane22/openfst.git at fc23b4cf529429284b874a26f28b15c6cc94f404. In that tree, FstImpl::operator= (src/include/fst/fst.h:690-691) is:

isymbols_ = impl.isymbols_ ? impl.isymbols_->Copy() : nullptr;
osymbols_ = impl.osymbols_ ? impl.osymbols_->Copy() : nullptr;

isymbols_ and osymbols_ are std::unique_ptr<SymbolTable>, while SymbolTable::Copy() is declared virtual SymbolTable *Copy() const (symbol-table.h:411). So the conditional yields SymbolTable * and the statement is unique_ptr<SymbolTable> = SymbolTable *.

std::unique_ptr has exactly three assignment operators: from unique_ptr&&, from a convertible unique_ptr<U,E>&&, and from nullptr_t. None accepts a raw pointer, in any C++ standard, so these two lines are ill-formed everywhere. The same class spells the identical operation correctly 78 lines later in SetInputSymbols (fst.h:768), using .reset(...), which suggests a plain typo.

It has gone unnoticed because nothing instantiates FstImpl::operator=, and compilers before gcc-14 defer the check. gcc-14 resolves non-dependent operator expressions at template definition time, so it rejects the line in any translation unit that merely includes the header. The diagnostic header confirms this:

fst.h: In member function 'fst::internal::FstImpl<Arc>& fst::internal::FstImpl<Arc>::operator=(const fst::internal::FstImpl<Arc>&)':

That is In member function, not In instantiation of ... required from here, and there is no instantiation backtrace.

Compiler reading fst.h Result
gcc-12 (what build_itn_deps.sh uses to build OpenFST) OK, check deferred
gcc-13 OK, check deferred
gcc-14 error at definition time

fst_normalizer.cpp is the only translation unit here that includes OpenFST, so it is the only one that breaks. Note this is not a mismatch between gcc-12-built artifacts and a gcc-14 compile: build_itn_deps.sh installs the headers with cp -a, so they are verbatim source.

Fix

isymbols_.reset(impl.isymbols_ ? impl.isymbols_->Copy() : nullptr);
osymbols_.reset(impl.osymbols_ ? impl.osymbols_->Copy() : nullptr);

That matches the existing spelling in SetInputSymbols and compiles on every version tested. Since the affected function is never instantiated, libfst.so cannot contain it, so there is no ABI or ODR consequence.

The fix belongs in the pinned sarane22/openfst fork, or the pin could move to a revision that already has it.

Context

Found while packaging NeMo-Speech.cpp as a backend for LocalAI (pin 2e12e2def8a98ed06666f7ee3ca94e7193e04be4), where the build image defaults to gcc-14. Reproduced standalone from a file whose entire content is #include <fst/fst.h>, compiled with gcc 14.2: exactly 2 errors, matching CI. Downstream we patch the two lines in the installed prefix before configuring.

Happy to send a PR to whichever repo is the right home for it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions