On Sat, 20 Jun 2026, Filip Kastl wrote:

> Hi richi,
> 
> I found a case where the function.clobber varinfo gets included in a points-to
> set.  That shouldn't happen right?  It causes trouble for my PTA Steensgaard
> project.
> 
> Here is a testcase:
> 
> ---- pr35065-reduced.c ----
> enum vlc_module_properties { VLC_MODULE_CB_OPEN };
> char ParseNALBlock_p_frag_0;
> int vlc_entry__0_9_0f_p_submodule;
> void Open();
> void vlc_module_set(int *, enum vlc_module_properties, void *);
> void vlc_entry__0_9_0f() {
>   vlc_module_set(&vlc_entry__0_9_0f_p_submodule, VLC_MODULE_CB_OPEN, Open);
> }
> void ParseNALBlock();
> void Open() { ParseNALBlock(); }
> void bs_read_ue();
> void ParseNALBlock() {
>   if (ParseNALBlock_p_frag_0)
>     bs_read_ue();
> }
> ---- ----
> 
> I compile it with trunk GCC using these flags:
> gcc -c pr35065-reduced.c -fipa-pta -O2 -march=native -fno-inline 
> -fdump-ipa-pta2-details-alias
> 
> In the dump you can see this set:
> callarg(34) = { ESCAPED Open Open.clobber Open.use Open.result }
> 
> I've stepped through PTA in GDB and found that initially,
> callarg(34) = { Open }
> When we process the constraints callarg(34) = callarg(34) + UNKNOWN,
> pta-andersen.cc:solution_set_expand() happilly expands the Open varinfo into
> all the subvariables Open.clobber Open.use Open.result.
> 
> Is this intentional?
> 
> Open.clobber, Open.use, Open.result all have is_full_var = 1, but Open does
> not.  What's your gut feeling about setting is_full_var = 1 for fninfos?  It
> does help with this testcase but I didn't yet look through the sources to see
> if it doesn't break something else.

I think this will break indirect call handling.  So what we have is

vlc_entry__0_9_0f ()
{
  vlc_module_set (&vlc_entry__0_9_0f_p_submodule, 0u, &Open);
}

where 'Open' is internal but vlc_module_set is not.  We generate

callarg(34) = &Open
callarg(34) = callarg(34) + UNKNOWN
callarg(34) = *callarg(34) + UNKNOWN
CALLUSED(30) = callarg(34)
*callarg(34) = callescape(29)
CALLCLOBBERED(31) = callarg(34)
callescape(29) = callarg(34)
ESCAPED = &Open

where this tries to set up things in a way to allow vlc_module_set
to call 'Open' indirectly, meaning the vlc_module_set call clobbers
include call clobbers of 'Open' and the 'Open' incoming arguments
now have to contain the vars escaped to vlc_module_set and of course
all other ESCAPED vars.  If you consider 'Open' being program-local,
having actual arguments and having meaningful uses/clobbers, then
this should make sense.  If you consider vlc_module_set being
not external and an indirect call visble you can also see how the
indirect call processing then works during PTA solving.

So I'm not sure that only solution_set_expand is an issue with
the way you do clobbers/uses, even if we'd do this in a more
explicit way you'd get clobbers and uses part of the solving
process.

There should be some very incomplete coverage of indirect call
handing in the gcc.dg/ipa/ipa-pta-* tests.

Now, that we get

allarg(34) = { ESCAPED Open Open.clobber Open.use Open.result }

shows that we fail to maintain the fact that we of course cannot
take the address of Open.clobber or Open.use.  I think this
means we fail to set ->is_artificial_var on those (but not on
arguments or result)?  So if that helps, I think that's the
correct thing to do here.

Richard.

Reply via email to