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

            Bug ID: 107907
           Summary: weak integer constant not linked correctly
           Product: gcc
           Version: 9.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bseifert at gmx dot at
  Target Milestone: ---

given the following files:

def.hpp
-----------
struct A
{
   static const int C;
   static int get_C();
};
-----------


weak.cpp
-----------
#include "def.hpp"

const int A::C __attribute__((weak)) = 1;

int A::get_C()
{
   return C;
}
-----------

main.cpp
-----------
#include <stdio.h>
#include "def.hpp"

const int A::C = 2;

int main()
{
   printf("%u\n", A::get_C());
}
-----------

the constant C in class A is defined weak in weak.cpp (to the value 1) and
defined strong in main.cpp (to the value 2).
it is expected that the static method get_C defined in weak.cpp is using the
strong symbol (value 2) but it uses the local definition of C regardless of the
weak attribute.

test case:
g++ -o test.exe -O2 main.cpp weak.cpp
./test.exe
1

then the file weak.cpp is replaced with file weak2.cpp (only difference is that
definition of C is AFTER the definition of get_C):

weak2.cpp
-----------
#include "def.hpp"

int A::get_C()
{
   return C;
}

const int A::C __attribute__((weak)) = 1;
-----------

test case:
g++ -o test.exe -O2 main.cpp weak2.cpp
./test.exe
2

it seems that the compilation of get_C is not done properly (wrongly optimized)
because the compiler should not directly use the value of a constant if the
constant is attributed weak!

here is the assembly of the methods get_C:

weak.lss
-----------
0000000000000000 <A::get_C()>:
   0:   f3 0f 1e fa             endbr64
   4:   b8 01 00 00 00          mov    $0x1,%eax
   9:   c3                      retq
-----------

weak2.lss
-----------
0000000000000000 <A::get_C()>:
   0:   f3 0f 1e fa             endbr64
   4:   8b 05 00 00 00 00       mov    0x0(%rip),%eax        # a
<A::get_C()+0xa>
   a:   c3                      retq
-----------

this clearly shows the direct use of the value of the constant in the first
case and the indirect loading of the value in the second case

Reply via email to