GCC11 issue: -Werror=free-nonheap-object causes build failure

Initially reported at: More GCC11 issues? -Werror=free-nonheap-object causes surge-fx build to fail · Issue #4251 · surge-synthesizer/surge · GitHub

Building Surge-FX with GCC11 (-Werror) & JUCE-6.0.8 on Fedora 34 fails. Example:

/builddir/build/BUILD/surge/libs/juce-6.0.8/juce/modules/juce_core/text/juce_String.cpp:164:52: error: 'void operator delete ’ called on unallocated object ‘juce::emptyString’ [-Werror=free-nonheap-object]
164 | delete reinterpret_cast<char*> (b);

The build log contains more lines than I’m allowed to post here but it’s attached in the github issue referenced above.

The solution (credit baconpaul) to prevent the build failure in surge was adding -Wno-free-nonheap-object
See Add -Wno-free-nonheap-object to prevent build failure with GCC11 by plaimbock · Pull Request #4254 · surge-synthesizer/surge · GitHub

I’ve tried building JUCE with g++ 11.0.1 20210416 (experimental) and -Wfree-nonheap-object but I can’t reproduce the warning. Perhaps it has been fixed in the compiler.

Thanks that’s good to know. The GCC11 version I had in Fedora 34 beta seems from March. But I do see a version 11.0.1 that will become available as an update when Fedora 34 is released. So let’s hope you are right and that this issue has been fixed in 11.0.1.

you need to build with -flto to get this warning message. I still see this warning with gcc 11.2 and 5.4.7

It needed -flto and -01 or higher.

Unfortunately I don’t think we can work around this in the source code:

you can:

so i suggest:

static void no_delete_string(char* a) {}
static void delete_string(char* a) { delete[] a; }

static inline void release (StringHolder* const b) noexcept
{
    void (*deleter)(char*) = isEmptyString (b) ? &no_delete_string : &delete_string;
    if (! isEmptyString (b))
        if (--(b->refCount) == -1)
            deleter(reinterpret_cast<char*> (b));
}

Nice find.

I think we’ll fix this by changing the underlying empty string check to use the address of a constexpr static instead, but this will need a bit more testing.

1 Like