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.