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).