This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [committed] analyzer: avoid comparisons between uncomparable types (PR 93450)


On Thu, 2020-01-30 at 15:36 +0100, Jakub Jelinek wrote:
> On Thu, Jan 30, 2020 at 09:27:33AM -0500, David Malcolm wrote:
> > --- a/gcc/analyzer/region-model.cc
> > +++ b/gcc/analyzer/region-model.cc
> > @@ -666,12 +666,16 @@ constant_svalue::eval_condition
> > (constant_svalue *lhs,
> >    gcc_assert (CONSTANT_CLASS_P (lhs_const));
> >    gcc_assert (CONSTANT_CLASS_P (rhs_const));
> >  
> > -  tree comparison
> > -    = fold_build2 (op, boolean_type_node, lhs_const, rhs_const);
> > -  if (comparison == boolean_true_node)
> > -    return tristate (tristate::TS_TRUE);
> > -  if (comparison == boolean_false_node)
> > -    return tristate (tristate::TS_FALSE);
> > +  /* Check for comparable types.  */
> > +  if (TREE_TYPE (lhs_const) == TREE_TYPE (rhs_const))
> 
> Isn't the analyzer invoked on GIMPLE?  In GIMPLE, pointer equality of
> types
> is often not guaranteed and the compiler generally doesn't care about
> that,
> what we care about is whether the two types are compatible
> (types_compatible_p).  E.g. if originally both types were say long
> int,
> but on lp64 one of the arguments was cast from long long int to long
> int,
> you can end up with one operand long int and the other long long int;
> they have the same precision etc., so it is ok to compare them.

Thanks.  In patch 1 of the attached I've replaced the pointer comparison
with a call to types_compatible_p, and added a call to
types_compatible_p to guard a place where constants were being compared.

> > +    {
> > +      tree comparison
> > +	= fold_build2 (op, boolean_type_node, lhs_const, rhs_const);
> > +      if (comparison == boolean_true_node)
> > +	return tristate (tristate::TS_TRUE);
> > +      if (comparison == boolean_false_node)
> > +	return tristate (tristate::TS_FALSE);
> 
> This seems to be a waste of compile time memory.  fold_build2 is
> essentially
>   tem = fold_binary_loc (loc, code, type, op0, op1);
>   if (!tem)
>     tem = build2_loc (loc, code, type, op0, op1 PASS_MEM_STAT);
> but as you only care if the result is boolean_true_node or
> boolean_false_node, the build2_loc is unnecessary.  So, just use
> fold_binary instead?  If it returns NULL_TREE, it won't compare equal
> to
> either and will fall through to the TS_UNKNOWN case.

Thanks.  I did some grepping and found that I'd made this mistake in
six places in the analyzer.  Sorry about that.  Patch 2 should fix all
of them.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

OK for master?

David Malcolm (2):
  analyzer: further fixes for comparisons between uncomparable types (PR
    93450)
  analyzer: avoid use of fold_build2

 gcc/analyzer/constraint-manager.cc | 19 +++++++++----------
 gcc/analyzer/region-model.cc       |  8 ++++----
 2 files changed, 13 insertions(+), 14 deletions(-)

-- 
2.21.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]