Date: Tue, 9 Jul 2024 15:33:06 +0100
On Tue, Jul 9, 2024 at 8:36 AM Frederick Virchanza Gotham wrote:
>
> I want to try code this. What compiler are you most interested in?
> VC++ / g++ / clang / icx ?
For the timebeing I'll go with GNU g++ on Linux x86_64. Starting out
with this code:
struct Base { virtual ~Base(){} };
struct Derived1 : Base { virtual ~Derived1(){} };
struct Derived2 : virtual Base { virtual ~Derived2(){} };
struct MostDerived : Derived1, virtual Derived2 {};
MostDerived *Caster(Base *const p)
{
return dynamic_cast<MostDerived*>(p);
}
I see that the function, 'Caster', gets compiled to:
test rdi, rdi
je Label
mov rcx, -1
mov edx, OFFSET FLAT:typeinfo for MostDerived
mov esi, OFFSET FLAT:typeinfo for Base
jmp __dynamic_cast
Label:
xor eax, eax
ret
Let's look at what's put in the registers:
RDI = Address of object
RSI = Address of type_info for base
RDX = Address of type_info for derived
RCX = -1
So it looks like "__dynamic_cast" is a function with four parameters
and a signature as follows:
void *__dynamic_cast(void *p, type_info const *base, type_info
const *derived, long long);
I did a search on Github just now and found the implementation here:
https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/dyncast.cc#L45
Scroll down to Line #89 and you'll see the comment:
// Both src and dst are known to be public bases of whole.
// Found a valid cross cast.
And if you scroll down to Line #101, you'll see:
// Found a valid down cast
So I reckon it's really just as simple as commenting out a few lines
in that function to achieve your 'dynamic_cast' that only does
downcasts.
>
> I want to try code this. What compiler are you most interested in?
> VC++ / g++ / clang / icx ?
For the timebeing I'll go with GNU g++ on Linux x86_64. Starting out
with this code:
struct Base { virtual ~Base(){} };
struct Derived1 : Base { virtual ~Derived1(){} };
struct Derived2 : virtual Base { virtual ~Derived2(){} };
struct MostDerived : Derived1, virtual Derived2 {};
MostDerived *Caster(Base *const p)
{
return dynamic_cast<MostDerived*>(p);
}
I see that the function, 'Caster', gets compiled to:
test rdi, rdi
je Label
mov rcx, -1
mov edx, OFFSET FLAT:typeinfo for MostDerived
mov esi, OFFSET FLAT:typeinfo for Base
jmp __dynamic_cast
Label:
xor eax, eax
ret
Let's look at what's put in the registers:
RDI = Address of object
RSI = Address of type_info for base
RDX = Address of type_info for derived
RCX = -1
So it looks like "__dynamic_cast" is a function with four parameters
and a signature as follows:
void *__dynamic_cast(void *p, type_info const *base, type_info
const *derived, long long);
I did a search on Github just now and found the implementation here:
https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/dyncast.cc#L45
Scroll down to Line #89 and you'll see the comment:
// Both src and dst are known to be public bases of whole.
// Found a valid cross cast.
And if you scroll down to Line #101, you'll see:
// Found a valid down cast
So I reckon it's really just as simple as commenting out a few lines
in that function to achieve your 'dynamic_cast' that only does
downcasts.
Received on 2024-07-09 14:33:19