Re: C++ constructors and callgraph interaction ("__ct_comp " vs constructor function body)
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)
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)
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)
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