]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
testsuite: fix analyzer C++ failures on Solaris [PR111475]
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 3 May 2024 13:05:29 +0000 (09:05 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Fri, 3 May 2024 13:05:29 +0000 (09:05 -0400)
As part of PR analyzer/96395, these patches moved testcases from
gcc.dg/analyzer to c-c++-common/analyzer:
r14-3503-g55f6a7d949abc7
r14-3823-g50b5199cff6908
r14-6564-gae034b9106fbdd

Unfortunately this led to numerous g++ testsuite failures on Solaris,
tracked as PR analyzer/111475.

Almost all of the failures are due to standard library differences where
including a C standard library on C++ e.g. <stdlib.h> leads to the plain
symbols referencing the symbols "std::" via a "using" declaration,
whereas I had written the code expecting them to use symbols in the root
namespace.

The analyzer has special-case handling of many functions by name.
This patch generalizes such handling to also match against functions
in "std::" for all of the cases I found in the testsuite (via manual
inspection of the preprocessed test cases against Solaris headers).
This fixes cases where the analyzer was failing to "know about" the
behavior of such functions.

Other such failures are due to "std::" prefixes appearing in names of
functions in the output, leading to mismatches against expected output.
The patch adds regexes to some cases, and moves some other cases back
from c-c++-common to gcc.dg where the dg-multiline syntax isn't
expressive enough.

Various "fd-*.c" failures relate to Solaris's socket-handling functions
not being marked with "noexcept", where due to PR analyzer/97111 we
mishandle the exception-handling edges in the CFG, leading to leak
false positives.  The patch works around this by adding -fno-exceptions
to these cases, pending a proper fix for PR analyzer/97111.

gcc/analyzer/ChangeLog:
PR analyzer/111475
* analyzer.cc (is_special_named_call_p): Add "look_in_std" param.
(is_std_function_p): Make non-static.
* analyzer.h (is_special_named_call_p): Add optional "look_in_std"
param.
(is_std_function_p): New decl.
* engine.cc (stmt_requires_new_enode_p): Look for both "signal"
and "std::signal".
* kf.cc (register_known_functions): Add various "std::" copies
of the known functions.
* known-function-manager.cc
(known_function_manager::~known_function_manager): Clean up
m_std_ns_map_id_to_kf.
(known_function_manager::add_std_ns): New.
(known_function_manager::get_match): Also look for known "std::"
functions.
(known_function_manager::get_by_identifier_in_std_ns): New.
* known-function-manager.h
(known_function_manager::add_std_ns): New decl.
(known_function_manager::get_by_identifier_in_std_ns): New decl.
(known_function_manager::m_std_ns_map_id_to_kf): New field.
* sm-file.cc (register_known_file_functions): Add various "std::"
copies of the known functions.
* sm-malloc.cc (malloc_state_machine::on_stmt): Handle
"std::realloc".
* sm-signal.cc (signal_unsafe_p): Consider "std::" copies of the
functions as also being async-signal-unsafe.
(signal_state_machine::on_stmt): Consider "std::signal".

gcc/testsuite/ChangeLog:
PR analyzer/111475
* c-c++-common/analyzer/fd-glibc-byte-stream-socket.c: Add
-fno-exceptions for now.
* c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c: Likewise.
* c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c: Rename to...
* c-c++-common/analyzer/fd-manpage-getaddrinfo-server.c: ...this, and
add -fno-exceptions for now.
* c-c++-common/analyzer/fd-socket-meaning.c: Add -fno-exceptions
for now.
* c-c++-common/analyzer/fd-symbolic-socket.c: Likewise.
* c-c++-common/analyzer/flexible-array-member-1.c: Use regexp to
handle C vs C++ differences in spelling of function name, which
could have a "std::" prefix on some targets.
* c-c++-common/analyzer/pr106539.c: Likewise.
* c-c++-common/analyzer/malloc-ipa-8-unchecked.c: Move back to...
* gcc.dg/analyzer/malloc-ipa-8-unchecked.c: ...here, dropping
attempt to generalize output for C vs C++.
* c-c++-common/analyzer/signal-4a.c: Move back to...
* gcc.dg/analyzer/signal-4a.c: ...here, dropping attempt to
generalize output for C vs C++.
* c-c++-common/analyzer/signal-4b.c: Move back to...
* gcc.dg/analyzer/signal-4b.c: ...here, dropping attempt to
generalize output for C vs C++.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
19 files changed:
gcc/analyzer/analyzer.cc
gcc/analyzer/analyzer.h
gcc/analyzer/engine.cc
gcc/analyzer/kf.cc
gcc/analyzer/known-function-manager.cc
gcc/analyzer/known-function-manager.h
gcc/analyzer/sm-file.cc
gcc/analyzer/sm-malloc.cc
gcc/analyzer/sm-signal.cc
gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c
gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c
gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-server.c [moved from gcc/testsuite/c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c with 96% similarity]
gcc/testsuite/c-c++-common/analyzer/fd-socket-meaning.c
gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c
gcc/testsuite/c-c++-common/analyzer/flexible-array-member-1.c
gcc/testsuite/c-c++-common/analyzer/pr106539.c
gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c [moved from gcc/testsuite/c-c++-common/analyzer/malloc-ipa-8-unchecked.c with 55% similarity]
gcc/testsuite/gcc.dg/analyzer/signal-4a.c [moved from gcc/testsuite/c-c++-common/analyzer/signal-4a.c with 53% similarity]
gcc/testsuite/gcc.dg/analyzer/signal-4b.c [moved from gcc/testsuite/c-c++-common/analyzer/signal-4b.c with 52% similarity]

index 7f5d3d56d3383e3f83e6c360edb40f6461158eaa..2a15a3a9ad79e9e858a8007e075f7768b9642431 100644 (file)
@@ -293,11 +293,13 @@ get_ssa_default_def (const function &fun, tree var)
    is_named_call_p should be used instead, using a fndecl from
    get_fndecl_for_call; this function should only be used for special cases
    where it's not practical to get at the region model, or for special
-   analyzer functions such as __analyzer_dump.  */
+   analyzer functions such as __analyzer_dump.
+
+   If LOOK_IN_STD is true, then also look for within std:: for the name.  */
 
 bool
 is_special_named_call_p (const gcall *call, const char *funcname,
-                        unsigned int num_args)
+                        unsigned int num_args, bool look_in_std)
 {
   gcc_assert (funcname);
 
@@ -305,7 +307,12 @@ is_special_named_call_p (const gcall *call, const char *funcname,
   if (!fndecl)
     return false;
 
-  return is_named_call_p (fndecl, funcname, call, num_args);
+  if (is_named_call_p (fndecl, funcname, call, num_args))
+    return true;
+  if (look_in_std)
+    if (is_std_named_call_p (fndecl, funcname, call, num_args))
+      return true;
+  return false;
 }
 
 /* Helper function for checkers.  Is FNDECL an extern fndecl at file scope
@@ -344,7 +351,7 @@ is_named_call_p (const_tree fndecl, const char *funcname)
    Compare with cp/typeck.cc: decl_in_std_namespace_p, but this doesn't
    rely on being the C++ FE (or handle inline namespaces inside of std).  */
 
-static inline bool
+bool
 is_std_function_p (const_tree fndecl)
 {
   tree name_decl = DECL_NAME (fndecl);
index d43812e396352bc3c3b32993366087c440e14e00..334b0d32bd051ab0b163ec4abbb645265d71da18 100644 (file)
@@ -448,10 +448,12 @@ extern tree remove_ssa_names (tree expr);
 } // namespace ana
 
 extern bool is_special_named_call_p (const gcall *call, const char *funcname,
-                                    unsigned int num_args);
+                                    unsigned int num_args,
+                                    bool look_in_std = false);
 extern bool is_named_call_p (const_tree fndecl, const char *funcname);
 extern bool is_named_call_p (const_tree fndecl, const char *funcname,
                             const gcall *call, unsigned int num_args);
