Re: C++ constructors and callgraph interaction ("__ct_comp " vs constructor function body)

2020-02-06 Thread David Malcolm
On Thu, 2020-02-06 at 13:49 +0100, Martin Jambor wrote:
> Hi,
> 
> On Wed, Feb 05 2020, David Malcolm wrote:
> > Answering my own question, calling ultimate_alias_target on the
> > __ct_comp cgraph_node seems to find the "right" cgraph_node.
> > 
> > Is that the right general-purpose answer here?
> > 
> 
> sounds like it.  If however you also want the function to
> look through thunks you should use cgraph_node::function_symbol()
> instead.  But thunks of course can modify the first parameter, return
> value etc.

Thanks.  I went with ultimate_alias_target for now; FWIW the patch in
question is:
  https://gcc.gnu.org/ml/gcc-patches/2020-02/msg00398.html


Dave



Re: C++ constructors and callgraph interaction ("__ct_comp " vs constructor function body)

2020-02-06 Thread Martin Jambor
Hi,

On Wed, Feb 05 2020, David Malcolm wrote:
> Answering my own question, calling ultimate_alias_target on the
> __ct_comp cgraph_node seems to find the "right" cgraph_node.
>
> Is that the right general-purpose answer here?
>

sounds like it.  If however you also want the function to
look through thunks you should use cgraph_node::function_symbol()
instead.  But thunks of course can modify the first parameter, return
value etc.

Martin




Re: C++ constructors and callgraph interaction ("__ct_comp " vs constructor function body)

2020-02-05 Thread David Malcolm
On Wed, 2020-02-05 at 23:07 -0500, David Malcolm wrote:
> When debugging PR analyzer/93288, I'm compiling this test C++ file:
> 
> struct a {
>   a();
> };
> class foo {
>   a b;
> } c;
> 
> I see a cgraph_edge from __static_initialization_and_destruction_0 to
> a "__ct_comp ", which I see is a DECL_COMPLETE_CONSTRUCTOR_P.
> 
> The "__ct_comp " prints as a "a::a()/2", but its DECL_STRUCT_FUNCTION
> has a NULL CFG (which is what's causing the ICE in the analyzer).
> 
> The simple fix is to check for NULL, and skip such cases (but that
> would fail to analyze the calls).
> 
> However, there seems to be a separate a::a in the cgraph with a CFG
> containing the body of the ctor.
> 
> Looking at the __ct_comp:
> 
> (gdb) call edge->callee->debug() 
> _ZN3fooC1Ev/2 (foo::foo()) @0x7fffe2d0
>   Type: function definition analyzed alias cpp_implicit_alias
>   Visibility: externally_visible public weak comdat
> comdat_group:_ZN3fooC5Ev one_only artificial
>   Same comdat group as: _ZN3fooC2Ev/1
>   References: _ZN3fooC2Ev/1 (alias)
>   Referring: 
>   Availability: available
>   Function flags:
>   Called by: _Z41__static_initialization_and_destruction_0ii/4 (can
> throw external) 
>   Calls: 
> 
> and I note that we have _ZN3fooC1Ev/2 (the __ct_comp) and
> _ZN3fooC2Ev/1, which demangle to foo::foo()/2 and foo::foo()/1
> respectively.
> 
> I'm a bit hazy on the details here, sorry.
> 
> Presumably this "__ct_comp " fndecl's cgraph_node is thus linked to
> the
> "real" fndecl as a "cpp_implicit_alias"?
> 
> What's the best strategy for the analyzer to follow when it
> encounters
> a DECL_STRUCT_FUNCTION with a NULL CFG?
> 
> Should the analyzer:
> 
> (a) special-case this (e.g. assume that "cpp_implicit_alias" will
> have
> a single reference I can look up, or get it from the comdat groups,
> or
> somesuch), or
> 
> (b) are there some more general semantics I need to implement? (e.g.
> if
> it's weak, look in the comdat group for a non-weak alias, or
> somesuch?)

Answering my own question, calling ultimate_alias_target on the
__ct_comp cgraph_node seems to find the "right" cgraph_node.

Is that the right general-purpose answer here?

Thanks
Dave

> (c) not bother exploring those paths


> Thanks, and sorry if I'm missing something obvious here (I'm less
> familiar with this part of the compiler)
> 
> Dave
> 



C++ constructors and callgraph interaction ("__ct_comp " vs constructor function body)

2020-02-05 Thread David Malcolm
When debugging PR analyzer/93288, I'm compiling this test C++ file:

struct a {
  a();
};
class foo {
  a b;
} c;

I see a cgraph_edge from __static_initialization_and_destruction_0 to
a "__ct_comp ", which I see is a DECL_COMPLETE_CONSTRUCTOR_P.

The "__ct_comp " prints as a "a::a()/2", but its DECL_STRUCT_FUNCTION
has a NULL CFG (which is what's causing the ICE in the analyzer).

The simple fix is to check for NULL, and skip such cases (but that
would fail to analyze the calls).

However, there seems to be a separate a::a in the cgraph with a CFG
containing the body of the ctor.

Looking at the __ct_comp:

(gdb) call edge->callee->debug() 
_ZN3fooC1Ev/2 (foo::foo()) @0x7fffe2d0
  Type: function definition analyzed alias cpp_implicit_alias
  Visibility: externally_visible public weak comdat
comdat_group:_ZN3fooC5Ev one_only artificial
  Same comdat group as: _ZN3fooC2Ev/1
  References: _ZN3fooC2Ev/1 (alias)
  Referring: 
  Availability: available
  Function flags:
  Called by: _Z41__static_initialization_and_destruction_0ii/4 (can
throw external) 
  Calls: 

and I note that we have _ZN3fooC1Ev/2 (the __ct_comp) and
_ZN3fooC2Ev/1, which demangle to foo::foo()/2 and foo::foo()/1
respectively.

I'm a bit hazy on the details here, sorry.

Presumably this "__ct_comp " fndecl's cgraph_node is thus linked to the
"real" fndecl as a "cpp_implicit_alias"?

What's the best strategy for the analyzer to follow when it encounters
a DECL_STRUCT_FUNCTION with a NULL CFG?

Should the analyzer:

(a) special-case this (e.g. assume that "cpp_implicit_alias" will have
a single reference I can look up, or get it from the comdat groups, or
somesuch), or

(b) are there some more general semantics I need to implement? (e.g. if
it's weak, look in the comdat group for a non-weak alias, or somesuch?)

(c) not bother exploring those paths

Thanks, and sorry if I'm missing something obvious here (I'm less
familiar with this part of the compiler)

Dave