analyzer: show region creation events for uninit warnings
When reviewing the output of -fanalyzer on PR analyzer/104224 I noticed that despite very verbose paths, the diagnostic paths for -Wanalyzer-use-of-uninitialized-value don't show where the uninitialized memory is allocated. This patch adapts and simplifies material from "[PATCH 3/6] analyzer: implement infoleak detection" https://gcc.gnu.org/pipermail/gcc-patches/2021-November/584377.html in order to add region creation events for the pertinent region (whether on the stack or heap). For example, this patch extends: malloc-1.c: In function 'test_40': malloc-1.c:461:5: warning: use of uninitialized value '*p' [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 461 | i = *p; | ~~^~~~ 'test_40': event 1 | | 461 | i = *p; | | ~~^~~~ | | | | | (1) use of uninitialized value '*p' here | to: malloc-1.c: In function 'test_40': malloc-1.c:461:5: warning: use of uninitialized value '*p' [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 461 | i = *p; | ~~^~~~ 'test_40': events 1-2 | | 460 | int *p = (int*)malloc(sizeof(int*)); | | ^~~~~~~~~~~~~~~~~~~~ | | | | | (1) region created on heap here | 461 | i = *p; | | ~~~~~~ | | | | | (2) use of uninitialized value '*p' here | and this helps readability of the resulting warnings, especially in more complicated cases. gcc/analyzer/ChangeLog: * checker-path.cc (event_kind_to_string): Handle EK_REGION_CREATION. (region_creation_event::region_creation_event): New. (region_creation_event::get_desc): New. (checker_path::add_region_creation_event): New. * checker-path.h (enum event_kind): Add EK_REGION_CREATION. (class region_creation_event): New subclass. (checker_path::add_region_creation_event): New decl. * diagnostic-manager.cc (diagnostic_manager::emit_saved_diagnostic): Pass NULL for new param to add_events_for_eedge when handling trailing eedge. (diagnostic_manager::build_emission_path): Create an interesting_t instance, allow the pending diagnostic to populate it, and pass it to the calls to add_events_for_eedge. (diagnostic_manager::add_events_for_eedge): Add "interest" param. Use it to add region_creation_events for on-stack regions created within at function entry, and when pertinent dynamically-sized regions are created. (diagnostic_manager::prune_for_sm_diagnostic): Add case for EK_REGION_CREATION. * diagnostic-manager.h (diagnostic_manager::add_events_for_eedge): Add "interest" param. * pending-diagnostic.cc: Include "selftest.h", "tristate.h", "analyzer/call-string.h", "analyzer/program-point.h", "analyzer/store.h", and "analyzer/region-model.h". (interesting_t::add_region_creation): New. (interesting_t::dump_to_pp): New. * pending-diagnostic.h (struct interesting_t): New. (pending_diagnostic::mark_interesting_stuff): New vfunc. * region-model.cc (poisoned_value_diagnostic::poisoned_value_diagnostic): Add (poisoned_value_diagnostic::operator==): Compare m_pkind and m_src_region fields. (poisoned_value_diagnostic::mark_interesting_stuff): New. (poisoned_value_diagnostic::m_src_region): New. (region_model::check_for_poison): Call get_region_for_poisoned_expr for uninit values and pass the resul to the diagnostic. (region_model::get_region_for_poisoned_expr): New. (region_model::deref_rvalue): Pass NULL for poisoned_value_diagnostic's src_region. * region-model.h (region_model::get_region_for_poisoned_expr): New decl. * region.h (frame_region::get_fndecl): New. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/data-model-1.c: Add dg-message directives for expected region creation events. * gcc.dg/analyzer/malloc-1.c: Likewise. * gcc.dg/analyzer/memset-CVE-2017-18549-1.c: Likewise. * gcc.dg/analyzer/pr101547.c: Likewise. * gcc.dg/analyzer/pr101875.c: Likewise. * gcc.dg/analyzer/pr101962.c: Likewise. * gcc.dg/analyzer/pr104224.c: Likewise. * gcc.dg/analyzer/pr94047.c: Likewise. * gcc.dg/analyzer/symbolic-1.c: Likewise. * gcc.dg/analyzer/uninit-1.c: Likewise. * gcc.dg/analyzer/uninit-4.c: Likewise. * gcc.dg/analyzer/uninit-alloca.c: New test. * gcc.dg/analyzer/uninit-pr94713.c: Add dg-message directive for expected region creation event. * gcc.dg/analyzer/uninit-pr94714.c: Likewise. * gcc.dg/analyzer/zlib-3.c: Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
f21f22d1ba
commit
00e7d024af
24 changed files with 265 additions and 36 deletions
|
@ -81,6 +81,8 @@ event_kind_to_string (enum event_kind ek)
|
|||
return "EK_CUSTOM";
|
||||
case EK_STMT:
|
||||
return "EK_STMT";
|
||||
case EK_REGION_CREATION:
|
||||
return "EK_REGION_CREATION";
|
||||
case EK_FUNCTION_ENTRY:
|
||||
return "EK_FUNCTION_ENTRY";
|
||||
case EK_STATE_CHANGE:
|
||||
|
@ -199,6 +201,34 @@ statement_event::get_desc (bool) const
|
|||
return label_text::take (xstrdup (pp_formatted_text (&pp)));
|
||||
}
|
||||
|
||||
/* class region_creation_event : public checker_event. */
|
||||
|
||||
region_creation_event::region_creation_event (const region *reg,
|
||||
location_t loc,
|
||||
tree fndecl,
|
||||
int depth)
|
||||
: checker_event (EK_REGION_CREATION, loc, fndecl, depth),
|
||||
m_reg (reg)
|
||||
{
|
||||
}
|
||||
|
||||
/* Implementation of diagnostic_event::get_desc vfunc for
|
||||
region_creation_event. */
|
||||
|
||||
label_text
|
||||
region_creation_event::get_desc (bool) const
|
||||
{
|
||||
switch (m_reg->get_memory_space ())
|
||||
{
|
||||
default:
|
||||
return label_text::borrow ("region created here");
|
||||
case MEMSPACE_STACK:
|
||||
return label_text::borrow ("region created on stack here");
|
||||
case MEMSPACE_HEAP:
|
||||
return label_text::borrow ("region created on heap here");
|
||||
}
|
||||
}
|
||||
|
||||
/* class function_entry_event : public checker_event. */
|
||||
|
||||
/* Implementation of diagnostic_event::get_desc vfunc for
|
||||
|
@ -991,6 +1021,17 @@ checker_path::debug () const
|
|||
}
|
||||
}
|
||||
|
||||
/* Add region_creation_event instance to this path for REG,
|
||||
describing whether REG is on the stack or heap. */
|
||||
|
||||
void
|
||||
checker_path::add_region_creation_event (const region *reg,
|
||||
location_t loc,
|
||||
tree fndecl, int depth)
|
||||
{
|
||||
add_event (new region_creation_event (reg, loc, fndecl, depth));
|
||||
}
|
||||
|
||||
/* Add a warning_event to the end of this path. */
|
||||
|
||||
void
|
||||
|
|
|
@ -31,6 +31,7 @@ enum event_kind
|
|||
EK_DEBUG,
|
||||
EK_CUSTOM,
|
||||
EK_STMT,
|
||||
EK_REGION_CREATION,
|
||||
EK_FUNCTION_ENTRY,
|
||||
EK_STATE_CHANGE,
|
||||
EK_START_CFG_EDGE,
|
||||
|
@ -58,6 +59,7 @@ extern const char *event_kind_to_string (enum event_kind ek);
|
|||
custom_event (EK_CUSTOM)
|
||||
precanned_custom_event
|
||||
statement_event (EK_STMT)
|
||||
region_creation_event (EK_REGION_CREATION)
|
||||
function_entry_event (EK_FUNCTION_ENTRY)
|
||||
state_change_event (EK_STATE_CHANGE)
|
||||
superedge_event
|
||||
|
@ -194,6 +196,21 @@ public:
|
|||
const program_state m_dst_state;
|
||||
};
|
||||
|
||||
/* A concrete event subclass describing the creation of a region that
|
||||
is significant for a diagnostic e.g. "region created on stack here". */
|
||||
|
||||
class region_creation_event : public checker_event
|
||||
{
|
||||
public:
|
||||
region_creation_event (const region *reg,
|
||||
location_t loc, tree fndecl, int depth);
|
||||
|
||||
label_text get_desc (bool) const FINAL OVERRIDE;
|
||||
|
||||
private:
|
||||
const region *m_reg;
|
||||
};
|
||||
|
||||
/* An event subclass describing the entry to a function. */
|
||||
|
||||
class function_entry_event : public checker_event
|
||||
|
@ -561,6 +578,10 @@ public:
|
|||
m_events[idx] = new_event;
|
||||
}
|
||||
|
||||
void add_region_creation_event (const region *reg,
|
||||
location_t loc,
|
||||
tree fndecl, int depth);
|
||||
|
||||
void add_final_event (const state_machine *sm,
|
||||
const exploded_node *enode, const gimple *stmt,
|
||||
tree var, state_machine::state_t state);
|
||||
|
|
|
@ -1222,7 +1222,7 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
|
|||
trailing eedge stashed, add any events for it. This is for use
|
||||
in handling longjmp, to show where a longjmp is rewinding to. */
|
||||
if (sd.m_trailing_eedge)
|
||||
add_events_for_eedge (pb, *sd.m_trailing_eedge, &emission_path);
|
||||
add_events_for_eedge (pb, *sd.m_trailing_eedge, &emission_path, NULL);
|
||||
|
||||
emission_path.prepare_for_emission (sd.m_d);
|
||||
|
||||
|
@ -1269,10 +1269,13 @@ diagnostic_manager::build_emission_path (const path_builder &pb,
|
|||
checker_path *emission_path) const
|
||||
{
|
||||
LOG_SCOPE (get_logger ());
|
||||
|
||||
interesting_t interest;
|
||||
pb.get_pending_diagnostic ()->mark_interesting_stuff (&interest);
|
||||
for (unsigned i = 0; i < epath.m_edges.length (); i++)
|
||||
{
|
||||
const exploded_edge *eedge = epath.m_edges[i];
|
||||
add_events_for_eedge (pb, *eedge, emission_path);
|
||||
add_events_for_eedge (pb, *eedge, emission_path, &interest);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1580,10 +1583,12 @@ struct null_assignment_sm_context : public sm_context
|
|||
void
|
||||
diagnostic_manager::add_events_for_eedge (const path_builder &pb,
|
||||
const exploded_edge &eedge,
|
||||
checker_path *emission_path) const
|
||||
checker_path *emission_path,
|
||||
interesting_t *interest) const
|
||||
{
|
||||
const exploded_node *src_node = eedge.m_src;
|
||||
const program_point &src_point = src_node->get_point ();
|
||||
const int src_stack_depth = src_point.get_stack_depth ();
|
||||
const exploded_node *dst_node = eedge.m_dest;
|
||||
const program_point &dst_point = dst_node->get_point ();
|
||||
const int dst_stack_depth = dst_point.get_stack_depth ();
|
||||
|
@ -1645,6 +1650,29 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb,
|
|||
(dst_point.get_supernode ()->get_start_location (),
|
||||
dst_point.get_fndecl (),
|
||||
dst_stack_depth));
|
||||
/* Create region_creation_events for on-stack regions within
|
||||
this frame. */
|
||||
if (interest)
|
||||
{
|
||||
unsigned i;
|
||||
const region *reg;
|
||||
FOR_EACH_VEC_ELT (interest->m_region_creation, i, reg)
|
||||
if (const frame_region *frame = reg->maybe_get_frame_region ())
|
||||
if (frame->get_fndecl () == dst_point.get_fndecl ())
|
||||
{
|
||||
const region *base_reg = reg->get_base_region ();
|
||||
if (tree decl = base_reg->maybe_get_decl ())
|
||||
if (DECL_P (decl)
|
||||
&& DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION)
|
||||
{
|
||||
emission_path->add_region_creation_event
|
||||
(reg,
|
||||
DECL_SOURCE_LOCATION (decl),
|
||||
dst_point.get_fndecl (),
|
||||
dst_stack_depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PK_BEFORE_STMT:
|
||||
|
@ -1700,6 +1728,42 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb,
|
|||
== dst_node->m_succs[0]->m_dest->get_point ())))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Look for changes in dynamic extents, which will identify
|
||||
the creation of heap-based regions and alloca regions. */
|
||||
if (interest)
|
||||
{
|
||||
const region_model *src_model = src_state.m_region_model;
|
||||
const region_model *dst_model = dst_state.m_region_model;
|
||||
if (src_model->get_dynamic_extents ()
|
||||
!= dst_model->get_dynamic_extents ())
|
||||
{
|
||||
unsigned i;
|
||||
const region *reg;
|
||||
FOR_EACH_VEC_ELT (interest->m_region_creation, i, reg)
|
||||
{
|
||||
const region *base_reg = reg->get_base_region ();
|
||||
const svalue *old_extents
|
||||
= src_model->get_dynamic_extents (base_reg);
|
||||
const svalue *new_extents
|
||||
= dst_model->get_dynamic_extents (base_reg);
|
||||
if (old_extents == NULL && new_extents != NULL)
|
||||
switch (base_reg->get_kind ())
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case RK_HEAP_ALLOCATED:
|
||||
case RK_ALLOCA:
|
||||
emission_path->add_region_creation_event
|
||||
(reg,
|
||||
src_point.get_location (),
|
||||
src_point.get_fndecl (),
|
||||
src_stack_depth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2004,6 +2068,10 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
|
|||
}
|
||||
break;
|
||||
|
||||
case EK_REGION_CREATION:
|
||||
/* Don't filter these. */
|
||||
break;
|
||||
|
||||
case EK_FUNCTION_ENTRY:
|
||||
if (m_verbosity < 1)
|
||||
{
|
||||
|
|
|
@ -141,7 +141,8 @@ private:
|
|||
|
||||
void add_events_for_eedge (const path_builder &pb,
|
||||
const exploded_edge &eedge,
|
||||
checker_path *emission_path) const;
|
||||
checker_path *emission_path,
|
||||
interesting_t *interest) const;
|
||||
|
||||
bool significant_edge_p (const path_builder &pb,
|
||||
const exploded_edge &eedge) const;
|
||||
|
|
|
@ -33,11 +33,43 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "diagnostic-event-id.h"
|
||||
#include "analyzer/sm.h"
|
||||
#include "analyzer/pending-diagnostic.h"
|
||||
#include "selftest.h"
|
||||
#include "tristate.h"
|
||||
#include "analyzer/call-string.h"
|
||||
#include "analyzer/program-point.h"
|
||||
#include "analyzer/store.h"
|
||||
#include "analyzer/region-model.h"
|
||||
|
||||
#if ENABLE_ANALYZER
|
||||
|
||||
namespace ana {
|
||||
|
||||
/* struct interesting_t. */
|
||||
|
||||
/* Mark the creation of REG as being interesting. */
|
||||
|
||||
void
|
||||
interesting_t::add_region_creation (const region *reg)
|
||||
{
|
||||
gcc_assert (reg);
|
||||
m_region_creation.safe_push (reg);
|
||||
}
|
||||
|
||||
void
|
||||
interesting_t::dump_to_pp (pretty_printer *pp, bool simple) const
|
||||
{
|
||||
pp_string (pp, "{ region creation: [");
|
||||
unsigned i;
|
||||
const region *reg;
|
||||
FOR_EACH_VEC_ELT (m_region_creation, i, reg)
|
||||
{
|
||||
if (i > 0)
|
||||
pp_string (pp, ", ");
|
||||
reg->dump_to_pp (pp, simple);
|
||||
}
|
||||
pp_string (pp, "]}");
|
||||
}
|
||||
|
||||
/* Generate a label_text by printing FMT.
|
||||
|
||||
Use a clone of the global_dc for formatting callbacks.
|
||||
|
|
|
@ -23,6 +23,22 @@ along with GCC; see the file COPYING3. If not see
|
|||
|
||||
namespace ana {
|
||||
|
||||
/* A bundle of information about things that are of interest to a
|
||||
pending_diagnostic.
|
||||
|
||||
For now, merely the set of regions that are pertinent to the
|
||||
diagnostic, so that we can notify the user about when they
|
||||
were created. */
|
||||
|
||||
struct interesting_t
|
||||
{
|
||||
void add_region_creation (const region *reg);
|
||||
|
||||
void dump_to_pp (pretty_printer *pp, bool simple) const;
|
||||
|
||||
auto_vec<const region *> m_region_creation;
|
||||
};
|
||||
|
||||
/* Various bundles of information used for generating more precise
|
||||
messages for events within a diagnostic_path, for passing to the
|
||||
various "describe_*" vfuncs of pending_diagnostic. See those
|
||||
|
@ -282,6 +298,14 @@ class pending_diagnostic
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Vfunc for registering additional information of interest to this
|
||||
diagnostic. */
|
||||
|
||||
virtual void mark_interesting_stuff (interesting_t *)
|
||||
{
|
||||
/* Default no-op implementation. */
|
||||
}
|
||||
};
|
||||
|
||||
/* A template to make it easier to make subclasses of pending_diagnostic.
|
||||
|
|
|
@ -454,8 +454,10 @@ class poisoned_value_diagnostic
|
|||
: public pending_diagnostic_subclass<poisoned_value_diagnostic>
|
||||
{
|
||||
public:
|
||||
poisoned_value_diagnostic (tree expr, enum poison_kind pkind)
|
||||
: m_expr (expr), m_pkind (pkind)
|
||||
poisoned_value_diagnostic (tree expr, enum poison_kind pkind,
|
||||
const region *src_region)
|
||||
: m_expr (expr), m_pkind (pkind),
|
||||
m_src_region (src_region)
|
||||
{}
|
||||
|
||||
const char *get_kind () const FINAL OVERRIDE { return "poisoned_value_diagnostic"; }
|
||||
|
@ -467,7 +469,9 @@ public:
|
|||
|
||||
bool operator== (const poisoned_value_diagnostic &other) const
|
||||
{
|
||||
return m_expr == other.m_expr;
|
||||
return (m_expr == other.m_expr
|
||||
&& m_pkind == other.m_pkind
|
||||
&& m_src_region == other.m_src_region);
|
||||
}
|
||||
|
||||
bool emit (rich_location *rich_loc) FINAL OVERRIDE
|
||||
|
@ -528,9 +532,16 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void mark_interesting_stuff (interesting_t *interest) FINAL OVERRIDE
|
||||
{
|
||||
if (m_src_region)
|
||||
interest->add_region_creation (m_src_region);
|
||||
}
|
||||
|
||||
private:
|
||||
tree m_expr;
|
||||
enum poison_kind m_pkind;
|
||||
const region *m_src_region;
|
||||
};
|
||||
|
||||
/* A subclass of pending_diagnostic for complaining about shifts
|
||||
|
@ -839,7 +850,11 @@ region_model::check_for_poison (const svalue *sval,
|
|||
fixup_tree_for_diagnostic. */
|
||||
tree diag_arg = fixup_tree_for_diagnostic (expr);
|
||||
enum poison_kind pkind = poisoned_sval->get_poison_kind ();
|
||||
if (ctxt->warn (new poisoned_value_diagnostic (diag_arg, pkind)))
|
||||
const region *src_region = NULL;
|
||||
if (pkind == POISON_KIND_UNINIT)
|
||||
src_region = get_region_for_poisoned_expr (expr);
|
||||
if (ctxt->warn (new poisoned_value_diagnostic (diag_arg, pkind,
|
||||
src_region)))
|
||||
{
|
||||
/* We only want to report use of a poisoned value at the first
|
||||
place it gets used; return an unknown value to avoid generating
|
||||
|
@ -853,6 +868,24 @@ region_model::check_for_poison (const svalue *sval,
|
|||
return sval;
|
||||
}
|
||||
|
||||
/* Attempt to get a region for describing EXPR, the source of region of
|
||||
a poisoned_svalue for use in a poisoned_value_diagnostic.
|
||||
Return NULL if there is no good region to use. */
|
||||
|
||||
const region *
|
||||
region_model::get_region_for_poisoned_expr (tree expr) const
|
||||
{
|
||||
if (TREE_CODE (expr) == SSA_NAME)
|
||||
{
|
||||
tree decl = SSA_NAME_VAR (expr);
|
||||
if (decl && DECL_P (decl))
|
||||
expr = decl;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return get_lvalue (expr, NULL);
|
||||
}
|
||||
|
||||
/* Update this model for the ASSIGN stmt, using CTXT to report any
|
||||
diagnostics. */
|
||||
|
||||
|
@ -2134,7 +2167,7 @@ region_model::deref_rvalue (const svalue *ptr_sval, tree ptr_tree,
|
|||
const poisoned_svalue *poisoned_sval
|
||||
= as_a <const poisoned_svalue *> (ptr_sval);
|
||||
enum poison_kind pkind = poisoned_sval->get_poison_kind ();
|
||||
ctxt->warn (new poisoned_value_diagnostic (ptr, pkind));
|
||||
ctxt->warn (new poisoned_value_diagnostic (ptr, pkind, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -813,6 +813,7 @@ class region_model
|
|||
const svalue *check_for_poison (const svalue *sval,
|
||||
tree expr,
|
||||
region_model_context *ctxt) const;
|
||||
const region * get_region_for_poisoned_expr (tree expr) const;
|
||||
|
||||
void check_dynamic_size_for_taint (enum memory_space mem_space,
|
||||
const svalue *size_in_bytes,
|
||||
|
|
|
@ -298,6 +298,7 @@ public:
|
|||
/* Accessors. */
|
||||
const frame_region *get_calling_frame () const { return m_calling_frame; }
|
||||
function *get_function () const { return m_fun; }
|
||||
tree get_fndecl () const { return get_function ()->decl; }
|
||||
int get_index () const { return m_index; }
|
||||
int get_stack_depth () const { return m_index + 1; }
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ int test_12 (void)
|
|||
/* Use of uninit value. */
|
||||
int test_12a (void)
|
||||
{
|
||||
int i;
|
||||
int i; /* { dg-message "region created on stack here" } */
|
||||
return i; /* { dg-warning "use of uninitialized value 'i'" } */
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ void test_12b (void *p, void *q)
|
|||
|
||||
int test_12c (void)
|
||||
{
|
||||
int i;
|
||||
int i; /* { dg-message "region created on stack here" } */
|
||||
int j;
|
||||
|
||||
j = i; /* { dg-warning "use of uninitialized value 'i'" } */
|
||||
|
@ -349,7 +349,7 @@ void test_18 (int i)
|
|||
|
||||
void test_19 (void)
|
||||
{
|
||||
int i, j;
|
||||
int i, j; /* { dg-message "region created on stack here" } */
|
||||
/* Compare two uninitialized locals. */
|
||||
__analyzer_eval (i == j); /* { dg-warning "UNKNOWN" "unknown " } */
|
||||
/* { dg-warning "use of uninitialized value 'i'" "uninit i" { target *-*-* } .-1 } */
|
||||
|
@ -633,7 +633,7 @@ void test_29a (struct coord p[])
|
|||
|
||||
void test_29b (void)
|
||||
{
|
||||
struct coord p[11];
|
||||
struct coord p[11]; /* { dg-message "region created on stack here" } */
|
||||
struct coord *q;
|
||||
|
||||
p[0].x = 100024;
|
||||
|
@ -819,7 +819,7 @@ void test_36 (int i)
|
|||
|
||||
int test_37 (void)
|
||||
{
|
||||
int *ptr;
|
||||
int *ptr; /* { dg-message "region created on stack here" } */
|
||||
return *ptr; /* { dg-warning "use of uninitialized value 'ptr'" } */
|
||||
}
|
||||
|
||||
|
@ -827,7 +827,7 @@ int test_37 (void)
|
|||
|
||||
void test_37a (int i)
|
||||
{
|
||||
int *ptr;
|
||||
int *ptr; /* { dg-message "region created on stack here" } */
|
||||
*ptr = i; /* { dg-warning "use of uninitialized value 'ptr'" } */
|
||||
}
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ void test_15 (void)
|
|||
|
||||
void test_16 (void)
|
||||
{
|
||||
void *p, *q;
|
||||
void *p, *q; /* { dg-message "region created on stack here" } */
|
||||
|
||||
p = malloc (1024);
|
||||
if (!p)
|
||||
|
@ -457,7 +457,7 @@ test_39 (int i)
|
|||
int *
|
||||
test_40 (int i)
|
||||
{
|
||||
int *p = (int*)malloc(sizeof(int*));
|
||||
int *p = (int*)malloc(sizeof(int*)); /* { dg-message "region created on heap here" } */
|
||||
i = *p; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" "possibly-null" } */
|
||||
/* { dg-warning "use of uninitialized value '\\*p'" "uninit" { target *-*-*} .-1 } */
|
||||
return p;
|
||||
|
|
|
@ -47,7 +47,7 @@ static int aac_send_raw_srb(/* [...snip...] */)
|
|||
|
||||
/* [...snip...] */
|
||||
|
||||
struct aac_srb_reply reply;
|
||||
struct aac_srb_reply reply; /* { dg-message "region created on stack here" } */
|
||||
|
||||
reply.status = ST_OK;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ void
|
|||
k2 (void)
|
||||
{
|
||||
char *setfiles[1];
|
||||
int i;
|
||||
int i; /* { dg-message "region created on stack here" } */
|
||||
|
||||
setfiles[i] = fopen ("", ""); /* { dg-warning "use of uninitialized value 'i'" } */
|
||||
} /* { dg-warning "leak of FILE" } */
|
||||
|
|
|
@ -8,7 +8,7 @@ void
|
|||
k2 (void)
|
||||
{
|
||||
char *setfiles[1];
|
||||
int i;
|
||||
int i; /* { dg-message "region created on stack here" } */
|
||||
|
||||
setfiles[i] = fopen("", ""); /* { dg-warning "use of uninitialized value 'i'" } */
|
||||
if (!setfiles[i]) /* { dg-warning "use of uninitialized value 'i'" } */
|
||||
|
|
|
@ -16,7 +16,7 @@ maybe_inc_int_ptr (int *ptr)
|
|||
int
|
||||
test_1 (void)
|
||||
{
|
||||
int stack;
|
||||
int stack; /* { dg-message "region created on stack here" } */
|
||||
int *a = &stack;
|
||||
a = maybe_inc_int_ptr (a);
|
||||
a = maybe_inc_int_ptr (a);
|
||||
|
|
|
@ -73,11 +73,11 @@ enum {RED, AMBER, GREEN, BLACK};
|
|||
|
||||
int main(void)
|
||||
{
|
||||
struct test t;
|
||||
int num;
|
||||
struct test t; /* { dg-message "region created on stack here" } */
|
||||
int num; /* { dg-message "region created on stack here" } */
|
||||
int arry[10];
|
||||
int arry_2[10];
|
||||
int go;
|
||||
int arry_2[10]; /* { dg-message "region created on stack here" } */
|
||||
int go; /* { dg-message "region created on stack here" } */
|
||||
int color = BLACK;
|
||||
|
||||
func1(&t);
|
||||
|
|
|
@ -12,7 +12,7 @@ bar (struct list *l)
|
|||
void
|
||||
foo (void)
|
||||
{
|
||||
struct list l;
|
||||
struct list l; /* { dg-message "region created on stack here" } */
|
||||
tlist t = l; /* { dg-warning "use of uninitialized value 'l'" } */
|
||||
for (;;)
|
||||
bar (&t);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
void test_1 (char a, char b, char c, char d, char e, char f,
|
||||
int i, int j)
|
||||
{
|
||||
char arr[1024];
|
||||
char arr[1024]; /* { dg-message "region created on stack here" } */
|
||||
arr[2] = a; /* (1) */
|
||||
arr[3] = b; /* (2) */
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
int test_1 (void)
|
||||
{
|
||||
int i;
|
||||
int i; /* { dg-message "region created on stack here" } */
|
||||
return i; /* { dg-warning "use of uninitialized value 'i'" } */
|
||||
}
|
||||
|
||||
int test_2 (void)
|
||||
{
|
||||
int i;
|
||||
int i; /* { dg-message "region created on stack here" } */
|
||||
return i * 2; /* { dg-warning "use of uninitialized value 'i'" } */
|
||||
}
|
||||
|
||||
|
@ -20,13 +20,13 @@ int test_3 (void)
|
|||
|
||||
int test_4 (void)
|
||||
{
|
||||
int *p;
|
||||
int *p; /* { dg-message "region created on stack here" } */
|
||||
return *p; /* { dg-warning "use of uninitialized value 'p'" } */
|
||||
}
|
||||
|
||||
int test_5 (int flag, int *q)
|
||||
{
|
||||
int *p;
|
||||
int *p; /* { dg-message "region created on stack here" } */
|
||||
if (flag) /* { dg-message "following 'false' branch" } */
|
||||
p = q;
|
||||
|
||||
|
@ -39,6 +39,6 @@ int test_5 (int flag, int *q)
|
|||
|
||||
int test_6 (int i)
|
||||
{
|
||||
int arr[10];
|
||||
int arr[10]; /* { dg-message "region created on stack here" } */
|
||||
return arr[i]; /* { dg-warning "use of uninitialized value 'arr\\\[i\\\]'" } */
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ struct foo
|
|||
struct foo *__attribute__((noinline))
|
||||
alloc_foo (int a, int b)
|
||||
{
|
||||
struct foo *p = malloc (sizeof (struct foo));
|
||||
struct foo *p = malloc (sizeof (struct foo)); /* { dg-message "region created on heap here" } */
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->i = a;
|
||||
|
|
7
gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c
Normal file
7
gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* { dg-require-effective-target alloca } */
|
||||
|
||||
int test_1 (void)
|
||||
{
|
||||
int *p = __builtin_alloca (sizeof (int)); /* { dg-message "region created on stack here" } */
|
||||
return *p; /* { dg-warning "use of uninitialized value '\\*p'" } */
|
||||
}
|
|
@ -3,7 +3,7 @@ void f2 (int);
|
|||
|
||||
int foo (void)
|
||||
{
|
||||
int *p;
|
||||
int *p; /* { dg-message "region created on stack here" } */
|
||||
|
||||
f1 (p); /* { dg-warning "use of uninitialized value 'p'" } */
|
||||
f2 (p[0]); /* { dg-warning "use of uninitialized value 'p'" } */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
int main (void)
|
||||
{
|
||||
int *p;
|
||||
int i;
|
||||
int i; /* { dg-message "region created on stack here" } */
|
||||
|
||||
p = &i; /* { dg-bogus "uninitialized" } */
|
||||
printf ("%d\n", p[0]); /* { dg-warning "use of uninitialized value '\\*p'" } */
|
||||
|
|
|
@ -46,7 +46,7 @@ static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e,
|
|||
uInt mask;
|
||||
register uInt *p;
|
||||
inflate_huft *q;
|
||||
struct inflate_huft_s r;
|
||||
struct inflate_huft_s r; /* { dg-message "region created on stack here" } */
|
||||
inflate_huft *u[15];
|
||||
register int w;
|
||||
uInt x[15 + 1];
|
||||
|
|
Loading…
Add table
Reference in a new issue