diff mbox series

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

Message ID 20200114165513.28124-1-jason@redhat.com
State New
Headers show
Series [C++] PR c++/92009 - ICE with punning of typeid. | expand

Commit Message

Jason Merrill Jan. 14, 2020, 4:55 p.m. UTC
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.

Tested x86_64-pc-linux-gnu, applying to trunk.

	* rtti.c (get_tinfo_desc): Call xref_basetypes.
	* constexpr.c (cxx_fold_indirect_ref): Don't strip
	REINTERPRET_CAST_P.
---
 gcc/cp/constexpr.c                            | 11 +++++++++-
 gcc/cp/rtti.c                                 |  1 +
 .../g++.dg/cpp0x/constexpr-reinterpret2.C     | 21 +++++++++++++++++++
 gcc/testsuite/g++.dg/rtti/typeid13.C          | 11 ++++++++++
 4 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret2.C
 create mode 100644 gcc/testsuite/g++.dg/rtti/typeid13.C


base-commit: 03e87724864a17e22c9b692cc0caa014e9dba6b1
diff mbox series

Patch

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 3a9fb566a52..bb126a9c006 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 2fc52f07980..36c1b4ed7bc 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 00000000000..1bc2a8f3012
--- /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 00000000000..d42005ed0d6
--- /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];
+}