c++: Fix ICE with static_cast when converting from int[] [PR93862]

This ICEs since my patch for P0388, which allowed conversions to arrays
of unknown bound, but not the reverse, so these two static_casts are
ill-formed.

[expr.static.cast]/3 says that "cv1 T1" and "cv2 T2" have to be
reference-compatible and the comment in build_static_cast_1 says it too
but then we actually use reference_related_p...  Fixed thus.

2020-02-26  Marek Polacek  <polacek@redhat.com>

	PR c++/93862 - ICE with static_cast when converting from int[].
	* call.c (reference_compatible_p): No longer static.
	* cp-tree.h (reference_compatible_p): Declare.
	* typeck.c (build_static_cast_1): Use reference_compatible_p instead
	of reference_related_p.

	* g++.dg/cpp0x/rv-cast7.C: New test.
This commit is contained in:
Marek Polacek 2020-02-24 14:43:48 -05:00
parent b9934ad88d
commit 4a305fa2fd
6 changed files with 22 additions and 3 deletions

View file

@ -1,3 +1,11 @@
2020-02-26 Marek Polacek <polacek@redhat.com>
PR c++/93862 - ICE with static_cast when converting from int[].
* call.c (reference_compatible_p): No longer static.
* cp-tree.h (reference_compatible_p): Declare.
* typeck.c (build_static_cast_1): Use reference_compatible_p instead
of reference_related_p.
2020-02-26 Marek Polacek <polacek@redhat.com>
PR c++/93803 - ICE with constexpr init and [[no_unique_address]].

View file

@ -204,7 +204,6 @@ static struct z_candidate *add_candidate
conversion **, tree, tree, int, struct rejection_reason *, int);
static tree source_type (conversion *);
static void add_warning (struct z_candidate *, struct z_candidate *);
static bool reference_compatible_p (tree, tree);
static conversion *direct_reference_binding (tree, conversion *);
static bool promoted_arithmetic_type_p (tree);
static conversion *conditional_conversion (tree, tree, tsubst_flags_t);
@ -1554,7 +1553,7 @@ reference_related_p (tree t1, tree t2)
/* Returns nonzero if T1 is reference-compatible with T2. */
static bool
bool
reference_compatible_p (tree t1, tree t2)
{
/* [dcl.init.ref]

View file

@ -6357,6 +6357,7 @@ extern tree make_temporary_var_for_ref_to_temp (tree, tree);
extern bool type_has_extended_temps (tree);
extern tree strip_top_quals (tree);
extern bool reference_related_p (tree, tree);
extern bool reference_compatible_p (tree, tree);
extern int remaining_arguments (tree);
extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t);
extern tree perform_implicit_conversion_flags (tree, tree, tsubst_flags_t, int);

View file

@ -7383,7 +7383,7 @@ build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
if (TYPE_REF_P (type)
&& TYPE_REF_IS_RVALUE (type)
&& (clk = real_lvalue_p (expr))
&& reference_related_p (TREE_TYPE (type), intype)
&& reference_compatible_p (TREE_TYPE (type), intype)
&& (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
{
if (processing_template_decl)

View file

@ -1,3 +1,8 @@
2020-02-26 Marek Polacek <polacek@redhat.com>
PR c++/93862 - ICE with static_cast when converting from int[].
* g++.dg/cpp0x/rv-cast7.C: New test.
2020-02-26 Marek Polacek <polacek@redhat.com>
DR 1423, Convertibility of nullptr to bool.

View file

@ -0,0 +1,6 @@
// PR c++/93862 - ICE with static_cast when converting from int[].
// { dg-do compile { target c++11 } }
int(&&intu_rvref)[]{1,2,3,4};
int(&int4_lvref)[4] = static_cast<int(&)[4]>(intu_rvref); // { dg-error "invalid .static_cast." }
int(&&int4_rvref)[4] = static_cast<int(&&)[4]>(intu_rvref); // { dg-error "invalid .static_cast." }