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

Generate 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.

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.
diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index 84c70f8..30fc6d43 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -185,39 +185,8 @@
 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 bb731a6..6ef9af2 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -670,6 +670,7 @@
 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 503480b..9d6464d 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -27,6 +27,7 @@
 #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 @@
 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 @@
   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 @@
 	}
     }
 
+  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 0000000..582ad58
--- /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;
+}