annotate lld/test/COFF/comdat-weak.test @ 192:d7606dcf6fce

Added tag llvm10 for changeset 0572611fdcc8
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 14 Dec 2020 18:01:34 +0900
parents 1d019706d866
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 RUN: lld-link -lldmingw %S/Inputs/inline-weak.o %S/Inputs/inline-weak2.o -out:%t.exe
anatofuz
parents:
diff changeset
2
anatofuz
parents:
diff changeset
3 When compiling certain forms of templated inline functions, some
anatofuz
parents:
diff changeset
4 versions of GCC (tested with 5.4) produces a weak symbol for the function.
anatofuz
parents:
diff changeset
5 Newer versions of GCC don't do this though.
anatofuz
parents:
diff changeset
6
anatofuz
parents:
diff changeset
7 The bundled object files are an example of that, they can be produced
anatofuz
parents:
diff changeset
8 with test code like this:
anatofuz
parents:
diff changeset
9
anatofuz
parents:
diff changeset
10 $ cat inline-weak.h
anatofuz
parents:
diff changeset
11 class MyClass {
anatofuz
parents:
diff changeset
12 public:
anatofuz
parents:
diff changeset
13 template<typename... _Args> int get(_Args&&... args) {
anatofuz
parents:
diff changeset
14 return a;
anatofuz
parents:
diff changeset
15 }
anatofuz
parents:
diff changeset
16 private:
anatofuz
parents:
diff changeset
17 int a;
anatofuz
parents:
diff changeset
18 };
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 $ cat inline-weak.cpp
anatofuz
parents:
diff changeset
21 #include "inline-weak.h"
anatofuz
parents:
diff changeset
22
anatofuz
parents:
diff changeset
23 int get(MyClass& a);
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 int main(int argc, char* argv[]) {
anatofuz
parents:
diff changeset
26 MyClass a;
anatofuz
parents:
diff changeset
27 int ret = a.get();
anatofuz
parents:
diff changeset
28 ret += get(a);
anatofuz
parents:
diff changeset
29 return ret;
anatofuz
parents:
diff changeset
30 }
anatofuz
parents:
diff changeset
31 extern "C" void mainCRTStartup(void) {
anatofuz
parents:
diff changeset
32 main(0, (char**)0);
anatofuz
parents:
diff changeset
33 }
anatofuz
parents:
diff changeset
34 extern "C" void __main(void) {
anatofuz
parents:
diff changeset
35 }
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 $ cat inline-weak2.cpp
anatofuz
parents:
diff changeset
38 #include "inline-weak.h"
anatofuz
parents:
diff changeset
39
anatofuz
parents:
diff changeset
40 int get(MyClass& a) {
anatofuz
parents:
diff changeset
41 return a.get();
anatofuz
parents:
diff changeset
42 }
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 $ x86_64-w64-mingw32-g++ -std=c++11 -c inline-weak.cpp
anatofuz
parents:
diff changeset
45 $ x86_64-w64-mingw32-g++ -std=c++11 -c inline-weak2.cpp
anatofuz
parents:
diff changeset
46
anatofuz
parents:
diff changeset
47 $ x86_64-w64-mingw32-nm inline-weak.o | grep MyClass3get
anatofuz
parents:
diff changeset
48 0000000000000000 p .pdata$_ZN7MyClass3getIJEEEiDpOT_
anatofuz
parents:
diff changeset
49 0000000000000000 t .text$_ZN7MyClass3getIJEEEiDpOT_
anatofuz
parents:
diff changeset
50 0000000000000000 T .weak._ZN7MyClass3getIIEEEiDpOT_.main
anatofuz
parents:
diff changeset
51 0000000000000000 r .xdata$_ZN7MyClass3getIJEEEiDpOT_
anatofuz
parents:
diff changeset
52 w _ZN7MyClass3getIIEEEiDpOT_
anatofuz
parents:
diff changeset
53 0000000000000000 T _ZN7MyClass3getIJEEEiDpOT_
anatofuz
parents:
diff changeset
54
anatofuz
parents:
diff changeset
55 $ x86_64-w64-mingw32-nm inline-weak2.o | grep MyClass3get
anatofuz
parents:
diff changeset
56 0000000000000000 p .pdata$_ZN7MyClass3getIJEEEiDpOT_
anatofuz
parents:
diff changeset
57 0000000000000000 t .text$_ZN7MyClass3getIJEEEiDpOT_
anatofuz
parents:
diff changeset
58 0000000000000000 T .weak._ZN7MyClass3getIIEEEiDpOT_._Z3getR7MyClass
anatofuz
parents:
diff changeset
59 0000000000000000 r .xdata$_ZN7MyClass3getIJEEEiDpOT_
anatofuz
parents:
diff changeset
60 w _ZN7MyClass3getIIEEEiDpOT_
anatofuz
parents:
diff changeset
61 0000000000000000 T _ZN7MyClass3getIJEEEiDpOT_
anatofuz
parents:
diff changeset
62
anatofuz
parents:
diff changeset
63 This can't be reproduced by assembling .s files with llvm-mc, since that
anatofuz
parents:
diff changeset
64 always produces a symbol named .weak.<weaksymbol>.default, therefore
anatofuz
parents:
diff changeset
65 the test uses prebuilt object files instead.
anatofuz
parents:
diff changeset
66
anatofuz
parents:
diff changeset
67 In these cases, the undefined weak symbol points to the regular symbol
anatofuz
parents:
diff changeset
68 .weak._ZN7MyClass3getIIEEEiDpOT_.<othersymbol>, where <othersymbol>
anatofuz
parents:
diff changeset
69 varies among the object files that emit the same function. This regular
anatofuz
parents:
diff changeset
70 symbol points to the same location as the comdat function
anatofuz
parents:
diff changeset
71 _ZN7MyClass3getIJEEEiDpOT_.
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 When linking, the comdat section from the second object file gets
anatofuz
parents:
diff changeset
74 discarded, as it matches the one that already exists. This means that
anatofuz
parents:
diff changeset
75 the uniquely named symbol .weak.<weakname>.<othername> points to a
anatofuz
parents:
diff changeset
76 discarded section chunk.
anatofuz
parents:
diff changeset
77
anatofuz
parents:
diff changeset
78 Previously, this would have triggered adding an Undefined symbol for
anatofuz
parents:
diff changeset
79 this case, which would later break linking. However, also previously,
anatofuz
parents:
diff changeset
80 if the second object file is linked in via a static library, this
anatofuz
parents:
diff changeset
81 leftover symbol is retained as a Lazy symbol, which would make the link
anatofuz
parents:
diff changeset
82 succeed.