bughunt: extract a call sequence leading to a strange init error with Clang
Observations:
- the initial observation was that we get two instances of the config rules service
- obviously this it is *not* the initialisation of a static variable accessed from
multiple compilation units. But the access from two compilation units is crucial
- we can exclude the effect of all other initialisation. It *is* in SingletonSubclass
- we can exclude the effect of dynamic linking. Even two translation units
linked statically exhibit the same problem
rebuild this test case in the research area, to be able to verify with various compilers
This commit is contained in:
parent
4f698f1bbb
commit
cec78fdc58
3 changed files with 118 additions and 0 deletions
38
research/clang-static-init-1.cpp
Normal file
38
research/clang-static-init-1.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include "lib/test/run.hpp"
|
||||
#include "proc/hh.hpp"
|
||||
|
||||
#include "proc/config-resolver.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using proc::ConfigResolver;
|
||||
|
||||
using ::test::Test;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
namespace proc {
|
||||
namespace test {
|
||||
|
||||
class StaticInstance_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
ConfigResolver& ref1 = ConfigResolver::instance();
|
||||
|
||||
ConfigResolver& sub2 = fabricate();
|
||||
|
||||
cout << "sub1="<< &ref1 << " sub2="<< &sub2 <<"\n";
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (StaticInstance_test, "unit bug");
|
||||
|
||||
|
||||
|
||||
}} // namespace proc::test
|
||||
36
research/clang-static-init-2.cpp
Normal file
36
research/clang-static-init-2.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include "proc/hh.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using proc::ConfigResolver;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
namespace proc {
|
||||
namespace test {
|
||||
|
||||
|
||||
int Subject::cnt = 0;
|
||||
|
||||
Subject::Subject()
|
||||
{
|
||||
++cnt;
|
||||
std::cout << "Subject("<<cnt<<")\n";
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
Holder<Subject> fab2;
|
||||
}
|
||||
|
||||
|
||||
ConfigResolver&
|
||||
fabricate()
|
||||
{
|
||||
return ConfigResolver::instance();
|
||||
}
|
||||
|
||||
|
||||
}} // namespace proc::test
|
||||
44
research/clang-static-init.hpp
Normal file
44
research/clang-static-init.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
|
||||
#include "proc/config-resolver.hpp"
|
||||
|
||||
namespace proc {
|
||||
namespace test {
|
||||
|
||||
template<typename T>
|
||||
struct Holder
|
||||
{
|
||||
static T* instance;
|
||||
|
||||
T&
|
||||
get()
|
||||
{
|
||||
if (!instance)
|
||||
{
|
||||
instance = new T();
|
||||
}
|
||||
return *instance;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
T* Holder<T>::instance;
|
||||
|
||||
struct Subject
|
||||
{
|
||||
static int cnt;
|
||||
|
||||
Subject();
|
||||
|
||||
};
|
||||
|
||||
|
||||
proc::ConfigResolver& fabricate();
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace proc::test
|
||||
|
||||
Loading…
Reference in a new issue