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 <dmalc...@redhat.com>. > + > +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