On Sun, 2026-06-14 at 19:45 +0100, Egas Ribeiro wrote:
> The following test (exception-subclass-2.C) xfails
When you say it "xfails", do you mean that it continues to fail, or
that it is now unexpectedly succeeding?
> with the lang-hook
> implementation:
> ```cpp
> #include "../../gcc.dg/analyzer/analyzer-decls.h"
>
> class exception
> {
> };
>
> class io_error : public exception
> {
> };
>
> int __analyzer_inner ()
> {
> try {
> throw io_error();
> } catch (exception &exc) {
> return -1;
> }
> __analyzer_dump_path (); // { dg-bogus "path" }
> return 0;
> }
>
> int test ()
> {
> return __analyzer_inner (); // { dg-message "path" "PR
> analyzer/119697" { xfail *-*-* } }
> }
> ```
>
> What is the intended behavior of this test?
I'm not sure, but I think my idea was to verify that the analysis does
in fact return from the call to __analyzer_inner.
BTW, have a look at exploded_graph::build_initial_worklist and
toplevel_function_p. By default, the analyzer tries to explore
execution paths starting at every externally-callable function, so
explores execution paths starting at "test" (with the interprocedurally
call into __analyzer_inner). It would also explore paths starting at
__analyzer_inner, but toplevel_function_p specifically ignores
functions with names starting with "__analyzer_".
> I'm not sure why the
> dg-message directive is on the call to __analyzer_inner,
Prior to r16-264-g7a39e0ca0652ff84a31efa3c7d4c7a78d9bb95ae the analyzer
was very confused by CFGs containing exception-handling, so my guess is
that we weren't even reaching that line, and perhaps the dump-path was
reported in the wrong place. But looking at it now, I'm not sure what
I was thinking.
> should I add a
> __analyzer_dump_path in the `catch (exception &exc)` path?
Sounds good.
>
>
>
> Separately from the question above, I found some typos in the
> internal
> docs for the analyzer:
> In the Region Model section, it seems in this section:
> ```
> Consider this example C code:
>
> @smallexample
> void *
> calls_malloc (size_t n)
> @{
> void *result = malloc (1024);
> return result; /* HERE */
> @}
>
> void test (size_t n)
> @{
> void *ptr = calls_malloc (n * 4);
> /* etc. */
> @}
> @end smallexample
> ```
>
> the docs write `void *result = malloc (1024);`, but the dumps after
> write:
> ```
> │ │ ╰─ frame: 'calls_malloc'@2
> │ │ ├─ result_4: &HEAP_ALLOCATED_REGION(27)
> │ │ ╰─ _5: &HEAP_ALLOCATED_REGION(27)
> │ ╰─ Dynamic Extents
> │ ╰─ HEAP_ALLOCATED_REGION(27): (INIT_VAL(n_2(D))*(size_t)4)
> ```
> which seems to assume we did `void *result = malloc (n);` instead.
You're right, I think the doc needs patching so that the example does a
"malloc (n)".
Looks like in the dump you quoted you're seeing the exploration of
"calls_malloc" as called from "test", as opposed to being explored
directly (both test and calls_malloc will have toplevel_function_p
return true, so I'd expect the initial worklist to contain both
entrypoints).
>
> Also, the dumps say `HEAP_ALLOCATED_REGION(27)` but later we write
> ```
> within test the whole cluster for result_4 is bound to a
> region_svalue pointing at
> HEAP_ALLOCATED_REGION(12)
> ```
> should be ` HEAP_ALLOCATED_REGION(27)` not `
> HEAP_ALLOCATED_REGION(12)`.
The precise numbering of heap-allocated regions will change from run to
run depending on what other code is being explored and in what order.
Maybe the docs should say that?
Hope this all makes sense
BTW, I'm working on a major rewrite of how store.{cc,h} works, which
(as well as fixing a bunch of bugs) will greatly change the way dumps
look - but I don't expect it to be ready to merge until late July at
the earliest.
Dave