[llvm-bugs] [Bug 39680] New: Clang doesn't mix static and dynamic initialization of objects

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Nov 15 12:57:57 PST 2018


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

            Bug ID: 39680
           Summary: Clang doesn't mix static and dynamic initialization of
                    objects
           Product: clang
           Version: unspecified
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: dmajor at mozilla.com
                CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org,
                    neeilans at live.com, richard-llvm at metafoo.co.uk

When a global is initialized with compile-time values but does non-constexpr
work in its constructor, MSVC will bake the compile-time values into the object
to minimize the runtime work.

Clang sets all the fields in the constructor. This can lead to lengthy static
initializers when the objects are large or numerous:
https://bugzilla.mozilla.org/show_bug.cgi?id=1506763

// ------------------------------------------------------------------

void (*Log)(void*);

struct Entry
{
    Entry(int _a, int _b, int _c, int _d)
     : a(_a), b(_b), c(_c), d(_d)
    {
       Log(this);
    }

    int a, b, c, d;
};

static const Entry myentry { 0, 1, 2, 3 };

int main(int argc, char** argv)
{
  return myentry.a;
}

// ------------------------------------------------------------------

> cl -Z7 -O2 -c x.cpp 
> link -debug x.obj

The members are already populated at load time:

0:000> dx -r1 (*((x!Entry *)0x14007f000))
(*((x!Entry *)0x14007f000))                 [Type: Entry]
    [+0x000] a                : 0 [Type: int]
    [+0x004] b                : 1 [Type: int]
    [+0x008] c                : 2 [Type: int]
    [+0x00c] d                : 3 [Type: int]

So the initializer only needs to do:

00000001`40006bb0 488d0d49840700  lea     rcx,[x!myentry (00000001`4007f000)]
00000001`40006bb7 48ff2562930700  jmp     qword ptr [x!Log (00000001`4007ff20)]

But on clang, the members are zero at process load:

> clang-cl -Z7 -O2 -c x.cpp 
> lld-link -debug x.obj 

0:000> dx -r1 (*((x!Entry *)0x14005eac0))
(*((x!Entry *)0x14005eac0))                 [Type: Entry]
    [+0x000] a                : 0 [Type: int]
    [+0x004] b                : 0 [Type: int]
    [+0x008] c                : 0 [Type: int]
    [+0x00c] d                : 0 [Type: int]

And the initializer writes the data manually:

00000001`40001014 0f2805e5bf0400  movaps  xmm0,xmmword ptr [x!_xmm
(00000001`4004d000)]
00000001`4000101b 0f29059eda0500  movaps  xmmword ptr [x!myentry
(00000001`4005eac0)],xmm0
00000001`40001022 488d0d97da0500  lea     rcx,[x!myentry (00000001`4005eac0)]
00000001`40001029 ff1581da0500    call    qword ptr [x!Log (00000001`4005eab0)]

-- 
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/20181115/b4485c89/attachment.html>


More information about the llvm-bugs mailing list