clang_isDynamicCall always returns true for CallExpr which call virtual methods

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

clang_isDynamicCall always returns true for CallExpr which call virtual methods

Fangrui Song via cfe-dev

Hi,

 

I’m visiting the AST of this simple code with libclang:

class Base

{

    public:

        virtual void Print() {}

};

 

class Derived : public Base

{

    public:

        virtual void Print() {}

};

 

void func1( Base * b )

{

    b->Print();

}

 

void func2( Base b )

{

    b.Print();

}

 

void func3( Base & b )

{

    b.Print();

}

 

clang_isDynamicCall returns true for all three CallExpr cursors in the code.  I would have expected clang_isDynamicCall to return false for the call in func2 because the call is definitely to the Print method of Base.  Is this intended behaviour?  If yes, is there another way to determine whether the function call is going to be made polymorphically?

 

Thanks in advance,

Matt


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang_isDynamicCall always returns true for CallExpr which call virtual methods

Fangrui Song via cfe-dev

Hi,

 

Just resending.  If I am asking this question on the wrong mailing list, please le me know.

 

Thanks,

Matt

 

From: Matt Borges <[hidden email]>
Date: Friday, May 8, 2020 at 11:36 AM
To: "[hidden email]" <[hidden email]>
Subject: clang_isDynamicCall always returns true for CallExpr which call virtual methods

 

Hi,

 

I’m visiting the AST of this simple code with libclang:

class Base

{

    public:

        virtual void Print() {}

};

 

class Derived : public Base

{

    public:

        virtual void Print() {}

};

 

void func1( Base * b )

{

    b->Print();

}

 

void func2( Base b )

{

    b.Print();

}

 

void func3( Base & b )

{

    b.Print();

}

 

clang_isDynamicCall returns true for all three CallExpr cursors in the code.  I would have expected clang_isDynamicCall to return false for the call in func2 because the call is definitely to the Print method of Base.  Is this intended behaviour?  If yes, is there another way to determine whether the function call is going to be made polymorphically?

 

Thanks in advance,

Matt


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang_isDynamicCall always returns true for CallExpr which call virtual methods

Fangrui Song via cfe-dev
I guess that clang_isDynamicCall is not concerned with function calls that can be de-virtualised through optimisation (albeit fairly trivial optimisation).

I'm interested to know how you could, in general, find out when a method will be called polymorphically but would guess that it's very hard as cross-translation unit optimisation (WPO) would have an effect. Clang's AST won't have access ot the info needed to determine this (as far as I know).

Please keep me posted on progress!

Jon

On Fri, 15 May 2020 at 14:28, Borges, Matt via cfe-dev <[hidden email]> wrote:

Hi,

 

Just resending.  If I am asking this question on the wrong mailing list, please le me know.

 

Thanks,

Matt

 

From: Matt Borges <[hidden email]>
Date: Friday, May 8, 2020 at 11:36 AM
To: "[hidden email]" <[hidden email]>
Subject: clang_isDynamicCall always returns true for CallExpr which call virtual methods

 

Hi,

 

I’m visiting the AST of this simple code with libclang:

class Base

{

    public:

        virtual void Print() {}

};

 

class Derived : public Base

{

    public:

        virtual void Print() {}

};

 

void func1( Base * b )

{

    b->Print();

}

 

void func2( Base b )

{

    b.Print();

}

 

void func3( Base & b )

{

    b.Print();

}

 

clang_isDynamicCall returns true for all three CallExpr cursors in the code.  I would have expected clang_isDynamicCall to return false for the call in func2 because the call is definitely to the Print method of Base.  Is this intended behaviour?  If yes, is there another way to determine whether the function call is going to be made polymorphically?

 

Thanks in advance,

Matt

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: clang_isDynamicCall always returns true for CallExpr which call virtual methods

Fangrui Song via cfe-dev

I don’t think this has anything to do with optimization.  If the type of the member expression base is completely known, it isn’t a dynamic call. 

It seems that function (clang_Cursor_isDynamicCall is the one I found?) ends up calling MemberExpr->performsVirtualDispatch, which only considers AppleKext and full qualification.

 

I also note that the uses of performsVirtualDispatch calls getDevirutalizedMethod (https://clang.llvm.org/doxygen/DeclCXX_8cpp_source.html#l02107).

 

I presume “isDynamicCall” (or some similar function) should be checking whether it can be devirtualized like this before deciding it is a dynamic call.

 

 

From: cfe-dev <[hidden email]> On Behalf Of Jonathan Coe via cfe-dev
Sent: Friday, May 15, 2020 6:37 AM
To: Borges, Matt <[hidden email]>
Cc: [hidden email]
Subject: Re: [cfe-dev] clang_isDynamicCall always returns true for CallExpr which call virtual methods

 

I guess that clang_isDynamicCall is not concerned with function calls that can be de-virtualised through optimisation (albeit fairly trivial optimisation).

I'm interested to know how you could, in general, find out when a method will be called polymorphically but would guess that it's very hard as cross-translation unit optimisation (WPO) would have an effect. Clang's AST won't have access ot the info needed to determine this (as far as I know).

Please keep me posted on progress!

Jon

 

On Fri, 15 May 2020 at 14:28, Borges, Matt via cfe-dev <[hidden email]> wrote:

Hi,

 

Just resending.  If I am asking this question on the wrong mailing list, please le me know.

 

Thanks,

Matt

 

From: Matt Borges <[hidden email]>
Date: Friday, May 8, 2020 at 11:36 AM
To: "[hidden email]" <[hidden email]>
Subject: clang_isDynamicCall always returns true for CallExpr which call virtual methods

 

Hi,

 

I’m visiting the AST of this simple code with libclang:

class Base

{

    public:

        virtual void Print() {}

};

 

class Derived : public Base

{

    public:

        virtual void Print() {}

};

 

void func1( Base * b )

{

    b->Print();

}

 

void func2( Base b )

{

    b.Print();

}

 

void func3( Base & b )

{

    b.Print();

}

 

clang_isDynamicCall returns true for all three CallExpr cursors in the code.  I would have expected clang_isDynamicCall to return false for the call in func2 because the call is definitely to the Print method of Base.  Is this intended behaviour?  If yes, is there another way to determine whether the function call is going to be made polymorphically?

 

Thanks in advance,

Matt

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev