re PR d/90651 (ICE in FuncDeclaration::semantic3, at d/dmd/func.c:1524)
authorIain Buclaw <ibuclaw@gdcproject.org>
Sun, 16 Jun 2019 07:49:06 +0000 (07:49 +0000)
committerIain Buclaw <ibuclaw@gcc.gnu.org>
Sun, 16 Jun 2019 07:49:06 +0000 (07:49 +0000)
PR d/90651
d/dmd: Merge upstream dmd 0f6cbbcad

Fixes segmentation fault in FuncDeclaration::semantic3.

Reviewed-on: https://github.com/dlang/dmd/pull/10003

gcc/d/ChangeLog:

2019-06-16  Iain Buclaw  <ibuclaw@gdcproject.org>

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

From-SVN: r272345

12 files changed:
gcc/d/ChangeLog
gcc/d/dmd/MERGE
gcc/d/dmd/expressionsem.c
gcc/d/dmd/func.c
gcc/d/dmd/mtype.c
gcc/d/typeinfo.cc
gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d [new file with mode: 0644]
gcc/testsuite/gdc.test/fail_compilation/fail19911a.d [new file with mode: 0644]
gcc/testsuite/gdc.test/fail_compilation/fail19911b.d [new file with mode: 0644]
gcc/testsuite/gdc.test/fail_compilation/fail19911c.d [new file with mode: 0644]
gcc/testsuite/gdc.test/fail_compilation/fail19922.d [new file with mode: 0644]
gcc/testsuite/gdc.test/fail_compilation/fail19923.d [new file with mode: 0644]

index b94a903c8ad6a18b894799fd220d03d7429cd6c2..8b6ce8551c2f293448f9bfe176fbbaf8ca850033 100644 (file)
@@ -1,3 +1,17 @@
+2019-06-16  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+       PR d/90651
+       * 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.
+
 2019-06-11  Richard Biener  <rguenthe@suse.de>
 
        d/90778
index 7258fadb1bba992f40a3bd8431b6114882c3a933..7b46e8f3da03402dc950c663a3fd0070ac7b88d5 100644 (file)
@@ -1,4 +1,4 @@
-ab03e2918508d62efcc5ee66c9a912a331b33aa0
+3be8a80bb0c4e01c436be970ac3555ceabb3caf8
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
index ebdfae584c8351f1e146f41b97a3e36b02ba15c8..5177f9f6449431ef01d20517c7fd6f7c05a0391c 100644 (file)
@@ -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)
         {
index 568decc8cee79307d4433f366ef6e8855d3db27e..04c70cf3b7b3b99b514c88b3d1e00ac963a3280d 100644 (file)
@@ -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;
index 2562f364b499f7e0f82fb195475ea31e127b2db2..1757b498debb7af6e0b23ea1b645ab1485355803 100644 (file)
@@ -8350,7 +8350,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)
             {
index 58c6ce1ba3c7668c91f849ef003b6c4cbb8be6ba..25bdb42d7626d842152805d977ac00ceb33f20c0 100644 (file)
@@ -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);
 }
 
@@ -1132,6 +1149,9 @@ public:
 tree
 layout_typeinfo (TypeInfoDeclaration *d)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   tree type = TREE_TYPE (get_typeinfo_decl (d));
   TypeInfoVisitor v = TypeInfoVisitor (type);
   d->accept (&v);
@@ -1144,6 +1164,9 @@ layout_typeinfo (TypeInfoDeclaration *d)
 tree
 layout_classinfo (ClassDeclaration *cd)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);
   tree type = TREE_TYPE (get_classinfo_decl (cd));
   TypeInfoVisitor v = TypeInfoVisitor (type);
@@ -1366,6 +1389,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);
@@ -1434,6 +1460,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 (file)
index 0000000..c7060b0
--- /dev/null
@@ -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 (file)
index 0000000..672db30
--- /dev/null
@@ -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 (file)
index 0000000..b4ad22b
--- /dev/null
@@ -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 (file)
index 0000000..d1e954e
--- /dev/null
@@ -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 (file)
index 0000000..5c9e2bb
--- /dev/null
@@ -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 (file)
index 0000000..042cf8a
--- /dev/null
@@ -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;
+}
+