[gcc r11-3537] analyzer: fix signal-handler registration location [PR95188]

David Malcolm dmalcolm@gcc.gnu.org
Tue Sep 29 22:33:33 GMT 2020


https://gcc.gnu.org/g:d60d63a00bb50ba6896939705c589578177b404d

commit r11-3537-gd60d63a00bb50ba6896939705c589578177b404d
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Tue Sep 29 15:55:33 2020 -0400

    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.

Diff:
---
 gcc/analyzer/engine.cc                             | 22 +++++++++++++++------
 .../gcc.dg/analyzer/signal-registration-loc.c      | 23 ++++++++++++++++++++++
 2 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index c15d1195a97..0e79254ad60 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 <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
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-registration-loc.c b/gcc/testsuite/gcc.dg/analyzer/signal-registration-loc.c
new file mode 100644
index 00000000000..4bac1269b1e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-registration-loc.c
@@ -0,0 +1,23 @@
+/* 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;
+}


More information about the Gcc-cvs mailing list