https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116361

            Bug ID: 116361
           Summary: lto1: fatal error: multiple prevailing defs when using
                    both LTO and OpenMP named critical sections
           Product: gcc
           Version: 14.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: lto
          Assignee: unassigned at gcc dot gnu.org
          Reporter: du.paul136 at gmail dot com
  Target Milestone: ---

Created attachment 58925
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58925&action=edit
Sources

Hi, I have a minimal reproducible example:

$ cat lib.h 
#ifndef LIB_H
#define LIB_H

void fun();
void fun2();

#endif // LIB_H

$ cat lib.c
#include "lib.h"

void fun()
{
    int i;
    #pragma omp critical(mysection)
    i = 0;
}

void fun2()
{

}

$ cat exec.c
int main()
{
    int a;
    #pragma omp critical(mysection)
    a = 0;
    return 0;
}

$ make      
gcc -flto -fopenmp -o lib.o -c lib.c
ar cr lib.a lib.o
gcc -flto -fopenmp -o exec.o -c exec.c
gcc -flto -fopenmp exec.o lib.a lib.a -o exec
lto1: fatal error: multiple prevailing defs for 'fun2'
compilation terminated.
lto-wrapper: fatal error: gcc returned 1 exit status
compilation terminated.
/usr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
make: *** [Makefile:7: exec] Error 1

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure
--enable-languages=ada,c,c++,d,fortran,go,lto,m2,objc,obj-c++,rust
--enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib
--mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues
--with-build-config=bootstrap-lto --with-linker-hash-style=gnu
--with-system-zlib --enable-__cxa_atexit --enable-cet=auto
--enable-checking=release --enable-clocale=gnu --enable-default-pie
--enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object
--enable-libstdcxx-backtrace --enable-link-serialization=1
--enable-linker-build-id --enable-lto --enable-multilib --enable-plugin
--enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.1.1 20240720 (GCC)

I'm on ArchLinux x86_64 but I also tested with different GCC version from 8 to
14 with the official Docker image but I have the same error.

Compiling with -Wall -Wextra only complains for unused variables.
Compiling with fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations
doesn't change anything.

It works if I do one of the following:
- I remove the -flto option
- I remove -fopenmp option
- I remove the critical section in lib.c or give them different names or no
names
- I include lib.h in exec.c and call one of the two functions of lib.c
somewhere in exec.c.

If I add more functions in lib.c, the error will point out the last one (and
not necessarily the one with the critical section).

At linking time, lib.a is added two times because for my real use case, which
is in C++ with CMake, CMake can put the same .a multiple times to resolve all
the dependencies.

With this minimal example, the following CMakeLists.txt can trigger the error:

$ cat empty.c  

$ cat CMakeLists.txt 
cmake_minimum_required(VERSION 3.16.3)

project(test
        DESCRIPTION "test"
        LANGUAGES C)

include(CheckIPOSupported)
check_ipo_supported()
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)

find_package(OpenMP REQUIRED C)

add_library(lib STATIC
    lib.c
    lib.h
)
target_link_libraries(lib
    PUBLIC
        OpenMP::OpenMP_C
)

add_library(libA STATIC
    empty.c
)
target_link_libraries(libA
    PRIVATE
        lib
)

add_library(libB STATIC
    empty.c
)
target_link_libraries(libB
    PRIVATE
        libA
        lib
)

add_executable(exec exec.c)
target_link_libraries(exec PRIVATE
    libB
    lib
)

For example, lib would be an utility library needed by every targets so it
makes sense to include it, but it can contains several .o and not all of them
would be used by every targets, but the unused .o with the named critical
section would trigger the error.

For convenience, I also send a tarball with contains all the mentioned files
and a Makefile.

Thank you for your time.

Reply via email to