#include "stor-layout.h"
#include "attribs.h"
#include "tree-object-size.h"
+#include "gimple-ssa.h"
+#include "tree-phinodes.h"
+#include "tree-ssa-operands.h"
+#include "ssa-iterators.h"
#if ENABLE_ANALYZER
}
}
+/* Workaround for discarding certain false positives from
+ -Wanalyzer-use-of-uninitialized-value
+ of the form:
+ ((A OR-IF B) OR-IF C)
+ and:
+ ((A AND-IF B) AND-IF C)
+ where evaluating B is redundant, but could involve simple accesses of
+ uninitialized locals.
+
+ When optimization is turned on the FE can immediately fold compound
+ conditionals. Specifically, c_parser_condition parses this condition:
+ ((A OR-IF B) OR-IF C)
+ and calls c_fully_fold on the condition.
+ Within c_fully_fold, fold_truth_andor is called, which bails when
+ optimization is off, but if any optimization is turned on can convert the
+ ((A OR-IF B) OR-IF C)
+ into:
+ ((A OR B) OR_IF C)
+ for sufficiently simple B
+ i.e. the inner OR-IF becomes an OR.
+ At gimplification time the inner OR becomes BIT_IOR_EXPR (in gimplify_expr),
+ giving this for the inner condition:
+ tmp = A | B;
+ if (tmp)
+ thus effectively synthesizing a redundant access of B when optimization
+ is turned on, when compared to:
+ if (A) goto L1; else goto L4;
+ L1: if (B) goto L2; else goto L4;
+ L2: if (C) goto L3; else goto L4;
+ for the unoptimized case.
+
+ Return true if CTXT appears to be handling such a short-circuitable stmt,
+ such as the def-stmt for B for the:
+ tmp = A | B;
+ case above, for the case where A is true and thus B would have been
+ short-circuited without optimization, using MODEL for the value of A. */
+
+static bool
+within_short_circuited_stmt_p (const region_model *model,
+ region_model_context *ctxt)
+{
+ gcc_assert (ctxt);
+ const gimple *curr_stmt = ctxt->get_stmt ();
+ if (curr_stmt == NULL)
+ return false;
+
+ /* We must have an assignment to a temporary of _Bool type. */
+ const gassign *assign_stmt = dyn_cast <const gassign *> (curr_stmt);
+ if (!assign_stmt)
+ return false;
+ tree lhs = gimple_assign_lhs (assign_stmt);
+ if (TREE_TYPE (lhs) != boolean_type_node)
+ return false;
+ if (TREE_CODE (lhs) != SSA_NAME)
+ return false;
+ if (SSA_NAME_VAR (lhs) != NULL_TREE)
+ return false;
+
+ /* The temporary bool must be used exactly once: as the second arg of
+ a BIT_IOR_EXPR or BIT_AND_EXPR. */
+ use_operand_p use_op;
+ gimple *use_stmt;
+ if (!single_imm_use (lhs, &use_op, &use_stmt))
+ return false;
+ const gassign *use_assign = dyn_cast <const gassign *> (use_stmt);
+ if (!use_assign)
+ return false;
+ enum tree_code op = gimple_assign_rhs_code (use_assign);
+ if (!(op == BIT_IOR_EXPR ||op == BIT_AND_EXPR))
+ return false;
+ if (!(gimple_assign_rhs1 (use_assign) != lhs
+ && gimple_assign_rhs2 (use_assign) == lhs))
+ return false;
+
+ /* The first arg of the bitwise stmt must have a known value in MODEL
+ that implies that the value of the second arg doesn't matter, i.e.
+ 1 for bitwise or, 0 for bitwise and. */
+ tree other_arg = gimple_assign_rhs1 (use_assign);
+ /* Use a NULL ctxt here to avoid generating warnings. */
+ const svalue *other_arg_sval = model->get_rvalue (other_arg, NULL);
+ tree other_arg_cst = other_arg_sval->maybe_get_constant ();
+ if (!other_arg_cst)
+ return false;
+ switch (op)
+ {
+ default:
+ gcc_unreachable ();
+ case BIT_IOR_EXPR:
+ if (zerop (other_arg_cst))
+ return false;
+ break;
+ case BIT_AND_EXPR:
+ if (!zerop (other_arg_cst))
+ return false;
+ break;
+ }
+
+ /* All tests passed. We appear to be in a stmt that generates a boolean
+ temporary with a value that won't matter. */
+ return true;
+}
+
/* Check for SVAL being poisoned, adding a warning to CTXT.
Return SVAL, or, if a warning is added, another value, to avoid
repeatedly complaining about the same poisoned value in followup code. */
&& is_empty_type (sval->get_type ()))
return sval;
+ /* Special case to avoid certain false positives. */
+ if (pkind == POISON_KIND_UNINIT
+ && within_short_circuited_stmt_p (this, ctxt))
+ return sval;
+
/* If we have an SSA name for a temporary, we don't want to print
'<unknown>'.
Poisoned values are shared by type, and so we can't reconstruct