+extern bool is_std_function_p (const_tree fndecl);
 extern bool is_std_named_call_p (const_tree fndecl, const char *funcname);
 extern bool is_std_named_call_p (const_tree fndecl, const char *funcname,
                                 const gcall *call, unsigned int num_args);
index e0dc0e66e88c5005ef8b1bcb991cc4f71e8a9d46..556e8a1c82880fa9e6ef8b58b8383a24d44f6a34 100644 (file)
@@ -3768,7 +3768,7 @@ stmt_requires_new_enode_p (const gimple *stmt,
         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))
+      if (is_special_named_call_p (call, "signal", 2, true))
        return true;
     }
 
index 6931f07bd75e1d50f9f506db045d406564ebfbe1..c60e220dd1b9da06215f538cdc58f916fbdf4055 100644 (file)
@@ -2344,6 +2344,28 @@ register_known_functions (known_function_manager &kfm,
 
   /* Language-specific support functions.  */
   register_known_functions_lang_cp (kfm);
+
+  /* Some C++ implementations use the std:: copies of these functions
+     from <cstdlib> etc for the C spellings of these headers (e.g. <stdlib.h>),
+     so we must match against these too.  */
+  {
+    kfm.add_std_ns ("malloc", make_unique<kf_malloc> ());
+    kfm.add_std_ns ("free", make_unique<kf_free> ());
+    kfm.add_std_ns ("realloc", make_unique<kf_realloc> ());
+    kfm.add_std_ns ("calloc", make_unique<kf_calloc> ());
+    kfm.add_std_ns
+      ("memcpy",
+       make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMCPY));
+    kfm.add_std_ns
+      ("memmove",
+       make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMMOVE));
+    kfm.add_std_ns ("memset", make_unique<kf_memset> (false));
+    kfm.add_std_ns ("strcat", make_unique<kf_strcat> (2, false));
+    kfm.add_std_ns ("strcpy", make_unique<kf_strcpy> (2, false));
+    kfm.add_std_ns ("strlen", make_unique<kf_strlen> ());
+    kfm.add_std_ns ("strncpy", make_unique<kf_strncpy> ());
+    kfm.add_std_ns ("strtok", make_unique<kf_strtok> (rmm));
+  }
 }
 
 } // namespace ana
index 9f7aeb86d09c188822bf484970c9582fe71adaae..d24e5b8f407976b25ef3aacea4805b507e06e270 100644 (file)
@@ -50,6 +50,8 @@ known_function_manager::~known_function_manager ()
   /* Delete all owned kfs.  */
   for (auto iter : m_map_id_to_kf)
     delete iter.second;
+  for (auto iter : m_std_ns_map_id_to_kf)
+    delete iter.second;
   for (auto iter : m_combined_fns_arr)
     delete iter;
 }
@@ -63,6 +65,15 @@ known_function_manager::add (const char *name,
   m_map_id_to_kf.put (id, kf.release ());
 }
 
+void
+known_function_manager::add_std_ns (const char *name,
+                            std::unique_ptr<known_function> kf)
+{
+  LOG_FUNC_1 (get_logger (), "registering std::%s", name);
+  tree id = get_identifier (name);
+  m_std_ns_map_id_to_kf.put (id, kf.release ());
+}
+
 void
 known_function_manager::add (enum built_in_function name,
                             std::unique_ptr<known_function> kf)
@@ -104,7 +115,16 @@ known_function_manager::get_match (tree fndecl, const call_details &cd) const
 
   /* Look for a match by name.  */
 
-  /* Reject fndecls that aren't in the root namespace.  */
+  if (is_std_function_p (fndecl))
+    {
+      if (tree identifier = DECL_NAME (fndecl))
+       if (const known_function *candidate
+             = get_by_identifier_in_std_ns (identifier))
+         if (candidate->matches_call_types_p (cd))
+           return candidate;
+      return nullptr;
+    }
+
   if (DECL_CONTEXT (fndecl)
       && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
     return NULL;
@@ -158,6 +178,22 @@ known_function_manager::get_by_identifier (tree identifier) const
     return NULL;
 }
 
+/* Get any known_function in C++ std:: namespace matching IDENTIFIER, without
+   type-checking.
+   Return nullptr if there isn't one.  */
+
+const known_function *
+known_function_manager::get_by_identifier_in_std_ns (tree identifier) const
+{
+  known_function_manager *mut_this = const_cast<known_function_manager *>(this);
+  known_function **slot = mut_this->m_std_ns_map_id_to_kf.get (identifier);
+  if (slot)
+    return *slot;
+  else
+    return nullptr;
+}
+
+
 } // namespace ana
 
 #endif /* #if ENABLE_ANALYZER */
index 81e42e157b73d2409e39e8d61e24b713f52b44e3..cf931936873845ed6de1716d07af9fca3d8f4a19 100644 (file)
@@ -44,6 +44,7 @@ public:
   ~known_function_manager ();
 
   void add (const char *name, std::unique_ptr<known_function> kf);
+  void add_std_ns (const char *name, std::unique_ptr<known_function> kf);
   void add (enum built_in_function name, std::unique_ptr<known_function> kf);
   void add (enum internal_fn ifn, std::unique_ptr<known_function> kf);
 
@@ -57,11 +58,15 @@ private:
   const known_function *
   get_normal_builtin (const builtin_known_function *builtin_kf) const;
   const known_function *get_by_identifier (tree identifier) const;
+  const known_function *get_by_identifier_in_std_ns (tree identifier) const;
 
   /* Map from identifier to known_function instance.
      Has ownership of the latter.  */
   hash_map<tree, known_function *> m_map_id_to_kf;
 
+  /* Likewise for C++'s std:: namespace.  */
+  hash_map<tree, known_function *> m_std_ns_map_id_to_kf;
+
   /* Array of known builtins.  */
   known_function *m_combined_fns_arr[CFN_LAST];
 };
index 6739c31c22b889dfbc5fced72b7846b1801d35a0..f85b400496928ee40c42a7fa73721a6d071211aa 100644 (file)
@@ -648,6 +648,14 @@ register_known_file_functions (known_function_manager &kfm)
   kfm.add ("fread", make_unique<kf_fread> ());
   kfm.add ("getc", make_unique<kf_getc> ());
   kfm.add ("getchar", make_unique<kf_getchar> ());
+
+  /* Some C++ implementations use the std:: copies of these functions
+     from <cstdio> for <stdio.h>, so we must match against these too.  */
+  kfm.add_std_ns ("ferror", make_unique<kf_ferror> ());
+  kfm.add_std_ns ("fgets", make_unique<kf_fgets> ());
+  kfm.add_std_ns ("fread", make_unique<kf_fread> ());
+  kfm.add_std_ns ("getc", make_unique<kf_getc> ());
+  kfm.add_std_ns ("getchar", make_unique<kf_getchar> ());
 }
 
 #if CHECKING_P
index 4e11d6dfc630b739121541dc48a0c8b0d9472ce8..fc6718ad74baee088e95fbe6587b051288cf9778 100644 (file)
@@ -1983,6 +1983,7 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt,
          }
 
        if (is_named_call_p (callee_fndecl, "realloc", call, 2)
+           || is_std_named_call_p (callee_fndecl, "realloc", call, 2)
            || is_named_call_p (callee_fndecl, "__builtin_realloc", call, 2))
          {
            on_realloc_call (sm_ctxt, node, call);
index 93269caa0dc58a36276ea4f6072895ab9feeb1c5..84603c5b77b78ceb66750913cde24ed838fc2ad7 100644 (file)
@@ -320,7 +320,13 @@ static bool
 signal_unsafe_p (tree fndecl)
 {
   function_set fs = get_async_signal_unsafe_fns ();
-  return fs.contains_decl_p (fndecl);
+  if (fs.contains_decl_p (fndecl))
+    return true;
+  if (is_std_function_p (fndecl)
+      && fs.contains_name_p (IDENTIFIER_POINTER (DECL_NAME (fndecl))))
+    return true;
+
+  return false;
 }
 
 /* Implementation of state_machine::on_stmt vfunc for signal_state_machine.  */
@@ -335,7 +341,8 @@ signal_state_machine::on_stmt (sm_context *sm_ctxt,
     {
       if (const gcall *call = dyn_cast <const gcall *> (stmt))
        if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
-         if (is_named_call_p (callee_fndecl, "signal", call, 2))
+         if (is_named_call_p (callee_fndecl, "signal", call, 2)
+             || is_std_named_call_p (callee_fndecl, "signal", call, 2))
            {
              tree handler = gimple_call_arg (call, 1);
              if (TREE_CODE (handler) == ADDR_EXPR
index fab8426acb926f3c903d42f12c8c89b787bca129..fd57d3b0894a023ba93194c1c6e5d1e6e30778d4 100644 (file)
@@ -1,5 +1,9 @@
 /* Example from glibc manual (16.9.6).  */
 /* { dg-require-effective-target sockets } */
+
+/* Needed on some targets until we have exception-handling working (PR 111475).  */
+/* { dg-additional-options "-fno-exceptions" } */
+
 /* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */
 
 #include <stdio.h>
index 21dfe977db813fe908fea9e9bd34eda7f66e6635..ee7e4b496c1e6361adf2e138e131d3fb3f36fac1 100644 (file)
@@ -28,6 +28,10 @@ the source, must acknowledge the copyright and authors of this work.
 
 /* { dg-require-effective-target sockets } */
 /* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
+/* Needed on some targets until we have exception-handling working (PR 111475).  */
+/* { dg-additional-options "-fno-exceptions" } */
+
 /* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */
 
 #include <sys/types.h>
similarity index 96%
rename from gcc/testsuite/c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c
rename to gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-server.c
index 2e9cec4abf0223ca402146331536e333fe557186..7bc456800961027b559d658c070e8ed65a935f26 100644 (file)
@@ -27,6 +27,10 @@ the source, must acknowledge the copyright and authors of this work.
 */
 
 /* { dg-require-effective-target sockets } */
+
+/* Needed on some targets until we have exception-handling working (PR 111475).  */
+/* { dg-additional-options "-fno-exceptions" } */
+
 /* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */
 
 #include <sys/types.h>
index 82a199f83b06ebb1bcd9fd88f8e8201812453e51..995d3a1d684bd84e133b938cd8063bdbc74047c3 100644 (file)
@@ -1,4 +1,8 @@
 /* { dg-require-effective-target sockets } */
+
+/* Needed on some targets until we have exception-handling working (PR 111475).  */
+/* { dg-additional-options "-fno-exceptions" } */
+
 /* { dg-additional-options "-fanalyzer-verbose-state-changes" } */
 
 #include <sys/socket.h>
index 32264fd9701318d5c19fbaf0dd658cca74e10fbf..c6af0a6487f462452ab895487954000d77dd6ec7 100644 (file)
@@ -1,4 +1,8 @@
 /* { dg-require-effective-target sockets } */
+
+/* Needed on some targets until we have exception-handling working (PR 111475).  */
+/* { dg-additional-options "-fno-exceptions" } */
+
 /* { dg-skip-if "" { hppa*-*-hpux* powerpc*-*-aix* } } */
 
 #include <string.h>
index 82dbcec535925fdbd2065ed8361d7a1e9faea83a..d794336198b82368dc39767ebec6033282b64613 100644 (file)
@@ -27,8 +27,7 @@ test_const_size_oob_1 (void)
   if (str) {
     str->len = 10;
     memset(str->data, 'x', 10); /* { dg-warning "heap-based buffer overflow" "Wanalyzer-out-of-bounds" } */
-    /* { dg-warning "'memset' writing 10 bytes into a region of size 0 overflows the destination" "Wstringop-overflow" { target c } .-1 } */
-    /* { dg-warning "'void\\* memset\\(void\\*, int, size_t\\)' writing 10 bytes into a region of size 0 overflows the destination" "Wstringop-overflow" { target c++ } .-2 } */
+    /* { dg-warning "'\[^\n\r\]*memset\[^\n\r\]*' writing 10 bytes into a region of size 0 overflows the destination" "Wstringop-overflow" { target *-*-* } .-1 } */
     return str;
   }
   return NULL;
@@ -42,8 +41,7 @@ test_const_size_oob_2 (void)
     str->len = 10;
     /* Using the wrong size here.  */
     memset(str->data, 'x', 11); /* { dg-warning "heap-based buffer overflow" "Wanalyzer-out-of-bounds" } */
-    /* { dg-warning "'memset' writing 11 bytes into a region of size 10 overflows the destination" "Wstringop-overflow" { target c } .-1 } */
-    /* { dg-warning "'void\\* memset\\(void\\*, int, size_t\\)' writing 11 bytes into a region of size 10 overflows the destination" "Wstringop-overflow" { target c++ } .-2 } */
+    /* { dg-warning "'\[^\n\r\]*memset\[^\n\r\]*' writing 11 bytes into a region of size 10 overflows the destination" "Wstringop-overflow" { target *-*-* } .-1 } */
 
     return str;
   }
index fd270868e36252e53df37dc5ac211338e96c5cb2..8745c1de09aea381c3dd5eabe2fd495f92c7de04 100644 (file)
@@ -7,7 +7,7 @@ void *test (void)
     return NULL;
   p[0] = malloc(10);
   p[1] = malloc(20); /* { dg-message "allocated here" }  */
-  void *q = realloc (p, sizeof (void *)); /* { dg-message "when 'realloc' succeeds, moving buffer" } */
+  void *q = realloc (p, sizeof (void *)); /* { dg-message "when '\[^\n\r\]*realloc\[^\n\r\]*' succeeds, moving buffer" } */
   if (!q)
   /* { dg-warning "leak of '<unknown>'" "leak of unknown" { target *-*-* } .-1 } */
     return p;
similarity index 55%
rename from gcc/testsuite/c-c++-common/analyzer/malloc-ipa-8-unchecked.c
rename to gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c
index 5bc8e57827b6fcfb3205de82c2ea051d9386e72c..f2c10dd3b751cdf786b15f18410ecfd65e68c3ef 100644 (file)
@@ -3,6 +3,9 @@
 /* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fanalyzer-checker=malloc -fdiagnostics-show-caret" } */
 /* { dg-enable-nn-line-numbers "" } */
 
+/* C only; attempting to generalize it for C++ leads
+   to an explosion of possibilities for the multiline output.  */
+
 #include <stdlib.h>
 
 void *wrapped_malloc (size_t size)
@@ -64,45 +67,4 @@ make_boxed_int (int i)
     |      |             |
     |      |             (6) 'result' could be NULL: unchecked value from (4)
     |
-  { dg-end-multiline-output "" { target c } } */
-/* { dg-begin-multiline-output "" }
-   NN |   result->i = i;
-      |   ~~~~~~~~~~^~~
-  'boxed_int* make_boxed_int(int)': events 1-2
-    |
-    |   NN | make_boxed_int (int i)
-    |      | ^~~~~~~~~~~~~~
-    |      | |
-    |      | (1) entry to 'make_boxed_int'
-    |   NN | {
-    |   NN |   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
-    |      |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    |      |                                                   |
-    |      |                                                   (2) calling 'wrapped_malloc' from 'make_boxed_int'
-    |
-    +--> 'void* wrapped_malloc(size_t)': events 3-4
-           |
-           |   NN | void *wrapped_malloc (size_t size)
-           |      |       ^~~~~~~~~~~~~~
-           |      |       |
-           |      |       (3) entry to 'wrapped_malloc'
-           |   NN | {
-           |   NN |   return malloc (size);
-           |      |          ~~~~~~~~~~~~~
-           |      |                 |
-           |      |                 (4) this call could return NULL
-           |
-    <------+
-    |
-  'boxed_int* make_boxed_int(int)': events 5-6
-    |
-    |   NN |   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
-    |      |                                    ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
-    |      |                                                   |
-    |      |                                                   (5) possible return of NULL to 'make_boxed_int' from 'wrapped_malloc'
-    |   NN |   result->i = i;
-    |      |   ~~~~~~~~~~~~~                     
-    |      |             |
-    |      |             (6) 'result' could be NULL: unchecked value from (4)
-    |
-  { dg-end-multiline-output "" { target c++ } } */
+  { dg-end-multiline-output "" } */
similarity index 53%
rename from gcc/testsuite/c-c++-common/analyzer/signal-4a.c
rename to gcc/testsuite/gcc.dg/analyzer/signal-4a.c
index b5c6012ec2ec853fbc920c891604175edaebad31..538adaea6ee606598c9ca97b9a1e14e3a05b41c0 100644 (file)
@@ -1,5 +1,8 @@
 /* Verify how paths are printed for signal-handler diagnostics.  */
 
+/* C only; attempting to generalize it for C++ leads
+   to an explosion of possibilities for the multiline output.  */
+
 /* { dg-options "-fanalyzer -fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
 /* { dg-enable-nn-line-numbers "" } */
 /* { dg-require-effective-target signal } */
@@ -12,8 +15,7 @@ extern void body_of_program(void);
 
 void custom_logger(const char *msg)
 {
-  fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to 'fprintf' from within signal handler" "" { target c } } */
-  /* { dg-warning "call to 'int fprintf\\(FILE\\*, const char\\*, ...\\)' from within signal handler" "" { target c++ } .-1 } */
+  fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to 'fprintf' from within signal handler" } */
 }
 
 static void int_handler(int signum)
@@ -74,49 +76,4 @@ void test (void)
                   |      |   |
                   |      |   (7) call to 'fprintf' from within signal handler
                   |
-  { dg-end-multiline-output "" { target c } } */
-/* { dg-begin-multiline-output "" }
-   NN |   fprintf(stderr, "LOG: %s", msg);
-      |   ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
-  'void test()': events 1-2
-    |
-    |   NN | void test (void)
-    |      |      ^~~~
-    |      |      |
-    |      |      (1) entry to 'test'
-    |......
-    |   NN |   signal(SIGINT, int_handler);
-    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    |      |         |
-    |      |         (2) registering 'void int_handler(int)' as signal handler
-    |
-  event 3
-    |
-    |cc1plus:
-    | (3): later on, when the signal is delivered to the process
-    |
-    +--> 'void int_handler(int)': events 4-5
-           |
-           |   NN | static void int_handler(int signum)
-           |      |             ^~~~~~~~~~~
-           |      |             |
-           |      |             (4) entry to 'int_handler'
-           |   NN | {
-           |   NN |   custom_logger("got signal");
-           |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-           |      |                |
-           |      |                (5) calling 'custom_logger' from 'int_handler'
-           |
-           +--> 'void custom_logger(const char*)': events 6-7
-                  |
-                  |   NN | void custom_logger(const char *msg)
-                  |      |      ^~~~~~~~~~~~~
-                  |      |      |
-                  |      |      (6) entry to 'custom_logger'
-                  |   NN | {
-                  |   NN |   fprintf(stderr, "LOG: %s", msg);
-                  |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                  |      |          |
-                  |      |          (7) call to 'int fprintf(FILE*, const char*, ...)' from within signal handler
-                  |
-  { dg-end-multiline-output "" { target c++ } } */
+  { dg-end-multiline-output "" } */
similarity index 52%
rename from gcc/testsuite/c-c++-common/analyzer/signal-4b.c
rename to gcc/testsuite/gcc.dg/analyzer/signal-4b.c
index d2b5db7b2760ef5db69bf2ca1e69ac637d2b9240..5bf8c823ef99a47c34be1652af70f782e1cdc00c 100644 (file)
@@ -1,5 +1,8 @@
 /* Verify how paths are printed for signal-handler diagnostics.  */
 
+/* C only; attempting to generalize it for C++ leads
+   to an explosion of possibilities for the multiline output.  */
+
 /* { dg-options "-fanalyzer -fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
 /* { dg-enable-nn-line-numbers "" } */
 /* { dg-require-effective-target signal } */
@@ -12,8 +15,7 @@ extern void body_of_program(void);
 
 void custom_logger(const char *msg)
 {
-  fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to 'fprintf' from within signal handler" "" { target c } } */
-  /* { dg-warning "call to 'int fprintf\\(FILE\\*, const char\\*, ...\\)' from within signal handler" "" { target c++ } .-1 } */
+  fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to 'fprintf' from within signal handler" } */
 }
 
 static void int_handler(int signum)
@@ -89,61 +91,4 @@ void test (void)
                   |      |   |
                   |      |   (9) call to 'fprintf' from within signal handler
                   |
-  { dg-end-multiline-output "" { target c } } */
-/* { dg-begin-multiline-output "" }
-   NN |   fprintf(stderr, "LOG: %s", msg);
-      |   ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
-  'void test()': events 1-2
-    |
-    |   NN | void test (void)
-    |      |      ^~~~
-    |      |      |
-    |      |      (1) entry to 'test'
-    |   NN | {
-    |   NN |   __analyzer_register_handler ();
-    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    |      |                               |
-    |      |                               (2) calling '__analyzer_register_handler' from 'test'
-    |
-    +--> 'void __analyzer_register_handler()': events 3-4
-           |
-           |   NN | static void __analyzer_register_handler ()
-           |      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
-           |      |             |
-           |      |             (3) entry to '__analyzer_register_handler'
-           |   NN | {
-           |   NN |   signal(SIGINT, int_handler);
-           |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-           |      |         |
-           |      |         (4) registering 'void int_handler(int)' as signal handler
-           |
-  event 5
-    |
-    |cc1plus:
-    | (5): later on, when the signal is delivered to the process
-    |
-    +--> 'void int_handler(int)': events 6-7
-           |
-           |   NN | static void int_handler(int signum)
-           |      |             ^~~~~~~~~~~
-           |      |             |
-           |      |             (6) entry to 'int_handler'
-           |   NN | {
-           |   NN |   custom_logger("got signal");
-           |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-           |      |                |
-           |      |                (7) calling 'custom_logger' from 'int_handler'
-           |
-           +--> 'void custom_logger(const char*)': events 8-9
-                  |
-                  |   NN | void custom_logger(const char *msg)
-                  |      |      ^~~~~~~~~~~~~
-                  |      |      |
-                  |      |      (8) entry to 'custom_logger'
-                  |   NN | {
-                  |   NN |   fprintf(stderr, "LOG: %s", msg);
-                  |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                  |      |          |
-                  |      |          (9) call to 'int fprintf(FILE*, const char*, ...)' from within signal handler
-                  |
-  { dg-end-multiline-output "" { target c++ } } */
+  { dg-end-multiline-output "" } */