We got an unexpected "visibility attribute not supported in this configuration" warning when compiling for mingw with LTO enabled. (Downstream bug: https://github.com/bitcoin-core/secp256k1/issues/1421) Here's a minimal test case: $ cat a.b __attribute__ ((visibility("default"))) void a(void) {} $ cat b.c void a(void); int main(void) { a(); } $ x86_64-w64-mingw32-gcc -flto=2 -flto-partition=max a.c b.c a.c: In function ‘a’: a.c:1:55: warning: visibility attribute not supported in this configuration; ignored [-Wattributes] 1 | __attribute__ ((visibility("default"))) void a(void) {} | I believe that the emitted warning reveals a bug. The attribute should be supported. The manual claims "Default visibility is supported everywhere.", see https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Common-Function-Attributes.html . It may be correct that the attribute has no effect, but then GCC should not warn about it. When running without -flto or with -flto-partition=1to1, the warning disappears. Note that -flto-partition=max is necessary to reproduce this in this minimal test case. When we encountered the bug in the wild, we got the warning even with the default -flto-partition=balanced, but like here, it disappeared with -flto-partition=1to1. The only other relevant bug I could find is bug 71286, but that seems to be a different issue. $ x86_64-w64-mingw32-gcc -v Using built-in specs. COLLECT_GCC=x86_64-w64-mingw32-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-w64-mingw32/13.1.0/lto-wrapper Target: x86_64-w64-mingw32 Configured with: /build/mingw-w64-gcc/src/gcc/configure --prefix=/usr --libexecdir=/usr/lib --target=x86_64-w64-mingw32 --with-bugurl=https://bugs.archlinux.org/ --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-shared --enable-static --enable-threads=posix --enable-fully-dynamic-string --enable-libstdcxx-time=yes --enable-libstdcxx-filesystem-ts=yes --with-system-zlib --enable-cloog-backend=isl --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-sjlj-exceptions --with-dwarf2 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 13.1.0 (GCC)
We emit the diagnostic from both i386_pe_assemble_visibility and default_assemble_visibility (if !HAVE_GAS_HIDDEN). I suspect that what happens is that LTO demotes 'a' to be local thus 'default' now has an effect. Testing on x86-64 with -flto-partition=1to1 shows a/0 (a) Type: function definition analyzed Visibility: force_output semantic_interposition no_reorder prevailing_def_ironly note the missing externally_visible. It's LTRANS unit then has a/0 (a) Type: function definition analyzed Visibility: used_from_other_partition force_output no_reorder prevailing_def_ironly public visibility_specified visibility:hidden and we seem to ignore the 'default' visibility attribute on it. I do not have any access to a mingw toolchain to see how we arrive at a diagnostic there but adding -fdump-ipa-all-details -save-temps should get you .000i.graph and 081i.whole-program dumps you can cross-check this against the above. I think the desired behavior (on x86-64 as well) is to have 'a' have default visibility in the output, not hidden as it currently happens on x86-64-linux. When processing a visibility attribute we adjust DECL_VISIBILITY and DECL_VISIBILITY_SPECIFIED but we also add the attribute because /* Go ahead and attach the attribute to the node as well. This is needed so we can determine whether we have VISIBILITY_DEFAULT because the visibility was not specified, or because it was explicitly overridden from the containing scope. */ (it seems that DECL_VISIBILITY_SPECIFIED could be used for this) Honza?