Hi,

When looking into fixing PR100967, I noticed that the gcc-9 release
branch first needed a patch to address another issue that didn't
originally get backported from GCC-10.

This fixes segmentation fault in FuncDeclaration::semantic3.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
committed to the gcc-9 release branch.

Regards,
Iain.

---
gcc/d/ChangeLog:

        PR d/90651
        * dmd/expressionsem.c (ExpressionSemanticVisitor::visit (TypeidExp)):
        Error when TypeInfo doesn't exist.
        * dmd/func.c (FuncDeclaration::semantic3): Likewise.
        * dmd/mtype.c (TypeClass::dotExp): Likewise.
        * typeinfo.cc (object_module): New variable.
        (make_frontend_typeinfo): Update signature.  Set temporary on
        generated TypeInfo classes.
        (create_tinfo_types): Set object_module.  Move generation of front-end
        typeinfo into ...
        (create_frontend_tinfo_types): ... New function.
        (layout_typeinfo): Call create_frontend_tinfo_types.
        (layout_classinfo): Likewise.
        (layout_cpp_typeinfo): Likewise.
        (create_typeinfo): Likewise.

gcc/testsuite/ChangeLog:

        PR d/90651
        * gdc.test/fail_compilation/extra-files/minimal/object.d: New file.
        * gdc.test/fail_compilation/fail19911a.d: New test.
        * gdc.test/fail_compilation/fail19911b.d: New test.
        * gdc.test/fail_compilation/fail19911c.d: New test.
        * gdc.test/fail_compilation/fail19922.d: New test.
        * gdc.test/fail_compilation/fail19923.d: New test.

(cherry picked from commit 88ad43b1f91f7cd2ba9c342c6c1a6da82e6088bf)
---
 gcc/d/dmd/expressionsem.c                     | 18 ++--
 gcc/d/dmd/func.c                              | 12 +++
 gcc/d/dmd/mtype.c                             |  7 +-
 gcc/d/typeinfo.cc                             | 85 +++++++++++++------
 .../extra-files/minimal/object.d              |  1 +
 .../gdc.test/fail_compilation/fail19911a.d    | 11 +++
 .../gdc.test/fail_compilation/fail19911b.d    | 13 +++
 .../gdc.test/fail_compilation/fail19911c.d    | 17 ++++
 .../gdc.test/fail_compilation/fail19922.d     | 19 +++++
 .../gdc.test/fail_compilation/fail19923.d     | 19 +++++
 10 files changed, 168 insertions(+), 34 deletions(-)
 create mode 100644 
gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19911a.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19911b.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19911c.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19922.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19923.d

diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 75794a03285..847a0796792 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -1806,11 +1806,19 @@ public:
         Expression *e;
         if (ea && ta->toBasetype()->ty == Tclass)
         {
-            /* Get the dynamic type, which is .classinfo
-            */
-            ea = semantic(ea, sc);
-            e = new TypeidExp(ea->loc, ea);
-            e->type = Type::typeinfoclass->type;
+            if (!Type::typeinfoclass)
+            {
+                error(exp->loc, "`object.TypeInfo_Class` could not be found, 
but is implicitly used");
+                e = new ErrorExp();
+            }
+            else
+            {
+                /* Get the dynamic type, which is .classinfo
+                */
+                ea = semantic(ea, sc);
+                e = new TypeidExp(ea->loc, ea);
+                e->type = Type::typeinfoclass->type;
+            }
         }
         else if (ta->ty == Terror)
         {
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index 568decc8cee..04c70cf3b7b 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -1520,6 +1520,18 @@ void FuncDeclaration::semantic3(Scope *sc)
         {
             if (f->linkage == LINKd)
             {
+                // Variadic arguments depend on Typeinfo being defined
+                if (!global.params.useTypeInfo || !Type::dtypeinfo || 
!Type::typeinfotypelist)
+                {
+                    if (!global.params.useTypeInfo)
+                        error("D-style variadic functions cannot be used with 
-betterC");
+                    else if (!Type::typeinfotypelist)
+                        error("`object.TypeInfo_Tuple` could not be found, but 
is implicitly used in D-style variadic functions");
+                    else
+                        error("`object.TypeInfo` could not be found, but is 
implicitly used in D-style variadic functions");
+                    fatal();
+                }
+
                 // Declare _arguments[]
                 v_arguments = new VarDeclaration(Loc(), 
Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
                 v_arguments->storage_class |= STCtemp | STCparameter;
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 585199033af..0204860fec3 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -8347,7 +8347,12 @@ L1:
 
         if (ident == Id::classinfo)
         {
-            assert(Type::typeinfoclass);
+            if (!Type::typeinfoclass)
+            {
+                error(e->loc, "`object.TypeInfo_Class` could not be found, but 
is implicitly used");
+                return new ErrorExp();
+            }
+
             Type *t = Type::typeinfoclass->type;
             if (e->op == TOKtype || e->op == TOKdottype)
             {
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 0b19bcf7f34..6e8583e38b4 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -185,28 +185,36 @@ make_internal_typeinfo (tinfo_kind tk, Identifier *ident, 
...)
   va_end (ap);
 }
 
-/* Helper for create_tinfo_types.  Creates a typeinfo class declaration
-   incase one wasn't supplied by reading `object.d'.  */
+/* Reference to the `object` module, where all TypeInfo is defined.  */
+
+static Module *object_module;
+
+/* Helper for create_frontend_tinfo_types.  Creates a typeinfo class
+   declaration incase one wasn't supplied by reading `object.d'.  */
 
 static void
-make_frontend_typeinfo (Module *mod, Identifier *ident,
-                       ClassDeclaration *base = NULL)
+make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL)
 {
   if (!base)
     base = Type::dtypeinfo;
 
+  gcc_assert (object_module);
+
   /* Create object module in order to complete the semantic.  */
-  if (!mod->_scope)
-    mod->importAll (NULL);
+  if (!object_module->_scope)
+    object_module->importAll (NULL);
 
   /* Assignment of global typeinfo variables is managed by the ClassDeclaration
      constructor, so only need to new the declaration here.  */
-  Loc loc = (mod->md) ? mod->md->loc : mod->loc;
+  Loc loc = (object_module->md) ? object_module->md->loc : object_module->loc;
   ClassDeclaration *tinfo = ClassDeclaration::create (loc, ident, NULL, NULL,
                                                      true);
-  tinfo->parent = mod;
-  tinfo->semantic (mod->_scope);
+  tinfo->parent = object_module;
+  tinfo->semantic (object_module->_scope);
   tinfo->baseClass = base;
+  /* This is a compiler generated class, and shouldn't be mistaken for being
+     the type declared in the runtime library.  */
+  tinfo->storage_class |= STCtemp;
 }
 
 /* Make sure the required builtin types exist for generating the TypeInfo
@@ -227,69 +235,78 @@ create_tinfo_types (Module *mod)
                          ptr_type_node, d_uint_type, ptr_type_node,
                          array_type_node, ptr_type_node, ptr_type_node, NULL);
 
+  object_module = mod;
+}
+
+/* Same as create_tinfo_types, but builds all front-end TypeInfo variable
+   definitions.  */
+
+static void
+create_frontend_tinfo_types (void)
+{
   /* If there's no Object class defined, then neither can TypeInfo be.  */
-  if (ClassDeclaration::object == NULL)
+  if (object_module == NULL || ClassDeclaration::object == NULL)
     return;
 
   /* Create all frontend TypeInfo classes declarations.  We rely on all
      existing, even if only just as stubs.  */
   if (!Type::dtypeinfo)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo"),
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo"),
                            ClassDeclaration::object);
 
   if (!Type::typeinfoclass)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Class"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Class"));
 
   if (!Type::typeinfointerface)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Interface"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Interface"));
 
   if (!Type::typeinfostruct)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Struct"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Struct"));
 
   if (!Type::typeinfopointer)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Pointer"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Pointer"));
 
   if (!Type::typeinfoarray)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Array"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Array"));
 
   if (!Type::typeinfostaticarray)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_StaticArray"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_StaticArray"));
 
   if (!Type::typeinfoassociativearray)
-    make_frontend_typeinfo (mod, Identifier::idPool 
("TypeInfo_AssociativeArray"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_AssociativeArray"));
 
   if (!Type::typeinfoenum)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Enum"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Enum"));
 
   if (!Type::typeinfofunction)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Function"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Function"));
 
   if (!Type::typeinfodelegate)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Delegate"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Delegate"));
 
   if (!Type::typeinfotypelist)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Tuple"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Tuple"));
 
   if (!Type::typeinfoconst)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Const"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Const"));
 
   if (!Type::typeinfoinvariant)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Invariant"),
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Invariant"),
                            Type::typeinfoconst);
 
   if (!Type::typeinfoshared)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Shared"),
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Shared"),
                            Type::typeinfoconst);
 
   if (!Type::typeinfowild)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Wild"),
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Wild"),
                            Type::typeinfoconst);
 
   if (!Type::typeinfovector)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Vector"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Vector"));
 
   if (!ClassDeclaration::cpp_type_info_ptr)
