+2020-04-28 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/94447
+ PR analyzer/94639
+ PR analyzer/94732
+ PR analyzer/94754
+ * doc/invoke.texi (Static Analyzer Options): Remove
+ -Wanalyzer-use-of-uninitialized-value.
+ (-Wno-analyzer-use-of-uninitialized-value): Remove item.
+
2020-04-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94809
+2020-04-28 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/94447
+ PR analyzer/94639
+ PR analyzer/94732
+ PR analyzer/94754
+ * analyzer.opt (Wanalyzer-use-of-uninitialized-value): Delete.
+ * program-state.cc (selftest::test_program_state_dumping): Update
+ expected dump result for removal of "uninit".
+ * region-model.cc (poison_kind_to_str): Delete POISON_KIND_UNINIT
+ case.
+ (root_region::ensure_stack_region): Initialize stack with null
+ svalue_id rather than with a typeless POISON_KIND_UNINIT value.
+ (root_region::ensure_heap_region): Likewise for the heap.
+ (region_model::dump_summary_of_rep_path_vars): Remove
+ summarization of uninit values.
+ (region_model::validate): Remove check that the stack has a
+ POISON_KIND_UNINIT value.
+ (poisoned_value_diagnostic::emit): Remove POISON_KIND_UNINIT
+ case.
+ (poisoned_value_diagnostic::describe_final_event): Likewise.
+ (selftest::test_dump): Update expected dump result for removal of
+ "uninit".
+ (selftest::test_svalue_equality): Remove "uninit" and "freed".
+ * region-model.h (enum poison_kind): Remove POISON_KIND_UNINIT.
+
2020-04-01 David Malcolm <dmalcolm@redhat.com>
PR analyzer/94378
Common Var(warn_analyzer_use_of_pointer_in_stale_stack_frame) Init(1) Warning
Warn about code paths in which a pointer to a stale stack frame is used.
-Wanalyzer-use-of-uninitialized-value
-Common Var(warn_analyzer_use_of_uninitialized_value) Init(1) Warning
-Warn about code paths in which an uninitialized value is used.
-
Wanalyzer-too-complex
Common Var(warn_analyzer_too_complex) Init(0) Warning
Warn if the code is too complicated for the analyzer to fully explore.
ASSERT_DUMP_EQ
(s, ext_state, false,
"rmodel: r0: {kind: `root', parent: null, sval: null}\n"
- "|-heap: r1: {kind: `heap', parent: r0, sval: sv0}\n"
- "| |: sval: sv0: {poisoned: uninit}\n"
+ "|-heap: r1: {kind: `heap', parent: r0, sval: null}\n"
"| `-r2: {kind: `symbolic', parent: r1, sval: null, possibly_null: true}\n"
"`-globals: r3: {kind: `globals', parent: r0, sval: null, map: {`p': r4}}\n"
- " `-`p': r4: {kind: `primitive', parent: r3, sval: sv1, type: `void *'}\n"
- " |: sval: sv1: {type: `void *', &r2}\n"
+ " `-`p': r4: {kind: `primitive', parent: r3, sval: sv0, type: `void *'}\n"
+ " |: sval: sv0: {type: `void *', &r2}\n"
" |: type: `void *'\n"
"svalues:\n"
- " sv0: {poisoned: uninit}\n"
- " sv1: {type: `void *', &r2}\n"
+ " sv0: {type: `void *', &r2}\n"
"constraint manager:\n"
" equiv classes:\n"
" constraints:\n"
- "malloc: {sv1: unchecked (`p')}\n");
+ "malloc: {sv0: unchecked (`p')}\n");
ASSERT_DUMP_EQ (s, ext_state, true,
- "rmodel: p: &r2 malloc: {sv1: unchecked (`p')}");
+ "rmodel: p: &r2 malloc: {sv0: unchecked (`p')}");
}
/* Verify that program_state::dump_to_pp works for string literals. */
{
default:
gcc_unreachable ();
- case POISON_KIND_UNINIT:
- return "uninit";
case POISON_KIND_FREED:
return "freed";
case POISON_KIND_POPPED_STACK:
{
if (m_stack_rid.null_p ())
{
- svalue_id uninit_sid
- = model->add_svalue (new poisoned_svalue (POISON_KIND_UNINIT,
- NULL_TREE));
m_stack_rid
= model->add_region (new stack_region (model->get_root_rid (),
- uninit_sid));
+ svalue_id::null ()));
}
return m_stack_rid;
}
{
if (m_heap_rid.null_p ())
{
- svalue_id uninit_sid
- = model->add_svalue (new poisoned_svalue (POISON_KIND_UNINIT,
- NULL_TREE));
m_heap_rid
= model->add_region (new heap_region (model->get_root_rid (),
- uninit_sid));
+ svalue_id::null ()));
}
return m_heap_rid;
}
unsigned i;
path_var *pv;
auto_vec<tree> unknown_trees;
- auto_vec<tree> uninit_trees;
FOR_EACH_VEC_ELT (*rep_path_vars, i, pv)
{
if (TREE_CODE (pv->m_tree) == STRING_CST)
{
poisoned_svalue *poisoned_sval = as_a <poisoned_svalue *> (sval);
enum poison_kind pkind = poisoned_sval->get_poison_kind ();
- if (pkind == POISON_KIND_UNINIT)
- uninit_trees.safe_push (pv->m_tree);
- else
- {
- dump_separator (pp, is_first);
- dump_tree (pp, pv->m_tree);
- pp_printf (pp, ": %s", poison_kind_to_str (pkind));
- }
+ dump_separator (pp, is_first);
+ dump_tree (pp, pv->m_tree);
+ pp_printf (pp, ": %s", poison_kind_to_str (pkind));
}
break;
case SK_SETJMP:
/* Print unknown and uninitialized values in consolidated form. */
dump_vec_of_tree (pp, is_first, unknown_trees, "unknown");
- dump_vec_of_tree (pp, is_first, uninit_trees, "uninit");
}
/* Assert that this object is valid. */
r->validate (*this);
// TODO: anything else?
-
- /* Verify that the stack region (if any) has an "uninitialized" value. */
- region *stack_region = get_root_region ()->get_stack_region (this);
- if (stack_region)
- {
- svalue_id stack_value_sid = stack_region->get_value_direct ();
- svalue *stack_value = get_svalue (stack_value_sid);
- gcc_assert (stack_value->get_kind () == SK_POISONED);
- poisoned_svalue *subclass = stack_value->dyn_cast_poisoned_svalue ();
- gcc_assert (subclass);
- gcc_assert (subclass->get_poison_kind () == POISON_KIND_UNINIT);
- }
}
/* Global data for use by svalue_id_cmp_by_constant_svalue. */
{
default:
gcc_unreachable ();
- case POISON_KIND_UNINIT:
- {
- diagnostic_metadata m;
- m.add_cwe (457); /* "CWE-457: Use of Uninitialized Variable". */
- return warning_meta (rich_loc, m,
- OPT_Wanalyzer_use_of_uninitialized_value,
- "use of uninitialized value %qE",
- m_expr);
- }
- break;
case POISON_KIND_FREED:
{
diagnostic_metadata m;
{
default:
gcc_unreachable ();
- case POISON_KIND_UNINIT:
- return ev.formatted_print ("use of uninitialized value %qE here",
- m_expr);
case POISON_KIND_FREED:
return ev.formatted_print ("use after %<free%> of %qE here",
m_expr);
ASSERT_DUMP_EQ (model, false,
"r0: {kind: `root', parent: null, sval: null}\n"
- "|-stack: r1: {kind: `stack', parent: r0, sval: sv0}\n"
- "| |: sval: sv0: {poisoned: uninit}\n"
+ "|-stack: r1: {kind: `stack', parent: r0, sval: null}\n"
"|-globals: r2: {kind: `globals', parent: r0, sval: null, map: {}}\n"
- "`-heap: r3: {kind: `heap', parent: r0, sval: sv1}\n"
- " |: sval: sv1: {poisoned: uninit}\n"
+ "`-heap: r3: {kind: `heap', parent: r0, sval: null}\n"
"svalues:\n"
- " sv0: {poisoned: uninit}\n"
- " sv1: {poisoned: uninit}\n"
"constraint manager:\n"
" equiv classes:\n"
" constraints:\n");
ASSERT_NE (cst_int_42->hash (), cst_int_0->hash ());
ASSERT_NE (*cst_int_42, *cst_int_0);
- svalue *uninit = new poisoned_svalue (POISON_KIND_UNINIT, NULL_TREE);
- svalue *freed = new poisoned_svalue (POISON_KIND_FREED, NULL_TREE);
-
- ASSERT_EQ (uninit->hash (), uninit->hash ());
- ASSERT_EQ (*uninit, *uninit);
-
- ASSERT_NE (uninit->hash (), freed->hash ());
- ASSERT_NE (*uninit, *freed);
-
svalue *unknown_0 = new unknown_svalue (ptr_type_node);
svalue *unknown_1 = new unknown_svalue (ptr_type_node);
ASSERT_EQ (unknown_0->hash (), unknown_0->hash ());
/* Comparisons between different kinds of svalue. */
ASSERT_NE (*ptr_to_r0, *cst_int_42);
- ASSERT_NE (*ptr_to_r0, *uninit);
ASSERT_NE (*ptr_to_r0, *unknown_0);
ASSERT_NE (*cst_int_42, *ptr_to_r0);
- ASSERT_NE (*cst_int_42, *uninit);
ASSERT_NE (*cst_int_42, *unknown_0);
- ASSERT_NE (*uninit, *ptr_to_r0);
- ASSERT_NE (*uninit, *cst_int_42);
- ASSERT_NE (*uninit, *unknown_0);
ASSERT_NE (*unknown_0, *ptr_to_r0);
ASSERT_NE (*unknown_0, *cst_int_42);
- ASSERT_NE (*unknown_0, *uninit);
delete ptr_to_r0;
delete ptr_to_r1;
delete cst_int_42;
delete cst_int_0;
- delete uninit;
- delete freed;
delete unknown_0;
delete unknown_1;
}
enum poison_kind
{
- /* For use to describe uninitialized memory. */
- POISON_KIND_UNINIT,
-
/* For use to describe freed memory. */
POISON_KIND_FREED,
-Wanalyzer-tainted-array-index @gol
-Wanalyzer-unsafe-call-within-signal-handler @gol
-Wanalyzer-use-after-free @gol
--Wanalyzer-use-of-uninitialized-value @gol
-Wanalyzer-use-of-pointer-in-stale-stack-frame @gol
}
This diagnostic warns for paths through the code in which a pointer
is dereferenced that points to a variable in a stale stack frame.
-@item -Wno-analyzer-use-of-uninitialized-value
-@opindex Wanalyzer-use-of-uninitialized-value
-@opindex Wno-analyzer-use-of-uninitialized-value
-This warning requires @option{-fanalyzer}, which enables it; use
-@option{-Wno-analyzer-use-of-uninitialized-value} to disable it.
-
-This diagnostic warns for paths through the code in which an uninitialized
-value is used.
-
@end table
Pertinent parameters for controlling the exploration are:
+2020-04-28 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/94447
+ PR analyzer/94639
+ PR analyzer/94732
+ PR analyzer/94754
+ * gcc.dg/analyzer/data-model-1.c: Mark "use of uninitialized
+ value" warnings as xfail for now.
+ * gcc.dg/analyzer/data-model-5b.c: Remove uninitialized warning.
+ * gcc.dg/analyzer/pr94099.c: Mark "uninitialized" warning as xfail
+ for now.
+ * gcc.dg/analyzer/pr94447.c: New test.
+ * gcc.dg/analyzer/pr94639.c: New test.
+ * gcc.dg/analyzer/pr94732.c: New test.
+ * gcc.dg/analyzer/pr94754.c: New test.
+ * gcc.dg/analyzer/zlib-6.c: Mark "uninitialized" warning as xfail
+ for now.
+
2020-04-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94809
int test_37 (void)
{
int *ptr;
- return *ptr; /* { dg-warning "use of uninitialized value 'ptr'" } */
+ return *ptr; /* { dg-warning "use of uninitialized value 'ptr'" "uninit-warning-removed" { xfail *-*-* } } */
}
/* Write through uninitialized pointer. */
void test_37a (int i)
{
int *ptr;
- *ptr = i; /* { dg-warning "use of uninitialized value 'ptr'" } */
+ *ptr = i; /* { dg-warning "use of uninitialized value 'ptr'" "uninit-warning-removed" { xfail *-*-* } } */
}
// TODO: the various other ptr deref poisonings
if (--obj->str_base.ob_refcnt == 0)
{
//__analyzer_dump();
- obj->str_base.ob_type->tp_dealloc ((base_obj *)obj); /* { dg-bogus "use of uninitialized value '<unknown>'" "" { xfail *-*-* } } */
- // TODO (xfail): not sure what's going on here
+ obj->str_base.ob_type->tp_dealloc ((base_obj *)obj);
}
}
for (sc = 0; sc < 1; ++sc)
{
th.gk.hk = 0;
- th.gk.bg[sc] = 0; /* { dg-warning "uninitialized" } */
+ th.gk.bg[sc] = 0; /* { dg-warning "uninitialized" "uninit-warning-removed" { xfail *-*-* } } */
l3 (&th);
}
}
--- /dev/null
+struct foo
+{
+ int *v;
+};
+
+int test (void)
+{
+ struct foo f = {};
+ return *f.v;
+}
--- /dev/null
+#include <string.h>
+
+void validatedatetime(const char *str)
+{
+ const char *templates[] = {"dddd-dd-dd dd:dd", "dddd-dd-dd"};
+
+ size_t len = strlen(str);
+
+ for (unsigned t = 0; t < 2; t++) {
+ if (len != strlen(templates[t])) {
+ continue;
+ }
+ }
+}
--- /dev/null
+typedef struct { int *a; } S;
+int *f (void);
+static void g (S *x)
+{
+ int *p = x->a;
+ p[0] = 0;
+}
+void h (void)
+{
+ S x[1];
+ x->a = f ();
+ g (x);
+}
--- /dev/null
+[[gnu::nonnull]]
+static
+void init_x(int cond, int **x, int *y)
+{
+ if (!cond)
+ return;
+ *x = y;
+}
+
+int foo(int cond)
+{
+ int *x;
+ int y = 7;
+
+ if (cond < 2)
+ return -1;
+ init_x(cond, &x, &y);
+
+ return *x;
+}
return inflate_flush(s, z, r);
}
};
- b |= ((uLong)(n--, *p++)) << k; /* { dg-warning "use of uninitialized value" } */
+ b |= ((uLong)(n--, *p++)) << k; /* { dg-warning "use of uninitialized value" "uninit-warning-removed" { xfail *-*-* } } */
k += 8;
}
}