public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/107932] New: weak constant char array not used correctly
@ 2022-11-30  8:19 bseifert at gmx dot at
  2022-11-30  8:22 ` [Bug c++/107932] " bseifert at gmx dot at
  2022-11-30  8:27 ` bseifert at gmx dot at
  0 siblings, 2 replies; 3+ messages in thread
From: bseifert at gmx dot at @ 2022-11-30  8:19 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 107932
           Summary: weak constant char array not used 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
-----------
#include <string>

struct A
{
   static const char* C1;
   static const char C2[];
   static const char C3[];

   static std::string get_C1();
   static std::string get_C2();
   static std::string get_C3();
};
-----------


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

std::string A::get_C1()
{
   return C1;
}

std::string A::get_C2()
{
   return C2;
}

std::string A::get_C3()
{
   return C3;
}

__attribute__((weak)) const char* A::C1 = "w";
__attribute__((weak)) const char A::C2[] = "w";
__attribute__((weak)) const char A::C3[] = "";
-----------

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

const char* A::C1 = "S";
const char A::C2[] = "S";
const char A::C3[] = "S";

int main()
{
   printf("'%s'\n", A::get_C1().data());
   printf("'%s'\n", A::get_C2().data());
   printf("'%s'\n", A::get_C3().data());
}
-----------

the constant char pointer C1 in A is defined weak in weak.cpp (pointing to the
char array "w"). constant char array C2 in A is defined weak in weak.cpp
(initialized to "w"). constant char array C3 in A is defined weak in weak.cpp
(initialized to "").

in main.cpp all these constants are defined strong and initilaized to /
pointing to "S". The getter methodes get_C1, get_C2 and get_C3 make std::string
out of the constants and return the string respectively.

it is expected that in all three cases the string "S" is returned.

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

it seems that the compilation of get_C3 is not done properly (wrongly
optimized) because the compiler seems to wrongly assume a fixed length of 0
even though the constant is attributed weak!

here is the assembly of the methods:

weak.lss
-----------
0000000000000000 <A::get_C1[abi:cxx11]()>:
   0:   f3 0f 1e fa             endbr64
   4:   41 56                   push   %r14
   6:   41 55                   push   %r13
   8:   41 54                   push   %r12
   a:   55                      push   %rbp
   b:   48 8d 6f 10             lea    0x10(%rdi),%rbp
   f:   48 83 ec 18             sub    $0x18,%rsp
  13:   4c 8b 35 00 00 00 00    mov    0x0(%rip),%r14        # 1a
<A::get_C1[abi:cxx11]()+0x1a>
  1a:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
  21:   00 00
  23:   48 89 44 24 08          mov    %rax,0x8(%rsp)
  28:   31 c0                   xor    %eax,%eax
  2a:   48 89 2f                mov    %rbp,(%rdi)
  2d:   4d 85 f6                test   %r14,%r14
  30:   0f 84 a2 00 00 00       je     d8 <A::get_C1[abi:cxx11]()+0xd8>
  36:   49 89 fc                mov    %rdi,%r12
  39:   4c 89 f7                mov    %r14,%rdi
  3c:   e8 00 00 00 00          callq  41 <A::get_C1[abi:cxx11]()+0x41>
  41:   48 89 04 24             mov    %rax,(%rsp)
  45:   49 89 c5                mov    %rax,%r13
  48:   48 83 f8 0f             cmp    $0xf,%rax
  4c:   77 52                   ja     a0 <A::get_C1[abi:cxx11]()+0xa0>
  4e:   48 83 f8 01             cmp    $0x1,%rax
  52:   75 3c                   jne    90 <A::get_C1[abi:cxx11]()+0x90>
  54:   41 0f b6 16             movzbl (%r14),%edx
  58:   41 88 54 24 10          mov    %dl,0x10(%r12)
  5d:   49 89 44 24 08          mov    %rax,0x8(%r12)
  62:   c6 44 05 00 00          movb   $0x0,0x0(%rbp,%rax,1)
  67:   48 8b 44 24 08          mov    0x8(%rsp),%rax
  6c:   64 48 33 04 25 28 00    xor    %fs:0x28,%rax
  73:   00 00
  75:   75 6d                   jne    e4 <A::get_C1[abi:cxx11]()+0xe4>
  77:   48 83 c4 18             add    $0x18,%rsp
  7b:   4c 89 e0                mov    %r12,%rax
  7e:   5d                      pop    %rbp
  7f:   41 5c                   pop    %r12
  81:   41 5d                   pop    %r13
  83:   41 5e                   pop    %r14
  85:   c3                      retq
  86:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  8d:   00 00 00
  90:   48 85 c0                test   %rax,%rax
  93:   74 c8                   je     5d <A::get_C1[abi:cxx11]()+0x5d>
  95:   eb 26                   jmp    bd <A::get_C1[abi:cxx11]()+0xbd>
  97:   66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
  9e:   00 00
  a0:   48 89 e6                mov    %rsp,%rsi
  a3:   31 d2                   xor    %edx,%edx
  a5:   4c 89 e7                mov    %r12,%rdi
  a8:   e8 00 00 00 00          callq  ad <A::get_C1[abi:cxx11]()+0xad>
  ad:   49 89 04 24             mov    %rax,(%r12)
  b1:   48 89 c5                mov    %rax,%rbp
  b4:   48 8b 04 24             mov    (%rsp),%rax
  b8:   49 89 44 24 10          mov    %rax,0x10(%r12)
  bd:   48 89 ef                mov    %rbp,%rdi
  c0:   4c 89 ea                mov    %r13,%rdx
  c3:   4c 89 f6                mov    %r14,%rsi
  c6:   e8 00 00 00 00          callq  cb <A::get_C1[abi:cxx11]()+0xcb>
  cb:   48 8b 04 24             mov    (%rsp),%rax
  cf:   49 8b 2c 24             mov    (%r12),%rbp
  d3:   eb 88                   jmp    5d <A::get_C1[abi:cxx11]()+0x5d>
  d5:   0f 1f 00                nopl   (%rax)
  d8:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # df
