On Mon, 2023-08-07 at 15:04 +0200, Benjamin Priour wrote: > Hi Dave, [...snip...]
> Last test I'd like to discuss is analyzer/pr99193-1.c > [...snip...] > > If I comment out the call to perror("realloc"), then G++ behaves as > GCC. > If I replace perror ("realloc") by any other call, to a fully-defined > function or whatever, then the warning reappears. > The above SSA differ by an extra basic block in G++ that splits GCC's > <bb > 6> in two. > However, that doesn't account for much, as changing > if (p == NULL) { > perror ("realloc"); > __builtin_va_end (args); // (*) > return -1; > } > to > if (p == NULL) { > int x; > perror("realloc"); > if (x > 7) > x = 12; > __builtin_va_end (args); > return -1; > } > generates a similar basic block around __builtin_va_end, yet G++ > keeps > emitting the false positive whereas GCC doesn't. > // GCC modified SSA > <bb 6> : > perror ("realloc"); > if (x_51(D) > 7) > goto <bb 7>; [INV] > else > goto <bb 8>; [INV] > > <bb 7> : > x_52 = 12; > > <bb 8> : > __builtin_va_end (&args); > _54 = -1; > // predicted unlikely by early return (on trees) predictor. > goto <bb 12>; [INV] > > // G++ modified SSA > <bb 7> : > perror ("realloc"); > > <bb 8> : > if (x_55(D) > 7) > goto <bb 9>; [INV] > else > goto <bb 10>; [INV] > > <bb 9> : > x_56 = 12; > > <bb 10> : > __builtin_va_end (&args); > _58 = -1; > // predicted unlikely by early return (on trees) predictor. > goto <bb 15>; [INV] > > Debugging and glaring at the exploded graph gave me no clue towards > fixing > this test. > If you have any hint, I welcome it. There a CFG difference here, so have a look at the .supergraph.dot files with gcc vs g++, using -fdump-analyzer-supergraph. Both write out to pr99193-1.c.supergraph.dot, but renaming the results and then comparing them side-by-side, I see various differences. In particular, looking at the BB containing the perror ("realloc"), both GCC and G++ have an out-edge with flag FALLTHRU going to the BB that starts with __builtin_va_end, but G++ also has an out-edge with flag EH going to BB 16, which starts with guestfs_int_cleanup_free (generated by the __attribute__((cleanup(guestfs_int_cleanup_free))) on argv. So I think what we're seeing here is the execution path that follows that EH edge, which is to handle the case where perror raises an exception. I don't know if that's actually possible, but perhaps it is. Are you adding any exception-handling flags to the G++ cases? (e.g. disabling exception-handling?) Dave