From 88ad43b1f91f7cd2ba9c342c6c1a6da82e6088bf Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Sun, 16 Jun 2019 07:49:06 +0000 Subject: [PATCH] re PR d/90651 (ICE in FuncDeclaration::semantic3, at d/dmd/func.c:1524) 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 * 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 --- gcc/d/ChangeLog | 14 +++ gcc/d/dmd/MERGE | 2 +- 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 +++++ 12 files changed, 183 insertions(+), 35 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/ChangeLog b/gcc/d/ChangeLog index b94a903c8ad..8b6ce8551c2 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,17 @@ +2019-06-16 Iain Buclaw + + 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 d/90778 diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 7258fadb1bb..7b46e8f3da0 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -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. diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c index ebdfae584c8..5177f9f6449 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 2562f364b49..1757b498deb 100644 --- a/gcc/d/dmd/mtype.c +++ b/gcc/d/dmd/mtype.c @@ -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) { diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc index 58c6ce1ba3c..25bdb42d762 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); } @@ -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 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.30.2