On Fri, 2019-11-15 at 20:23 -0500, David Malcolm wrote:
> This patch adds a "state_machine" base class for describing
> API checkers in terms of state machine transitions. Followup
> patches use this to add specific API checkers.
>
> gcc/ChangeLog:
> * analyzer/sm.cc: New file.
> * analyzer/sm.h: New file.
> ---
> gcc/analyzer/sm.cc | 135
> ++++++++++++++++++++++++++++++++++++++++++++
> gcc/analyzer/sm.h | 160
> +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 295 insertions(+)
> create mode 100644 gcc/analyzer/sm.cc
> create mode 100644 gcc/analyzer/sm.h
>
> diff --git a/gcc/analyzer/sm.cc b/gcc/analyzer/sm.cc
> new file mode 100644
> index 0000000..eda9350
> --- /dev/null
> +++ b/gcc/analyzer/sm.cc
> @@ -0,0 +1,135 @@
> +/* Modeling API uses and misuses via state machines.
> + Copyright (C) 2019 Free Software Foundation, Inc.
> + Contributed by David Malcolm <[email protected]>.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it
> +under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful, but
> +WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3. If not see
> +<http://www.gnu.org/licenses/>;. */
> +
> +#include "config.h"
> +#include "gcc-plugin.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "tree.h"
> +#include "gimple.h"
> +#include "analyzer/analyzer.h"
> +#include "analyzer/sm.h"
> +
> +////////////////////////////////////////////////////////////////////
> ////////
> +
> +/* If STMT is an assignment to zero, return the LHS. */
> +
> +tree
> +is_zero_assignment (const gimple *stmt)
> +{
> + const gassign *assign_stmt = dyn_cast <const gassign *> (stmt);
> + if (!assign_stmt)
> + return NULL_TREE;
> +
> + enum tree_code op = gimple_assign_rhs_code (assign_stmt);
> + if (op != INTEGER_CST)
> + return NULL_TREE;
> +
> + if (!zerop (gimple_assign_rhs1 (assign_stmt)))
> + return NULL_TREE;
> +
> + return gimple_assign_lhs (assign_stmt);
> +}
"assignment from zero" rather than "assignment to zero" I think.
I think you'd want to use "integer_zerop" rather than an open-coded
check. That'll also allow you to pick up other forms such as
COMPLEX_CST and VECTOR_CST.
> +
> +/* If COND_STMT is a comparison against zero of the form (LHS OP 0),
> + return true and write what's being compared to *OUT_LHS and the
> kind of
> + the comparison to *OUT_OP. */
> +
> +bool
> +is_comparison_against_zero (const gcond *cond_stmt,
> + tree *out_lhs, enum tree_code *out_op)
> +{
> + enum tree_code op = gimple_cond_code (cond_stmt);
> + tree lhs = gimple_cond_lhs (cond_stmt);
> + tree rhs = gimple_cond_rhs (cond_stmt);
> + if (!zerop (rhs))
> + return false;
> + // TODO: make it symmetric?
> +
> + switch (op)
> + {
> + case NE_EXPR:
> + case EQ_EXPR:
> + *out_lhs = lhs;
> + *out_op = op;
> + return true;
> +
> + default:
> + return false;
> + }
> +}
Seems like this might be useful to make generically available.
> +
> +bool
> +any_pointer_p (tree var)
> +{
> + if (TREE_CODE (TREE_TYPE (var)) != POINTER_TYPE)
> + return false;
> +
> + return true;
> +}
I believe what you really want is POINTER_TYPE_P which will also happen
to help C++ since it'll include things that are REFERENCE_TYPEs.
It looks like some of the methods don't have comments on their
definitions. Please check those and add them as necessary.
Otherwise it looks reasonable.
jeff