[committed] d: Fix ICE in TypeInfoDeclaration, at dmd/declaration.c (PR100967)

Message ID 20210610183035.3275691-1-ibuclaw@gdcproject.org
State New
Headers show
Series
  • [committed] d: Fix ICE in TypeInfoDeclaration, at dmd/declaration.c (PR100967)
Related show

Commit Message

Jonathan Wakely via Gcc-patches June 10, 2021, 6:30 p.m.
Hi,

This patch fixes an ICE in the constructor of TypeInfoDeclaration from
within the D language front-end.  Generates a stub TypeInfo class even
if the root Object class is missing.  The front-end will take care of
issuing an error and abort the compilation when running semantic on
constructed TypeInfo objects.

The errors issued by the code generation pass relating to missing or
disabled RTTI has been consolidated into a single function, so that a
meaningful error will be emitted before the front-end terminates.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32,
committed to mainline, and backported to the gcc-9, gcc-10, and gcc-11
release branches.

Regards,
Iain

---
gcc/d/ChangeLog:

	PR d/100967
	* d-frontend.cc (getTypeInfoType): Move TypeInfo checks to
	check_typeinfo_type and call new function.
	* d-tree.h (check_typeinfo_type): Declare.
	* typeinfo.cc: Include dmd/scope.h.
	(create_frontend_tinfo_types): Generate front-end types even if Object
	is missing.
	(build_typeinfo): Move TypeInfo checks to check_typeinfo_type and call
	new function.
	(check_typeinfo_type): New function.

gcc/testsuite/ChangeLog:

	PR d/100967
	* gdc.dg/pr100967.d: New test.
---
 gcc/d/d-frontend.cc             | 33 +---------------------------
 gcc/d/d-tree.h                  |  1 +
 gcc/d/typeinfo.cc               | 38 +++++++++++++++++++++++++++------
 gcc/testsuite/gdc.dg/pr100967.d | 11 ++++++++++
 4 files changed, 45 insertions(+), 38 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/pr100967.d

-- 
2.27.0

Patch

diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index 84c70f8ee6a..30fc6d435d0 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -185,39 +185,8 @@  eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments)
 Type *
 getTypeInfoType (Loc loc, Type *type, Scope *sc)
 {
-  if (!global.params.useTypeInfo)
-    {
-      /* Even when compiling without RTTI we should still be able to evaluate
-	 TypeInfo at compile-time, just not at run-time.  */
-      if (!sc || !(sc->flags & SCOPEctfe))
-	{
-	  static int warned = 0;
-
-	  if (!warned)
-	    {
-	      error_at (make_location_t (loc),
-			"%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
-	      warned = 1;
-	    }
-	}
-    }
-
-  if (Type::dtypeinfo == NULL
-      || (Type::dtypeinfo->storage_class & STCtemp))
-    {
-      /* If TypeInfo has not been declared, warn about each location once.  */
-      static Loc warnloc;
-
-      if (!loc.equals (warnloc))
-	{
-	  error_at (make_location_t (loc),
-		    "%<object.TypeInfo%> could not be found, "
-		    "but is implicitly used");
-	  warnloc = loc;
-	}
-    }
-
   gcc_assert (type->ty != Terror);
+  check_typeinfo_type (loc, sc);
   create_typeinfo (type, sc ? sc->_module->importedFrom : NULL);
   return type->vtinfo->type;
 }
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index bb731a60541..6ef9af2a991 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -670,6 +670,7 @@  extern tree layout_classinfo (ClassDeclaration *);
 extern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *);
 extern tree get_typeinfo_decl (TypeInfoDeclaration *);
 extern tree get_classinfo_decl (ClassDeclaration *);
+extern void check_typeinfo_type (const Loc &, Scope *);
 extern tree build_typeinfo (const Loc &, Type *);
 extern void create_typeinfo (Type *, Module *);
 extern void create_tinfo_types (Module *);
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 503480b491d..9d6464deb07 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -27,6 +27,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "dmd/identifier.h"
 #include "dmd/module.h"
 #include "dmd/mtype.h"
+#include "dmd/scope.h"
 #include "dmd/template.h"
 #include "dmd/target.h"
 
@@ -244,8 +245,8 @@  create_tinfo_types (Module *mod)
 static void
 create_frontend_tinfo_types (void)
 {
-  /* If there's no Object class defined, then neither can TypeInfo be.  */
-  if (object_module == NULL || ClassDeclaration::object == NULL)
+  /* If there's no object module, then neither can there be TypeInfo.  */
+  if (object_module == NULL)
     return;
 
   /* Create all frontend TypeInfo classes declarations.  We rely on all
@@ -1373,16 +1374,19 @@  get_classinfo_decl (ClassDeclaration *decl)
   return decl->csym;
 }
 
-/* Returns typeinfo reference for TYPE.  */
+/* Performs sanity checks on the `object.TypeInfo' type, raising an error if
+   RTTI is disabled, or the type is missing.  */
 
-tree
-build_typeinfo (const Loc &loc, Type *type)
+void
+check_typeinfo_type (const Loc &loc, Scope *sc)
 {
   if (!global.params.useTypeInfo)
     {
       static int warned = 0;
 
-      if (!warned)
+      /* Even when compiling without RTTI we should still be able to evaluate
+	 TypeInfo at compile-time, just not at run-time.  */
+      if (!warned && (!sc || !(sc->flags & SCOPEctfe)))
 	{
 	  error_at (make_location_t (loc),
 		    "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
@@ -1390,7 +1394,29 @@  build_typeinfo (const Loc &loc, Type *type)
 	}
     }
 
+  if (Type::dtypeinfo == NULL
+      || (Type::dtypeinfo->storage_class & STCtemp))
+    {
+      /* If TypeInfo has not been declared, warn about each location once.  */
+      static Loc warnloc;
+
+      if (!warnloc.equals (loc))
+	{
+	  error_at (make_location_t (loc),
+		    "%<object.TypeInfo%> could not be found, "
+		    "but is implicitly used");
+	  warnloc = loc;
+	}
+    }
+}
+
+/* Returns typeinfo reference for TYPE.  */
+
+tree
+build_typeinfo (const Loc &loc, Type *type)
+{
   gcc_assert (type->ty != Terror);
+  check_typeinfo_type (loc, NULL);
   create_typeinfo (type, NULL);
   return build_address (get_typeinfo_decl (type->vtinfo));
 }
diff --git a/gcc/testsuite/gdc.dg/pr100967.d b/gcc/testsuite/gdc.dg/pr100967.d
new file mode 100644
index 00000000000..582ad582676
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr100967.d
@@ -0,0 +1,11 @@ 
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100967
+// { dg-do compile }
+
+module object; // { dg-error "class object.TypeInfo missing or corrupt object.d" }
+
+extern(C) int main()
+{
+    int[int] aa;
+    aa[0] = 1;  // { dg-error ".object.TypeInfo. could not be found, but is implicitly used" }
+    return 0;
+}