-    make_frontend_typeinfo (mod, Identifier::idPool ("__cpp_type_info_ptr"),
+    make_frontend_typeinfo (Identifier::idPool ("__cpp_type_info_ptr"),
                            ClassDeclaration::object);
 }
 
@@ -1143,6 +1160,9 @@ public:
 tree
 layout_typeinfo (TypeInfoDeclaration *d)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   TypeInfoVisitor v = TypeInfoVisitor (get_typeinfo_decl (d));
   d->accept (&v);
   return v.result ();
@@ -1154,6 +1174,9 @@ layout_typeinfo (TypeInfoDeclaration *d)
 tree
 layout_classinfo (ClassDeclaration *cd)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);
   TypeInfoVisitor v = TypeInfoVisitor (get_classinfo_decl (cd));
   d->accept (&v);
@@ -1375,6 +1398,9 @@ build_typeinfo (const Loc &loc, Type *type)
 void
 layout_cpp_typeinfo (ClassDeclaration *cd)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   gcc_assert (cd->isCPPclass ());
 
   tree decl = get_cpp_typeinfo_decl (cd);
@@ -1443,6 +1469,9 @@ get_cpp_typeinfo_decl (ClassDeclaration *decl)
 void
 create_typeinfo (Type *type, Module *mod)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   /* Do this since not all Type's are merged.  */
   Type *t = type->merge2 ();
   Identifier *ident;
diff --git 
a/gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d 
b/gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d
new file mode 100644
index 00000000000..c7060b0d96c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d
@@ -0,0 +1 @@
+module object;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19911a.d 
b/gcc/testsuite/gdc.test/fail_compilation/fail19911a.d
new file mode 100644
index 00000000000..672db305223
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19911a.d
@@ -0,0 +1,11 @@
+/*
+REQUIRED_ARGS: -betterC
+TEST_OUTPUT:
+---
+fail_compilation/fail19911a.d(9): Error: function `fail19911a.fun` D-style 
variadic functions cannot be used with -betterC
+---
+*/
+
+void fun(...)
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19911b.d 
b/gcc/testsuite/gdc.test/fail_compilation/fail19911b.d
new file mode 100644
index 00000000000..b4ad22b0896
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19911b.d
@@ -0,0 +1,13 @@
+/* 
+DFLAGS:
+REQUIRED_ARGS:
+EXTRA_SOURCES: extra-files/minimal/object.d
+TEST_OUTPUT:
+---
+fail_compilation/fail19911b.d(10): Error: function `fail19911b.fun` 
`object.TypeInfo_Tuple` could not be found, but is implicitly used in D-style 
variadic functions
+---
+*/
+
+void fun(...)
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19911c.d 
b/gcc/testsuite/gdc.test/fail_compilation/fail19911c.d
new file mode 100644
index 00000000000..d1e954ed394
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19911c.d
@@ -0,0 +1,17 @@
+/* 
+DFLAGS:
+REQUIRED_ARGS:
+TEST_OUTPUT:
+---
+fail_compilation/fail19911c.d(15): Error: function `object.fun` 
`object.TypeInfo` could not be found, but is implicitly used in D-style 
variadic functions
+---
+*/
+
+module object;
+
+class Object { }
+class TypeInfo_Tuple { }
+
+void fun(...)
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19922.d 
b/gcc/testsuite/gdc.test/fail_compilation/fail19922.d
new file mode 100644
index 00000000000..5c9e2bbe0ab
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19922.d
@@ -0,0 +1,19 @@
+/* 
+DFLAGS:
+REQUIRED_ARGS:
+TEST_OUTPUT:
+---
+fail_compilation/fail19922.d(17): Error: `object.TypeInfo_Class` could not be 
found, but is implicitly used
+---
+*/
+
+module object;
+
+class Object {}
+
+void test()
+{
+    Object o;
+    auto ti = typeid(o);
+}
+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19923.d 
b/gcc/testsuite/gdc.test/fail_compilation/fail19923.d
new file mode 100644
index 00000000000..042cf8af11a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19923.d
@@ -0,0 +1,19 @@
+/* 
+DFLAGS:
+REQUIRED_ARGS:
+TEST_OUTPUT:
+---
+fail_compilation/fail19923.d(17): Error: `object.TypeInfo_Class` could not be 
found, but is implicitly used
+---
+*/
+
+module object;
+
+class Object {}
+
+void test()
+{
+    Object o;
+    auto ti = o.classinfo;
+}
+
-- 
2.27.0

Reply via email to