[prev in list] [next in list] [prev in thread] [next in thread]
List: cfe-dev
Subject: Re: [cfe-dev] Adding support for multiple non-virtual inheritance for -cxx-abi microsoft
From: John McCall <rjmccall () apple ! com>
Date: 2013-04-09 1:06:02
Message-ID: DDD5F398-AB22-45BE-BE35-5F552F7F0ADA () apple ! com
[Download RAW message or body]
[Attachment #2 (multipart/alternative)]
On Apr 8, 2013, at 5:47 PM, Richard Smith <richard@metafoo.co.uk> wrote:
> On Mon, Apr 8, 2013 at 5:27 PM, John McCall <rjmccall@apple.com> wrote:
> On Apr 8, 2013, at 5:24 PM, Richard Smith <richard@metafoo.co.uk> wrote:
> > On Mon, Apr 8, 2013 at 11:33 AM, John McCall <rjmccall@apple.com> wrote:
> > On Apr 8, 2013, at 11:08 AM, Reid Kleckner <rnk@google.com> wrote:
> > > On Mon, Apr 8, 2013 at 2:02 PM, Timur Iskhodzhanov <timurrrr@google.com> wrote:
> > > > 2013/4/8 John McCall <rjmccall@apple.com>:
> > > > > I also find it curious that MSVC uses a thunk for member pointers, since
> > > > > the required this-adjustment is already plainly expressible in the member
> > > > > pointer value.
> > > > Me too actually.
> > > > Reid, wdyt?
> > >
> > > I think it allows them to avoid the union between non-virtual methods
> > > and virtual methods. Seems a bit cleaner and more obvious to me, but
> > > it has tradeoffs in terms of code size at the call site and the number
> > > of conditional vs. indirect branches that you have to do:
> > > indirect to thunk and indirect through vtable, vs conditional between
> > > two indirect calls
> >
> > Oh, does MSVC not do the union thing? They always make a thunk to do
> > the virtual call?
> >
> > If so, this "thunk" is potentially quite a bit more than just a thunk — it may
> > actually have ABI pointer-equality requirements on it for e.g. member
> > pointer equality tests.
> >
> > I don't believe there's any need for that -- comparisons on pointers to virtual \
> > member functions produce unspecified results (see [expr.eq]p2, second-last \
> > sentence).
>
> Oh, interesting. I guess Itanium made it work because it fell out easily enough to \
> do so.
> Even on Itanium, it (arguably) doesn't always work:
>
> struct A { virtual void f() = 0; };
> struct B { virtual void f() = 0; };
> struct C : A, B { virtual void f(); };
> void (C::*af)() = &A::f;
> void (C::*bf)() = &B::f;
> int main() { return af == bf; } // returns 0
True, although under this definition of "same member" you would presumably expect \
&A::f to be (indirectly) convertible to type 'void (B::*)()' and then be validly \
dereferenced on an object of a dynamic type that didn't include A. We could actually \
make that work, but only by emitting an obscene amount of code for member \
conversions. :)
Also, I don't think your example needs to be even that complex; you could probably \
just compare &B::f (offset sizeof(void*) when converted into C) against &C::f (offset \
zero). Any sort of repeat declaration will screw it up. But Itanium *will* succeed \
if you start with the address of the same *declaration*.
At any rate, it'd be interesting to know to what extent MSVC does try to make this \
work: absent any conversion, do member pointers for the same virtual member fail to \
compare equal:
- if produced at different times from the same expression? (pretty unlikely)
- if produced at different times from different instantiations of the same \
expression? (also pretty unlikely)
- if produced from different expressions within the same translation unit?
- if produced from different translation units within the same linkage unit?
You could get all the way out to the last pretty easily by just emitting the thunk \
with a well-defined mangling and weak linkage.
John.
[Attachment #5 (text/html)]
<html><head><meta http-equiv="Content-Type" content="text/html \
charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: \
space; -webkit-line-break: after-white-space; "><div><div>On Apr 8, 2013, at 5:47 PM, \
Richard Smith <<a \
href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> \
wrote:</div><blockquote type="cite"><div dir="ltr">On Mon, Apr 8, 2013 at 5:27 PM, \
John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" \
target="_blank">rjmccall@apple.com</a>></span> wrote:<br><div \
class="gmail_extra"><div class="gmail_quote"> <blockquote class="gmail_quote" \
style="margin:0px 0px 0px \
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div \
style="word-wrap:break-word"><div><div class="h5"><div> <div>On Apr 8, 2013, at 5:24 \
PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" \
target="_blank">richard@metafoo.co.uk</a>> wrote:</div><blockquote \
type="cite"><div dir="ltr">On Mon, Apr 8, 2013 at 11:33 AM, John McCall <span \
dir="ltr"><<a href="mailto:rjmccall@apple.com" \
target="_blank">rjmccall@apple.com</a>></span> wrote:<br> <div \
class="gmail_extra"><div class="gmail_quote"> <blockquote class="gmail_quote" \
style="margin:0px 0px 0px \
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>On \
Apr 8, 2013, at 11:08 AM, Reid Kleckner <<a href="mailto:rnk@google.com" \
target="_blank">rnk@google.com</a>> wrote:<br>
> On Mon, Apr 8, 2013 at 2:02 PM, Timur Iskhodzhanov <<a \
href="mailto:timurrrr@google.com" target="_blank">timurrrr@google.com</a>> \
wrote:<br> >> 2013/4/8 John McCall <<a href="mailto:rjmccall@apple.com" \
target="_blank">rjmccall@apple.com</a>>:<br> >>> I also find it curious \
that MSVC uses a thunk for member pointers, since<br> >>> the required \
this-adjustment is already plainly expressible in the member<br> >>> pointer \
value.<br> >> Me too actually.<br>
>> Reid, wdyt?<br>
><br>
> I think it allows them to avoid the union between non-virtual methods<br>
> and virtual methods. Seems a bit cleaner and more obvious to me, but<br>
> it has tradeoffs in terms of code size at the call site and the number<br>
> of conditional vs. indirect branches that you have to do:<br>
> indirect to thunk and indirect through vtable, vs conditional between<br>
> two indirect calls<br>
<br>
</div>Oh, does MSVC not do the union thing? They always make a thunk to do<br>
the virtual call?<br>
<br>
If so, this "thunk" is potentially quite a bit more than just a thunk — it may<br>
actually have ABI pointer-equality requirements on it for e.g. member<br>
pointer equality tests.<br></blockquote><div> </div><div>I don't believe there's \
any need for that -- comparisons on pointers to virtual member functions produce \
unspecified results (see [expr.eq]p2, second-last sentence).</div>
</div></div></div>
</blockquote></div><br></div></div><div>Oh, interesting. I guess Itanium made \
it work because it fell out easily enough to do \
so.</div></div></blockquote><div><br></div><div style="">Even on Itanium, it \
(arguably) doesn't always work:</div> <div style=""><div><br></div><div>struct A { \
virtual void f() = 0; };</div><div>struct B { virtual void f() = 0; \
};</div><div>struct C : A, B { virtual void f(); };</div><div>void (C::*af)() = \
&A::f;</div><div>void (C::*bf)() = &B::f;</div> <div style="">int main() { \
return af == bf; } // returns 0</div></div></div></div></div> \
</blockquote></div><br><div>True, although under this definition of "same member" you \
would presumably expect &A::f to be (indirectly) convertible to type 'void \
(B::*)()' and then be validly dereferenced on an object of a dynamic type that didn't \
include A. We could actually make that work, but only by emitting an obscene \
amount of code for member conversions. :)</div><div><br></div><div>Also, I don't \
think your example needs to be even that complex; you could probably just \
compare &B::f (offset sizeof(void*) when converted into C) against &C::f \
(offset zero). Any sort of repeat declaration will screw it up. But \
Itanium *will* succeed if you start with the address of the same \
*declaration*.</div><div><br></div><div>At any rate, it'd be interesting to know to \
what extent MSVC does try to make this work: absent any conversion, do member \
pointers for the same virtual member fail to compare equal:</div><div> - if \
produced at different times from the same expression? (pretty \
unlikely)</div><div> - if produced at different times from different \
instantiations of the same expression? (also pretty unlikely)</div><div> - if \
produced from different expressions within the same translation \
unit?</div><div> - if produced from different translation units within the same \
linkage unit?</div><div><br></div><div>You could get all the way out to the last \
pretty easily by just emitting the thunk with a well-defined mangling and weak \
linkage.</div><div><br></div><div>John.</div></body></html>
_______________________________________________
cfe-dev mailing list
cfe-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic