aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/known-function-manager.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-05-03 09:05:29 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2024-05-03 09:05:29 -0400
commit5219414f3cde3c1037e289a6654cd722cfa75dea (patch)
treead39c0e8e7f8f22f6e0bdc5b336880703bb23242 /gcc/analyzer/known-function-manager.cc
parenta2e9032deaf9dbcff329d650f61e36c6a5aa1fc4 (diff)
downloadgcc-5219414f3cde3c1037e289a6654cd722cfa75dea.zip
gcc-5219414f3cde3c1037e289a6654cd722cfa75dea.tar.gz
gcc-5219414f3cde3c1037e289a6654cd722cfa75dea.tar.bz2
testsuite: fix analyzer C++ failures on Solaris [PR111475]
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>
Diffstat (limited to 'gcc/analyzer/known-function-manager.cc')
-rw-r--r--gcc/analyzer/known-function-manager.cc38
1 files changed, 37 insertions, 1 deletions
diff --git a/gcc/analyzer/known-function-manager.cc b/gcc/analyzer/known-function-manager.cc
index 9f7aeb8..d24e5b8 100644
--- a/gcc/analyzer/known-function-manager.cc
+++ b/gcc/analyzer/known-function-manager.cc
@@ -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;
}
@@ -64,6 +66,15 @@ known_function_manager::add (const char *name,
}
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 */