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

--- Comment #5 from Bernd Edlinger <edlinger at gcc dot gnu.org> ---
Some insight, why the crash only happens with -std=c++98:

-Wshadow=compatible-local tries to find out if there is an
implicit conversion between the "int16_t f" and "a f".
The only candidate is a::a(char *);
The conversion is only allowed when it f is NULL.

  /* [conv.ptr]
     A null pointer constant can be converted to a pointer type; ... A
     null pointer constant of integral type can be converted to an
     rvalue of type std::nullptr_t. */
  if ((tcode == POINTER_TYPE || TYPE_PTRMEM_P (to)
       || NULLPTR_TYPE_P (to))
      && ((expr && null_ptr_cst_p (expr))
          || NULLPTR_TYPE_P (from)))
    conv = build_conv (ck_std, to, conv);

and now null_ptr_cst_p is invoked with "int16_t()", aka CAST_EXPR(NULL_TREE):

bool
null_ptr_cst_p (tree t)
{
  tree type = TREE_TYPE (t);

  /* [conv.ptr]

     A null pointer constant is an integer literal ([lex.icon]) with value
     zero or a prvalue of type std::nullptr_t.  */
  if (NULLPTR_TYPE_P (type))
    return true;

  if (cxx_dialect >= cxx11)
    {
      STRIP_ANY_LOCATION_WRAPPER (t);

      /* Core issue 903 says only literal 0 is a null pointer constant.  */
      if (TREE_CODE (t) == INTEGER_CST
          && !TREE_OVERFLOW (t)
          && TREE_CODE (type) == INTEGER_TYPE
          && integer_zerop (t)
          && !char_type_p (type))
        return true;
    }
  else if (CP_INTEGRAL_TYPE_P (type))
    {
      t = fold_non_dependent_expr (t, tf_none);
      STRIP_NOPS (t);
      if (integer_zerop (t) && !TREE_OVERFLOW (t))
        return true;
    }

  return false;

and now fold_non_dependent_expr fails.

With above patch we enter with the t = f, the decl we want to cast,
it is obviously not null.

Reply via email to