From d60d63a00bb50ba6896939705c589578177b404d Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 29 Sep 2020 15:55:33 -0400 Subject: analyzer: fix signal-handler registration location [PR95188] PR analyzer/95188 reports that diagnostics from -Wanalyzer-unsafe-call-within-signal-handler use the wrong source location when reporting the signal-handler registration event in the diagnostic_path. The diagnostics erroneously use the location of the first stmt in the basic block containing the call to "signal", rather than that of the call itself. Fixed thusly. gcc/analyzer/ChangeLog: PR analyzer/95188 * engine.cc (stmt_requires_new_enode_p): Split enodes before "signal" calls. gcc/testsuite/ChangeLog: PR analyzer/95188 * gcc.dg/analyzer/signal-registration-loc.c: New test. --- gcc/analyzer/engine.cc | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'gcc/analyzer') diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index c15d119..0e79254 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -2677,13 +2677,23 @@ static bool 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 (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 -- cgit v1.1