[llvm-bugs] [Bug 39250] New: static construction order within translation unit, static data member of template class

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Oct 11 01:55:24 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=39250

            Bug ID: 39250
           Summary: static construction order within translation unit,
                    static data member of template class
           Product: clang
           Version: 7.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: cbcode at gmail.com
                CC: dgregor at apple.com, llvm-bugs at lists.llvm.org

Created attachment 20988
  --> https://bugs.llvm.org/attachment.cgi?id=20988&action=edit
test case

Within a single translation unit, static construction order is well defined, so
that the construction of classes appearing late in the source file should be
able to depend on the completed construction of static instances of classes
appearing early in the source file. It appears that in certain situations
static data members of template classes are statically constructed too early.

See a test case below and in the attachment.

Expected output is something like: 

a_int : 0x6b4bc8 0x6b4bc8
a_bool: 0x6b4bc0 0x6b4bc0
A_int(): 0x6b4bc8
A_bool(): 0x6b4bc0
C(): 0x6b4bc8
C(): 0x6b4bc0

Bad output:
C(): (nil)
C(): (nil)
a_int : 0x601050 0x601050
a_bool: 0x601058 0x601058
A_int(): 0x601050
A_bool(): 0x601058

For x86_64-unknown-linux-gnu I get bad output with:
7.0.0 (tags/RELEASE_700/final)
6.0.1 (tags/RELEASE_601/final)
5.0.2 (tags/RELEASE_502/final)
and earlier

Under windows with clang-cl, the problem appears for version 4.0 and earlier
but does not show up for 5.0 and later.

gcc or msvc generate correct output for all versions and platforms tested.

Test code:

#include <cstdio>

#pragma clang diagnostic ignored "-Wformat-pedantic"

struct A {
    virtual ~A() {}
    virtual void do_some_useful() {}
};
extern A const &a_int, &a_bool;
//goal: define struct B<T> such that &B<int>::a == &a_int and &B<bool>::a ==
&a_bool

template<typename> struct B {
    static A const& a;
};
template<> A const& B<int >::a = a_int;
template<> A const& B<bool>::a = a_bool;

static struct check { check() {
    std::printf("a_int : %p %p\n", &a_int,  &B<int >::a);
    std::printf("a_bool: %p %p\n", &a_bool, &B<bool>::a);
}} check;

struct A_int : A {
    A_int() { std::printf("A_int(): %p\n", this); }
} const a_int_inst;

struct A_bool : A {
    A_bool() { std::printf("A_bool(): %p\n", this); }
} const a_bool_inst;

A const &a_int = a_int_inst, &a_bool = a_bool_inst;

//Note: Everything happens within a single translation unit.
//Note: There is no reason anything below should be statically constructed
before anything above.

template<typename T> struct C {
    C() { std::printf("C(): %p\n", &B<T>::a); }
    static C const c;
};
template<typename T> C<T> const C<T>::c;

C<int > const& c_int  = C<int >::c;
C<bool> const& c_bool = C<bool>::c;

int main() {
    return 0;
}

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181011/de1c0c23/attachment-0001.html>


More information about the llvm-bugs mailing list