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.