<A::get_C1[abi:cxx11]()+0xdf>
  df:   e8 00 00 00 00          callq  e4 <A::get_C1[abi:cxx11]()+0xe4>
  e4:   e8 00 00 00 00          callq  e9 <A::get_C1[abi:cxx11]()+0xe9>
  e9:   90                      nop
  ea:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

00000000000000f0 <A::get_C2[abi:cxx11]()>:
  f0:   f3 0f 1e fa             endbr64
  f4:   48 8d 47 10             lea    0x10(%rdi),%rax
  f8:   41 54                   push   %r12
  fa:   49 89 fc                mov    %rdi,%r12
  fd:   48 89 07                mov    %rax,(%rdi)
 100:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # 107
<A::get_C2[abi:cxx11]()+0x17>
 107:   e8 00 00 00 00          callq  10c <A::get_C2[abi:cxx11]()+0x1c>
 10c:   48 83 f8 01             cmp    $0x1,%rax
 110:   75 0c                   jne    11e <A::get_C2[abi:cxx11]()+0x2e>
 112:   0f b6 15 00 00 00 00    movzbl 0x0(%rip),%edx        # 119
<A::get_C2[abi:cxx11]()+0x29>
 119:   41 88 54 24 10          mov    %dl,0x10(%r12)
 11e:   49 89 44 24 08          mov    %rax,0x8(%r12)
 123:   41 c6 44 04 10 00       movb   $0x0,0x10(%r12,%rax,1)
 129:   4c 89 e0                mov    %r12,%rax
 12c:   41 5c                   pop    %r12
 12e:   c3                      retq
 12f:   90                      nop

0000000000000130 <A::get_C3[abi:cxx11]()>:
 130:   f3 0f 1e fa             endbr64
 134:   48 8d 57 10             lea    0x10(%rdi),%rdx
 138:   48 c7 47 08 00 00 00    movq   $0x0,0x8(%rdi)
 13f:   00
 140:   48 89 f8                mov    %rdi,%rax
 143:   48 89 17                mov    %rdx,(%rdi)
 146:   c6 47 10 00             movb   $0x0,0x10(%rdi)
 14a:   c3                      retq
-----------

Though the pointer should be used in all three cases to call the constructor of
std::string, the three constants are treated completely different. I cannot say
what the exact difference between get_C1 and get_C2 is in the implementation,
but definitely get_C3 is not correct.

it does not matter if the weak definitions in weak.cpp are before or after the
definition of the methods (in contrast to bug 107907)

even casting the constants, does not help:

-----------
std::string A::get_C1()
{
   return (const char*) C1;
}

std::string A::get_C2()
{
   return (const char*) C2;
}

std::string A::get_C3()
{
   return (const char*) C3;
}
-----------

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/107932] weak constant char array not used correctly
  2022-11-30  8:19 [Bug c++/107932] New: weak constant char array not used correctly bseifert at gmx dot at
@ 2022-11-30  8:22 ` bseifert at gmx dot at
  2022-11-30  8:27 ` bseifert at gmx dot at
  1 sibling, 0 replies; 3+ messages in thread
From: bseifert at gmx dot at @ 2022-11-30  8:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Berni <bseifert at gmx dot at> ---
potentially related to bug 107907

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/107932] weak constant char array not used correctly
  2022-11-30  8:19 [Bug c++/107932] New: weak constant char array not used correctly bseifert at gmx dot at
  2022-11-30  8:22 ` [Bug c++/107932] " bseifert at gmx dot at
@ 2022-11-30  8:27 ` bseifert at gmx dot at
  1 sibling, 0 replies; 3+ messages in thread
From: bseifert at gmx dot at @ 2022-11-30  8:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Berni <bseifert at gmx dot at> ---
added test case:
g++ -o test.exe -Os main.cpp weak.cpp
./test.exe
'S'
'S'
'S'

here the result is as expected!

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-11-30  8:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-30  8:19 [Bug c++/107932] New: weak constant char array not used correctly bseifert at gmx dot at
2022-11-30  8:22 ` [Bug c++/107932] " bseifert at gmx dot at
2022-11-30  8:27 ` bseifert at gmx dot at

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).