PR c++/92009 - ICE with punning of typeid.

There were two issues in this PR:

1) We were crashing in is_really_empty_class because we say that the
internal RTTI types are classes, but never gave them TYPE_BINFO.

2) We were allowing the cast to a different pointer type because STRIP_NOPS
in cxx_fold_indirect_ref ignored REINTERPRET_CAST_P.

	* rtti.c (get_tinfo_desc): Call xref_basetypes.
	* constexpr.c (cxx_fold_indirect_ref): Don't strip
	REINTERPRET_CAST_P.
This commit is contained in:
Jason Merrill 2020-01-14 00:05:47 -05:00
parent 336da03cc3
commit 80de000242
5 changed files with 50 additions and 1 deletions

View File

@ -1,3 +1,10 @@
2020-01-14 Jason Merrill <jason@redhat.com>
PR c++/92009 - ICE with punning of typeid.
* rtti.c (get_tinfo_desc): Call xref_basetypes.
* constexpr.c (cxx_fold_indirect_ref): Don't strip
REINTERPRET_CAST_P.
2020-01-13 Jason Merrill <jason@redhat.com>
PR c++/92746 - ICE with noexcept of function concept check.

View File

@ -4023,7 +4023,16 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
tree subtype;
poly_uint64 const_op01;
STRIP_NOPS (sub);
/* STRIP_NOPS, but stop if REINTERPRET_CAST_P. */
while (CONVERT_EXPR_P (sub) || TREE_CODE (sub) == NON_LVALUE_EXPR
|| TREE_CODE (sub) == VIEW_CONVERT_EXPR)
{
if (TREE_CODE (sub) == NOP_EXPR
&& REINTERPRET_CAST_P (sub))
return NULL_TREE;
sub = TREE_OPERAND (sub, 0);
}
subtype = TREE_TYPE (sub);
if (!INDIRECT_TYPE_P (subtype))
return NULL_TREE;

View File

@ -1472,6 +1472,7 @@ get_tinfo_desc (unsigned ix)
/* Pass the fields chained in reverse. */
finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
xref_basetypes (pseudo_type, /*bases=*/NULL_TREE);
res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
res->name = get_identifier (real_name);

View File

@ -0,0 +1,21 @@
// { dg-do compile { target c++11 } }
struct S { void *p; };
struct T { S s; };
constexpr S s = { nullptr };
constexpr T t = { { nullptr } };
constexpr void *
foo ()
{
return ((void **) &t)[0]; // { dg-error "reinterpret_cast" }
}
constexpr void *
bar ()
{
return ((void **) &s)[0]; // { dg-error "reinterpret_cast" }
}
constexpr auto x = foo ();
constexpr auto y = bar ();

View File

@ -0,0 +1,11 @@
// PR c++/92009
namespace std {
class type_info {};
}
bool
a2 ()
{
return ((void **) &typeid (int))[0];
}