From cec78fdc58b193ff70fc1c159c2c04e07e709dd4 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 29 Sep 2013 01:08:15 +0200 Subject: [PATCH] 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 --- research/clang-static-init-1.cpp | 38 +++++++++++++++++++++++++++ research/clang-static-init-2.cpp | 36 ++++++++++++++++++++++++++ research/clang-static-init.hpp | 44 ++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 research/clang-static-init-1.cpp create mode 100644 research/clang-static-init-2.cpp create mode 100644 research/clang-static-init.hpp diff --git a/research/clang-static-init-1.cpp b/research/clang-static-init-1.cpp new file mode 100644 index 000000000..c4869fd65 --- /dev/null +++ b/research/clang-static-init-1.cpp @@ -0,0 +1,38 @@ +#include "lib/test/run.hpp" +#include "proc/hh.hpp" + +#include "proc/config-resolver.hpp" + +#include + +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 diff --git a/research/clang-static-init-2.cpp b/research/clang-static-init-2.cpp new file mode 100644 index 000000000..ea107ee96 --- /dev/null +++ b/research/clang-static-init-2.cpp @@ -0,0 +1,36 @@ + +#include "proc/hh.hpp" + +#include + +using proc::ConfigResolver; +using std::cout; +using std::endl; + + +namespace proc { +namespace test { + + + int Subject::cnt = 0; + + Subject::Subject() + { + ++cnt; + std::cout << "Subject("< fab2; + } + + + ConfigResolver& + fabricate() + { + return ConfigResolver::instance(); + } + + +}} // namespace proc::test diff --git a/research/clang-static-init.hpp b/research/clang-static-init.hpp new file mode 100644 index 000000000..c27e5ddf7 --- /dev/null +++ b/research/clang-static-init.hpp @@ -0,0 +1,44 @@ + +#include "lib/error.hpp" + +#include "proc/config-resolver.hpp" + +namespace proc { +namespace test { + + template + struct Holder + { + static T* instance; + + T& + get() + { + if (!instance) + { + instance = new T(); + } + return *instance; + } + }; + + + template + T* Holder::instance; + + struct Subject + { + static int cnt; + + Subject(); + + }; + + + proc::ConfigResolver& fabricate(); + + + + +}} // namespace proc::test +