Closed peterazmanov closed 6 years ago
Deciding whether to emit template instantiation-related symbols with cached includes is a very complex problem. Boost had already provided zapcc lots of good tests in tools/clang/test/zapcc/multi
, this is probably another... this example will need to be completely c-reduced first, will look into this.
Could you c-reduce (https://embed.cs.utah.edu/creduce) this example code to independent header and source files? final version would be few lines each, similar to https://github.com/yrnkrn/zapcc/tree/master/tools/clang/test/zapcc/multi/template-function-local-var also reduced from Boost. Thanks!
I managed to reduce (with the help of creduce) the test to the following: zapcc_test_reduced.zip
reduced_boost.h:
#pragma once
template <class A, class B>
void void_cast_register() __attribute__ ((__used__));
template <class A, class B>
void void_cast_register()
{
(void)dynamic_cast<A *>((B *)nullptr);
}
a.h:
#pragma once
struct B
{
virtual ~B() = default;
};
struct A : B
{
~A();
};
a.cpp:
#include "a.h"
#include "reduced_boost.h"
A::~A()
{
void_cast_register<A, B>();
}
main.cpp:
#include "reduced_boost.h"
int main()
{}
Nice & clean reduce, looking at the problem.
https://guides.github.com/features/mastering-markdown/ 12.zip
Normalized to our usual test script.
Fix reduced + new LIT test in 194583e73b0dde257b49f41426c5bc66229baba5. If original problem still persists, please open a new issue.
Fix solved the problem. Checked both reduced and non-reduced versions.
Linker fails with "multiple definition of ..." when compiling code that uses Boost.Serialization.
Steps to reproduce:
zapcc_test.zip
bin
subdirectorycd bin
CC=zapcc CXX=zapcc++ cmake ..
make
Output:
System:
Linux archlinux 4.17.2-1-ARCH #1 SMP PREEMPT Sat Jun 16 11:08:59 UTC 2018 x86_64 GNU/Linux
ZapCC is built from commit 01ff39e6e0278432e562987ebf8a5a99869cd747 (2018.06.21) Boost version: 1.67.0The example compiles and links fine with Clang 5.0/6.0 and GCC 8.1.1
The problem occures when serializing polymorphic base class. This causes registration in internal singleton of Boost.Serialization. Somehow vtable-related symbols from previous translation units are included in subsequent unrelated translation units.
Example has the following structure:
a.h
contains definitions for baseclass B
andclass A
derived fromB
a.cpp
contains explicitly instantiated serialization method for classA
, its default constructor and destructor. Placement of constructor and destructor is crucial for example to fail as it causes symbols to be marked as 'global', otherwise they would be marked as 'weak' - multiple weak symbols are allowed by linkermain.cpp
contains emptymain
function andstruct C
with empty serialization. WithoutC
example compiles and links without errors.a.h:
a.cpp:
main.cpp:
zapcc_test.zip