stmt_requires_new_enode_p (const gimple *stmt,
const gimple *prev_stmt)
{
- /* Stop consolidating at calls to
- "__analyzer_dump_exploded_nodes", so they always appear at the
- start of an exploded_node. */
if (const gcall *call = dyn_cast <const gcall *> (stmt))
- if (is_special_named_call_p (call, "__analyzer_dump_exploded_nodes",
- 1))
- return true;
+ {
+ /* Stop consolidating at calls to
+ "__analyzer_dump_exploded_nodes", so they always appear at the
+ start of an exploded_node. */
+ if (is_special_named_call_p (call, "__analyzer_dump_exploded_nodes",
+ 1))
+ return true;
+
+ /* sm-signal.cc injects an additional custom eedge at "signal" calls
+ from the registration enode to the handler enode, separate from the
+ regular next state, which defeats the "detect state change" logic
+ in process_node. Work around this via special-casing, to ensure
+ we split the enode immediately before any "signal" call. */
+ if (is_special_named_call_p (call, "signal", 2))
+ return true;
+ }
/* If we had a PREV_STMT with an unknown location, and this stmt
has a known location, then if a state change happens here, it
--- /dev/null
+/* Ensure we use the correct location when reporting where the
+ signal handler was registered (PR analyzer/95188). */
+
+/* { dg-require-effective-target signal } */
+
+#include <stdio.h>
+#include <signal.h>
+
+int g;
+extern int foo (void);
+
+static void
+handler (int n)
+{
+ fprintf (stderr, "got here: %i\n", g); /* { dg-warning "call to 'fprintf' from within signal handler" } */
+}
+
+int main (int argc, char *argv[])
+{
+ g = foo (); /* { dg-bogus "registering" } */
+ signal (SIGSEGV, handler); /* { dg-message "registering 'handler' as signal handler" } */
+ return 0;
+}