[Bug tree-optimization/78586] [7 Regression] Wrong code caused by printf-return-value

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Nov 29 16:16:00 GMT 2016


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78586

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
There are still various weird spots in format_integer.
E.g.
  else if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE
           || TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE)
    {
      /* Determine the type of the provided non-constant argument.  */
      if (TREE_CODE (arg) == NOP_EXPR)
        arg = TREE_OPERAND (arg, 0);
      else if (TREE_CODE (arg) == CONVERT_EXPR)
        arg = TREE_OPERAND (arg, 0);
      if (TREE_CODE (arg) == COMPONENT_REF)
        arg = TREE_OPERAND (arg, 1);

      argtype = TREE_TYPE (arg);
    }
When would this actually happen?  The pass is done in SSA GIMPLE, and
integral/pointer types are gimple types, so the arguments should be always
is_gimple_val.  So, INTEGER_CST, SSA_NAME, or say ADDR_EXPR of something etc.,
but should not be NOP_EXPR, CONVERT_EXPR (we have a macro for those two btw,
CONVERT_EXPR_P), nor COMPONENT_REF.  Even if there would be NOPs etc., you
aren't checking if they convert from INTEGER/POINTER type or something
different.
2) for SSA_NAMEs with VR_RANGE, you only look at the argument's ranges, while
for something VR_VARYING and similar you consider both dirtype and argtype's
precision.  Isn't it always UB if the precision is different?  Corner case
might be C bitfields, not sure what exact type one gets when passing that to
varargs.  For UB wouldn't it be better to punt (return don't know value)?
I mean, if you have "%lld%d" format and pass in int and long long, assuming
what the result will be is strange.  For the same precision, it is quite common
that there is a mismatch between sign of what dirtype expects and what argtype
has (or one can be pointer and the other not).  That case we need to handle
properly.  But is e.g. for unsigned printing the minimum value of a signed type
the largest one?  I'd think it is -1.  E.g. for smaller precision signed (e.g.
bitfield) into larger precision unsigned.
3) "When precision is specified but unknown, use zero as the minimum since it
results in no bytes on output (unless width is specified to be greater than
0)."
When is 0 printed as nothing?  I thought it is printed as 0 (or 0x0 etc.).
4)               if (code == NOP_EXPR)
                argtype = TREE_TYPE (gimple_assign_rhs1 (def));
Similar case to 1), except it can happen, but argtype could be anything,
boolean type, perhaps fixed point type, enum, whatever.


More information about the Gcc-bugs mailing list