d: Fix ICE in TypeInfoDeclaration, at dmd/declaration.c (PR100967)
authorIain Buclaw <ibuclaw@gdcproject.org>
Thu, 10 Jun 2021 17:59:23 +0000 (19:59 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Thu, 10 Jun 2021 18:19:39 +0000 (20:19 +0200)
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.

gcc/d/d-frontend.cc
gcc/d/d-tree.h
gcc/d/typeinfo.cc
gcc/testsuite/gdc.dg/pr100967.d [new file with mode: 0644]

index 84c70f8..30fc6d4 100644 (file)
@@ -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;
 }
index bb731a6..6ef9af2 100644 (file)
@@ -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 *);
index 503480b..9d6464d 100644 (file)
@@ -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 (file)
index 0000000..582ad58
--- /dev/null
@@ -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;
+}