mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 12:11:08 +08:00
analyzer: log the stashing of named constants [PR107711]
PR analyzer/107711 seems to be a bug in how named constants are looked up by the analyzer in the C frontend. To help debug this, this patch extends -fdump-analyzer and -fdump-analyzer-stderr so that they dump this part of the analyzer's startup. gcc/analyzer/ChangeLog: PR analyzer/107711 * analyzer-language.cc: Include "diagnostic.h". (maybe_stash_named_constant): Add logger param and use it to log the name being looked up, and the result. (stash_named_constants): New, splitting out from... (on_finish_translation_unit): ...this function. Call get_or_create_logfile and use the result to create a logger instance, passing it to stash_named_constants. * analyzer.h (get_or_create_any_logfile): New decl. * engine.cc (dump_fout, owns_dump_fout): New globals, split out from run_checkers. (get_or_create_any_logfile): New function, split out from... (run_checkers): ...here, so that the logfile can be opened by on_finish_translation_unit. Clear the globals when closing the dump file. gcc/testsuite/ChangeLog: PR analyzer/107711 * gcc.dg/analyzer/fdump-analyzer-1.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
bdd784fc48
commit
6e4962810f
gcc
@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "analyzer/analyzer.h"
|
||||
#include "analyzer/analyzer-language.h"
|
||||
#include "analyzer/analyzer-logging.h"
|
||||
#include "diagnostic.h"
|
||||
|
||||
/* Map from identifier to INTEGER_CST. */
|
||||
static GTY (()) hash_map <tree, tree> *analyzer_stashed_constants;
|
||||
@ -39,8 +40,12 @@ namespace ana {
|
||||
If found, stash its value within analyzer_stashed_constants. */
|
||||
|
||||
static void
|
||||
maybe_stash_named_constant (const translation_unit &tu, const char *name)
|
||||
maybe_stash_named_constant (logger *logger,
|
||||
const translation_unit &tu,
|
||||
const char *name)
|
||||
{
|
||||
LOG_FUNC_1 (logger, "name: %qs", name);
|
||||
|
||||
if (!analyzer_stashed_constants)
|
||||
analyzer_stashed_constants = hash_map<tree, tree>::create_ggc ();
|
||||
|
||||
@ -49,7 +54,30 @@ maybe_stash_named_constant (const translation_unit &tu, const char *name)
|
||||
{
|
||||
gcc_assert (TREE_CODE (t) == INTEGER_CST);
|
||||
analyzer_stashed_constants->put (id, t);
|
||||
if (logger)
|
||||
logger->log ("%qs: %qE", name, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger)
|
||||
logger->log ("%qs: not found", name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Call into TU to try to find values for the names we care about.
|
||||
If found, stash their values within analyzer_stashed_constants. */
|
||||
|
||||
static void
|
||||
stash_named_constants (logger *logger, const translation_unit &tu)
|
||||
{
|
||||
LOG_SCOPE (logger);
|
||||
|
||||
/* Stash named constants for use by sm-fd.cc */
|
||||
maybe_stash_named_constant (logger, tu, "O_ACCMODE");
|
||||
maybe_stash_named_constant (logger, tu, "O_RDONLY");
|
||||
maybe_stash_named_constant (logger, tu, "O_WRONLY");
|
||||
maybe_stash_named_constant (logger, tu, "SOCK_STREAM");
|
||||
maybe_stash_named_constant (logger, tu, "SOCK_DGRAM");
|
||||
}
|
||||
|
||||
/* Hook for frontend to call into analyzer when TU finishes.
|
||||
@ -68,12 +96,12 @@ on_finish_translation_unit (const translation_unit &tu)
|
||||
if (!flag_analyzer)
|
||||
return;
|
||||
|
||||
/* Stash named constants for use by sm-fd.cc */
|
||||
maybe_stash_named_constant (tu, "O_ACCMODE");
|
||||
maybe_stash_named_constant (tu, "O_RDONLY");
|
||||
maybe_stash_named_constant (tu, "O_WRONLY");
|
||||
maybe_stash_named_constant (tu, "SOCK_STREAM");
|
||||
maybe_stash_named_constant (tu, "SOCK_DGRAM");
|
||||
FILE *logfile = get_or_create_any_logfile ();
|
||||
log_user the_logger (NULL);
|
||||
if (logfile)
|
||||
the_logger.set_logger (new logger (logfile, 0, 0,
|
||||
*global_dc->printer));
|
||||
stash_named_constants (the_logger.get_logger (), tu);
|
||||
}
|
||||
|
||||
/* Lookup NAME in the named constants stashed when the frontend TU finished.
|
||||
|
@ -324,6 +324,8 @@ public:
|
||||
extern tree get_stashed_constant_by_name (const char *name);
|
||||
extern void log_stashed_constants (logger *logger);
|
||||
|
||||
extern FILE *get_or_create_any_logfile ();
|
||||
|
||||
} // namespace ana
|
||||
|
||||
extern bool is_special_named_call_p (const gcall *call, const char *funcname,
|
||||
|
@ -6144,6 +6144,34 @@ impl_run_checkers (logger *logger)
|
||||
delete purge_map;
|
||||
}
|
||||
|
||||
/* Handle -fdump-analyzer and -fdump-analyzer-stderr. */
|
||||
static FILE *dump_fout = NULL;
|
||||
|
||||
/* Track if we're responsible for closing dump_fout. */
|
||||
static bool owns_dump_fout = false;
|
||||
|
||||
/* If dumping is enabled, attempt to create dump_fout if it hasn't already
|
||||
been opened. Return it. */
|
||||
|
||||
FILE *
|
||||
get_or_create_any_logfile ()
|
||||
{
|
||||
if (!dump_fout)
|
||||
{
|
||||
if (flag_dump_analyzer_stderr)
|
||||
dump_fout = stderr;
|
||||
else if (flag_dump_analyzer)
|
||||
{
|
||||
char *dump_filename = concat (dump_base_name, ".analyzer.txt", NULL);
|
||||
dump_fout = fopen (dump_filename, "w");
|
||||
free (dump_filename);
|
||||
if (dump_fout)
|
||||
owns_dump_fout = true;
|
||||
}
|
||||
}
|
||||
return dump_fout;
|
||||
}
|
||||
|
||||
/* External entrypoint to the analysis "engine".
|
||||
Set up any dumps, then call impl_run_checkers. */
|
||||
|
||||
@ -6153,23 +6181,9 @@ run_checkers ()
|
||||
/* Save input_location. */
|
||||
location_t saved_input_location = input_location;
|
||||
|
||||
/* Handle -fdump-analyzer and -fdump-analyzer-stderr. */
|
||||
FILE *dump_fout = NULL;
|
||||
/* Track if we're responsible for closing dump_fout. */
|
||||
bool owns_dump_fout = false;
|
||||
if (flag_dump_analyzer_stderr)
|
||||
dump_fout = stderr;
|
||||
else if (flag_dump_analyzer)
|
||||
{
|
||||
char *dump_filename = concat (dump_base_name, ".analyzer.txt", NULL);
|
||||
dump_fout = fopen (dump_filename, "w");
|
||||
free (dump_filename);
|
||||
if (dump_fout)
|
||||
owns_dump_fout = true;
|
||||
}
|
||||
|
||||
{
|
||||
log_user the_logger (NULL);
|
||||
get_or_create_any_logfile ();
|
||||
if (dump_fout)
|
||||
the_logger.set_logger (new logger (dump_fout, 0, 0,
|
||||
*global_dc->printer));
|
||||
@ -6182,7 +6196,11 @@ run_checkers ()
|
||||
}
|
||||
|
||||
if (owns_dump_fout)
|
||||
fclose (dump_fout);
|
||||
{
|
||||
fclose (dump_fout);
|
||||
owns_dump_fout = false;
|
||||
dump_fout = NULL;
|
||||
}
|
||||
|
||||
/* Restore input_location. Subsequent passes may assume that input_location
|
||||
is some arbitrary value *not* in the block tree, which might be violated
|
||||
|
14
gcc/testsuite/gcc.dg/analyzer/fdump-analyzer-1.c
Normal file
14
gcc/testsuite/gcc.dg/analyzer/fdump-analyzer-1.c
Normal file
@ -0,0 +1,14 @@
|
||||
/* { dg-additional-options "-fdump-analyzer" } */
|
||||
|
||||
void test (void)
|
||||
{
|
||||
}
|
||||
|
||||
/* Verify that we log the named constants that we look up in the TU
|
||||
(before the analysis pass runs).
|
||||
{ dg-final { scan-file fdump-analyzer-1.c.analyzer.txt "maybe_stash_named_constant: name: 'O_ACCMODE'" } }
|
||||
|
||||
Verify that we log the main part of the analysis (part of the
|
||||
analysis pass):
|
||||
{ dg-final { scan-file fdump-analyzer-1.c.analyzer.txt "ana::run_checkers" } }
|
||||
*/
|
Loading…
x
Reference in New Issue
Block a user