public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r9-9578] PR d/90651 (ICE in FuncDeclaration::semantic3, at d/dmd/func.c:1524)
@ 2021-06-10 17:56 Iain Buclaw
  0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2021-06-10 17:56 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:dcde4afec2a25a5fa69d1e5eec022768340fa1ab

commit r9-9578-gdcde4afec2a25a5fa69d1e5eec022768340fa1ab
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Thu Jun 10 19:48:49 2021 +0200

    PR d/90651 (ICE in FuncDeclaration::semantic3, at d/dmd/func.c:1524)
    
    Fixes segmentation fault in FuncDeclaration::semantic3.
    
    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)

Diff:
---
 gcc/d/dmd/expressionsem.c                          | 18 +++--
 gcc/d/dmd/func.c                                   | 12 +++
 gcc/d/dmd/mtype.c                                  |  7 +-
 gcc/d/typeinfo.cc                                  | 85 +++++++++++++++-------
 .../fail_compilation/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(-)

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;
+}
+


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-06-10 17:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-10 17:56 [gcc r9-9578] PR d/90651 (ICE in FuncDeclaration::semantic3, at d/dmd/func.c:1524) Iain Buclaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).