https://bugs.llvm.org/show_bug.cgi?id=36952
Bug ID: 36952
Summary: [MS] Clang fails to emit vftable adjustor thunks when
parameter types are incomplete
Product: clang
Version: unspecified
Hardware: PC
OS: Windows NT
Status: NEW
Severity: enhancement
Priority: P
Component: LLVM Codegen
Assignee: unassignedclangb...@nondot.org
Reporter: r...@google.com
CC: llvm-bugs@lists.llvm.org
Consider:
$ cat t.h
struct Incomplete;
struct A {
virtual void foo(Incomplete p) = 0;
};
struct B : virtual A {
void foo(Incomplete p) override;
};
struct C : B { int c; };
$ cat a.cpp
#include "t.h"
int main() { C c; }
$ cat b.cpp
#include "t.h"
struct Incomplete { void *p; };
void B::foo(Incomplete p) {}
This should produce a valid C++ program, but with clang we get link errors:
$ clang-cl -c a.cpp b.cpp && link -nologo a.obj b.obj -out:t.exe && ./t.exe
a.obj : error LNK2001: unresolved external symbol "[thunk]:public: virtual void
__cdecl B::foo`adjustor{8}' (struct Incomplete)"
(?foo@B@@W7EAAXUIncomplete@@@Z)
t.exe : fatal error LNK1120: 1 unresolved externals
Reduced from https://crbug.com/822202.
Here are the record layouts:
*** Dumping AST Record Layout
0 | struct B
0 | (B vbtable pointer)
8 | struct A (virtual base)
8 | (A vftable pointer)
| [sizeof=16, align=8,
| nvsize=8, nvalign=8]
*** Dumping AST Record Layout
0 | struct C
0 | struct B (base)
0 | (B vbtable pointer)
8 | int c
16 | struct A (virtual base)
16 | (A vftable pointer)
| [sizeof=24, align=8,
| nvsize=16, nvalign=8]
The primary definition of 'B::foo' hardcodes a -8 this adjustment, which
adjusts from A-in-B to the beginning of B.
A is a virtual base, so its location changes relative to B in C's layout. In
C's layout, the offset from A to B is -16, not -8.
C's vftable slot for 'foo' needs to use a thunk to do an additional 8 byte
adjustment so that -8 - 8 = -16, and B::foo's 'this' argument is correctly
positioned. That's where "adjustor{8}" symbol comes from.
So far, Clang implements all that stuff correctly.
The link error comes from the fact we don't have a definition for the
Incomplete struct in a.cpp, so we give up when attempting to emit the thunk
that does the adjustment. We don't emit an error because this code was
originally written to support available_externally vtables for Itanium, so it
was just an optimization, not a correctness issue.
The fix is probably to abuse musttail to emit a thunk without knowing the
prototype for the virtual method.
--
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs