aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/analyzer/analyzer.cc15
-rw-r--r--gcc/analyzer/analyzer.h4
-rw-r--r--gcc/analyzer/engine.cc2
-rw-r--r--gcc/analyzer/kf.cc22
-rw-r--r--gcc/analyzer/known-function-manager.cc38
-rw-r--r--gcc/analyzer/known-function-manager.h5
-rw-r--r--gcc/analyzer/sm-file.cc8
-rw-r--r--gcc/analyzer/sm-malloc.cc1
-rw-r--r--gcc/analyzer/sm-signal.cc11
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c4
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c4
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-server.c (renamed from gcc/testsuite/c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c)4
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/fd-socket-meaning.c4
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c4
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/flexible-array-member-1.c6
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/pr106539.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c (renamed from gcc/testsuite/c-c++-common/analyzer/malloc-ipa-8-unchecked.c)46
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-4a.c (renamed from gcc/testsuite/c-c++-common/analyzer/signal-4a.c)53
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-4b.c (renamed from gcc/testsuite/c-c++-common/analyzer/signal-4b.c)65
19 files changed, 134 insertions, 164 deletions
diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc
index 7f5d3d5..2a15a3a 100644
--- a/gcc/analyzer/analyzer.cc
+++ b/gcc/analyzer/analyzer.cc
@@ -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);
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index d43812e3..334b0d3 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -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);
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index e0dc0e6..556e8a1 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -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;
}
diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
index 6931f07..c60e220 100644
--- a/gcc/analyzer/kf.cc
+++ b/gcc/analyzer/kf.cc
@@ -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
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 */
diff --git a/gcc/analyzer/known-function-manager.h b/gcc/analyzer/known-function-manager.h
index 81e42e1..cf93193 100644
--- a/gcc/analyzer/known-function-manager.h
+++ b/gcc/analyzer/known-function-manager.h
@@ -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];
};
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index 6739c31..f85b400 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -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
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index 4e11d6d..fc6718a 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -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);
diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc
index 93269ca..84603c5 100644
--- a/gcc/analyzer/sm-signal.cc
+++ b/gcc/analyzer/sm-signal.cc
@@ -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
diff --git a/gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c b/gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c
index fab8426..fd57d3b 100644
--- a/gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c
+++ b/gcc/testsuite/c-c++-common/analyzer/fd-glibc-byte-stream-socket.c
@@ -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>
diff --git a/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c b/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c
index 21dfe97..ee7e4b4 100644
--- a/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c
+++ b/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-client.c
@@ -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>
diff --git a/gcc/testsuite/c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c b/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-server.c
index 2e9cec4..7bc4568 100644
--- a/gcc/testsuite/c-c++-common/analyzer/fd-mappage-getaddrinfo-server.c
+++ b/gcc/testsuite/c-c++-common/analyzer/fd-manpage-getaddrinfo-server.c
@@ -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>
diff --git a/gcc/testsuite/c-c++-common/analyzer/fd-socket-meaning.c b/gcc/testsuite/c-c++-common/analyzer/fd-socket-meaning.c
index 82a199f..995d3a1 100644
--- a/gcc/testsuite/c-c++-common/analyzer/fd-socket-meaning.c
+++ b/gcc/testsuite/c-c++-common/analyzer/fd-socket-meaning.c
@@ -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>
diff --git a/gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c b/gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c
index 32264fd..c6af0a6 100644
--- a/gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c
+++ b/gcc/testsuite/c-c++-common/analyzer/fd-symbolic-socket.c
@@ -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>
diff --git a/gcc/testsuite/c-c++-common/analyzer/flexible-array-member-1.c b/gcc/testsuite/c-c++-common/analyzer/flexible-array-member-1.c
index 82dbcec..d794336 100644
--- a/gcc/testsuite/c-c++-common/analyzer/flexible-array-member-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/flexible-array-member-1.c
@@ -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;
}
diff --git a/gcc/testsuite/c-c++-common/analyzer/pr106539.c b/gcc/testsuite/c-c++-common/analyzer/pr106539.c
index fd27086..8745c1d 100644
--- a/gcc/testsuite/c-c++-common/analyzer/pr106539.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr106539.c
@@ -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;
diff --git a/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-8-unchecked.c b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c
index 5bc8e57..f2c10dd 100644
--- a/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-8-unchecked.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c
@@ -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 "" } */
diff --git a/gcc/testsuite/c-c++-common/analyzer/signal-4a.c b/gcc/testsuite/gcc.dg/analyzer/signal-4a.c
index b5c6012..538adae 100644
--- a/gcc/testsuite/c-c++-common/analyzer/signal-4a.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-4a.c
@@ -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 "" } */
diff --git a/gcc/testsuite/c-c++-common/analyzer/signal-4b.c b/gcc/testsuite/gcc.dg/analyzer/signal-4b.c
index d2b5db7..5bf8c82 100644
--- a/gcc/testsuite/c-c++-common/analyzer/signal-4b.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-4b.c
@@ -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 "" } */