From: Jason Merrill Date: Tue, 14 Jan 2020 05:05:47 +0000 (-0500) Subject: PR c++/92009 - ICE with punning of typeid. X-Git-Tag: upstream/12.2.0~19088 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=80de0002429c74626198cefa168c3081c9d90566;p=platform%2Fupstream%2Fgcc.git 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. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4729e3d..f7e5e74 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2020-01-14 Jason Merrill + + 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 PR c++/92746 - ICE with noexcept of function concept check. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 3a9fb56..bb126a9 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 2fc52f0..36c1b4e 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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); diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret2.C new file mode 100644 index 0000000..1bc2a8f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret2.C @@ -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 (); diff --git a/gcc/testsuite/g++.dg/rtti/typeid13.C b/gcc/testsuite/g++.dg/rtti/typeid13.C new file mode 100644 index 0000000..d42005e --- /dev/null +++ b/gcc/testsuite/g++.dg/rtti/typeid13.C @@ -0,0 +1,11 @@ +// PR c++/92009 + +namespace std { + class type_info {}; +} + +bool +a2 () +{ + return ((void **) &typeid (int))[0]; +}