Hi, Upstream dmd has now released v2.100.0, this patch merges in the latest bug fixes since the last sync-up of the release branch.
D front-end changes: - Import dmd v2.100.0 release. - The new behavior of issuing deprecation messages for scope violations has been reverted until next release. Phobos changes: - Import phobos v2.100.0 release. Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and committed to the releases/gcc-12 branch. Regards, Iain. --- gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd a53934d18. * dmd/VERSION: Update version to v2.100.0. * d-codegen.cc (d_decl_context): Use resolvedLinkage to get declaration linkage. (build_struct_literal): Track offset in bits. * d-gimplify.cc (d_gimplify_modify_expr): Check both operands for a bit-field reference. * d-lang.cc (d_post_options): Set flag_rtti and flag_exceptions if -fno-druntime was seen on command-line. (d_type_promotes_to): Use resolvedLinkage to get declaration linkage. * decl.cc (make_thunk): Likewise. * types.cc (layout_aggregate_members): Ignore anonymous fields in total count. libphobos/ChangeLog: * src/MERGE: Merge upstream phobos 604534d7c. --- gcc/d/d-codegen.cc | 17 ++++----- gcc/d/d-gimplify.cc | 3 +- gcc/d/d-lang.cc | 16 +++++++-- gcc/d/decl.cc | 4 +-- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/VERSION | 2 +- gcc/d/dmd/clone.d | 22 +++++++----- gcc/d/dmd/dclass.d | 2 +- gcc/d/dmd/declaration.d | 10 ++++-- gcc/d/dmd/declaration.h | 3 +- gcc/d/dmd/dmangle.d | 10 +++--- gcc/d/dmd/dsymbolsem.d | 20 +++++------ gcc/d/dmd/dtemplate.d | 2 +- gcc/d/dmd/dtoh.d | 19 ++++++---- gcc/d/dmd/escape.d | 2 +- gcc/d/dmd/expressionsem.d | 35 +++++++++++++++++-- gcc/d/dmd/func.d | 17 ++++----- gcc/d/dmd/initsem.d | 12 +++++++ gcc/d/dmd/json.d | 2 +- gcc/d/dmd/mtype.d | 25 +++++++++++-- gcc/d/dmd/objc.d | 6 ++-- gcc/d/dmd/semantic2.d | 15 ++++---- gcc/d/dmd/semantic3.d | 2 +- gcc/d/dmd/traits.d | 6 ++-- gcc/d/types.cc | 10 ++++-- gcc/testsuite/gdc.test/compilable/test23097.d | 33 +++++++++++++++++ .../extra-files/test23109/object.d | 17 +++++++++ .../gdc.test/fail_compilation/fail12604.d | 4 +-- .../gdc.test/fail_compilation/fail23108a.d | 16 +++++++++ .../gdc.test/fail_compilation/fail23108b.d | 18 ++++++++++ .../gdc.test/fail_compilation/fail23109.d | 12 +++++++ .../gdc.test/fail_compilation/fail3703.d | 4 +-- .../gdc.test/fail_compilation/fail_scope.d | 30 ++++++++-------- .../gdc.test/fail_compilation/ice23097.d | 28 +++++++++++++++ .../fail_compilation/imports/test23109a.d | 10 ++++++ .../fail_compilation/imports/test23109b.d | 10 ++++++ .../fail_compilation/imports/test23109c.d | 3 ++ .../gdc.test/fail_compilation/test9150.d | 2 +- gcc/testsuite/gdc.test/runnable/test20734.d | 28 +++++++++++++++ libphobos/src/MERGE | 2 +- 40 files changed, 375 insertions(+), 106 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/test23097.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/extra-files/test23109/object.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23108a.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23108b.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail23109.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/ice23097.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/test23109a.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/test23109b.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/test23109c.d create mode 100644 gcc/testsuite/gdc.test/runnable/test20734.d diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index bb96b2f8d28..22090a8c755 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -76,7 +76,7 @@ d_decl_context (Dsymbol *dsym) but only for extern(D) symbols. */ if (parent->isModule ()) { - if ((decl != NULL && decl->linkage != LINK::d) + if ((decl != NULL && decl->resolvedLinkage () != LINK::d) || (ad != NULL && ad->classKind != ClassKind::d)) return NULL_TREE; @@ -1165,7 +1165,7 @@ build_struct_literal (tree type, vec <constructor_elt, va_gc> *init) } vec <constructor_elt, va_gc> *ve = NULL; - HOST_WIDE_INT offset = 0; + HOST_WIDE_INT bitoffset = 0; bool constant_p = true; bool finished = false; @@ -1210,11 +1210,11 @@ build_struct_literal (tree type, vec <constructor_elt, va_gc> *init) if (is_initialized) { - HOST_WIDE_INT fieldpos = int_byte_position (field); + HOST_WIDE_INT fieldpos = int_bit_position (field); gcc_assert (value != NULL_TREE); /* Must not initialize fields that overlap. */ - if (fieldpos < offset) + if (fieldpos < bitoffset) { /* Find the nearest user defined type and field. */ tree vtype = type; @@ -1243,12 +1243,9 @@ build_struct_literal (tree type, vec <constructor_elt, va_gc> *init) finished = true; } - /* Move offset to the next position in the struct. */ - if (TREE_CODE (type) == RECORD_TYPE) - { - offset = int_byte_position (field) - + int_size_in_bytes (TREE_TYPE (field)); - } + /* Move bit offset to the next position in the struct. */ + if (TREE_CODE (type) == RECORD_TYPE && DECL_SIZE (field)) + bitoffset = int_bit_position (field) + tree_to_shwi (DECL_SIZE (field)); /* If all initializers have been assigned, there's nothing else to do. */ if (vec_safe_is_empty (init)) diff --git a/gcc/d/d-gimplify.cc b/gcc/d/d-gimplify.cc index a98089b7cca..36b76da3acc 100644 --- a/gcc/d/d-gimplify.cc +++ b/gcc/d/d-gimplify.cc @@ -109,7 +109,8 @@ d_gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) } /* Same as above, but for bit-field assignments. */ - if (bit_field_ref (op0) && TREE_TYPE (op0) != TREE_TYPE (op1)) + if ((bit_field_ref (op0) || bit_field_ref (op1)) + && TREE_TYPE (op0) != TREE_TYPE (op1)) { TREE_OPERAND (*expr_p, 1) = convert (TREE_TYPE (op0), op1); return GS_OK; diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index 9adcabdf7cf..dc8560f799a 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -904,16 +904,26 @@ d_post_options (const char ** fn) ? CHECKENABLEoff : CHECKENABLEon; } + /* When not linking against D runtime, turn off all code generation that + would otherwise reference it. */ if (global.params.betterC) { if (!OPTION_SET_P (flag_moduleinfo)) global.params.useModuleInfo = false; + /* Ensure that the front-end options are in sync with the `-frtti' and + `-fexceptions' flags. */ if (!OPTION_SET_P (flag_rtti)) - global.params.useTypeInfo = false; + { + global.params.useTypeInfo = false; + flag_rtti = false; + } if (!OPTION_SET_P (flag_exceptions)) - global.params.useExceptions = false; + { + global.params.useExceptions = false; + flag_exceptions = false; + } global.params.checkAction = CHECKACTION_C; } @@ -1558,7 +1568,7 @@ d_type_promotes_to (tree type) /* Promotions are only applied on unnamed function arguments for declarations with `extern(C)' or `extern(C++)' linkage. */ if (cfun && DECL_LANG_FRONTEND (cfun->decl) - && DECL_LANG_FRONTEND (cfun->decl)->linkage != LINK::d) + && DECL_LANG_FRONTEND (cfun->decl)->resolvedLinkage () != LINK::d) { /* In [type/integer-promotions], integer promotions are conversions of the following types: diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 86ea1761f4f..f5c21078aad 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -1845,7 +1845,7 @@ make_thunk (FuncDeclaration *decl, int offset) forcing a D local thunk to be emitted. */ const char *ident; - if (decl->linkage == LINK::cpp) + if (decl->resolvedLinkage () == LINK::cpp) ident = target.cpp.thunkMangle (decl, offset); else { @@ -1862,7 +1862,7 @@ make_thunk (FuncDeclaration *decl, int offset) d_keep (thunk); - if (decl->linkage != LINK::cpp) + if (decl->resolvedLinkage () != LINK::cpp) free (CONST_CAST (char *, ident)); if (!DECL_EXTERNAL (function)) diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 73697fba8e6..d538621ba83 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -88de5e369b2c322e55174ae4f3bef5ad0c0c0930 +a53934d18eecccbf677cd32a4febeff3bc0ee292 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/VERSION b/gcc/d/dmd/VERSION index 0ad60f92b8f..5ea2ba0d8ec 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.100.0-rc.1 +v2.100.0 diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index 9c8c1c316bf..75a16bd2da4 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -563,9 +563,12 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc) e = new DotIdExp(sd.loc, e, Id.object); e = new DotIdExp(sd.loc, e, id); e = e.expressionSemantic(sc); - Dsymbol s = getDsymbol(e); - assert(s); - sd.xerreq = s.isFuncDeclaration(); + if (!e.isErrorExp()) + { + Dsymbol s = getDsymbol(e); + assert(s); + sd.xerreq = s.isFuncDeclaration(); + } } Loc declLoc; // loc is unnecessary so __xopEquals is never called directly Loc loc; // loc is unnecessary so errors are gagged @@ -684,9 +687,12 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc) e = new DotIdExp(sd.loc, e, Id.object); e = new DotIdExp(sd.loc, e, id); e = e.expressionSemantic(sc); - Dsymbol s = getDsymbol(e); - assert(s); - sd.xerrcmp = s.isFuncDeclaration(); + if (!e.isErrorExp()) + { + Dsymbol s = getDsymbol(e); + assert(s); + sd.xerrcmp = s.isFuncDeclaration(); + } } Loc declLoc; // loc is unnecessary so __xopCmp is never called directly Loc loc; // loc is unnecessary so errors are gagged @@ -867,7 +873,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc) // Build the field destructor (`ad.fieldDtor`), if needed. // If the user dtor is an extern(C++) prototype, then we expect it performs a full-destruction and skip building. - const bool dtorIsCppPrototype = ad.userDtors.dim && ad.userDtors[0].linkage == LINK.cpp && !ad.userDtors[0].fbody; + const bool dtorIsCppPrototype = ad.userDtors.dim && ad.userDtors[0]._linkage == LINK.cpp && !ad.userDtors[0].fbody; if (!dtorIsCppPrototype) { Expression e = null; @@ -1019,7 +1025,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc) // Set/build `ad.dtor`. // On Windows, the dtor in the vtable is a shim with different signature. - ad.dtor = (ad.aggrDtor && ad.aggrDtor.linkage == LINK.cpp && !target.cpp.twoDtorInVtable) + ad.dtor = (ad.aggrDtor && ad.aggrDtor._linkage == LINK.cpp && !target.cpp.twoDtorInVtable) ? buildWindowsCppDtor(ad, ad.aggrDtor, sc) : ad.aggrDtor; diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d index 15ac8d91735..a4a2abf4144 100644 --- a/gcc/d/dmd/dclass.d +++ b/gcc/d/dmd/dclass.d @@ -984,7 +984,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration auto var = new VarDeclaration(loc, vtype, Identifier.idPool("__vtbl"), null, STC.immutable_ | STC.static_); var.addMember(null, this); var.isdataseg = 1; - var.linkage = LINK.d; + var._linkage = LINK.d; var.semanticRun = PASS.semanticdone; // no more semantic wanted vtblsym = var; } diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index a533d30ca80..7b50c050487 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -221,7 +221,7 @@ extern (C++) abstract class Declaration : Dsymbol Type originalType; // before semantic analysis StorageClass storage_class = STC.undefined_; Visibility visibility; - LINK linkage = LINK.default_; + LINK _linkage = LINK.default_; // may be `LINK.system`; use `resolvedLinkage()` to resolve it short inuse; // used to detect cycles ubyte adFlags; // control re-assignment of AliasDeclaration (put here for packing reasons) @@ -420,6 +420,12 @@ extern (C++) abstract class Declaration : Dsymbol return (storage_class & STC.static_) != 0; } + /// Returns the linkage, resolving the target-specific `System` one. + final LINK resolvedLinkage() const + { + return _linkage == LINK.system ? target.systemLinkage() : _linkage; + } + bool isDelete() { return false; @@ -1919,7 +1925,7 @@ extern (C++) class TypeInfoDeclaration : VarDeclaration this.tinfo = tinfo; storage_class = STC.static_ | STC.gshared; visibility = Visibility(Visibility.Kind.public_); - linkage = LINK.c; + _linkage = LINK.c; alignment.set(target.ptrsize); } diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index 7e51b057dc1..6fe4a221c3b 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -115,7 +115,7 @@ public: Type *originalType; // before semantic analysis StorageClass storage_class; Visibility visibility; - LINK linkage; + LINK _linkage; // may be `LINK::system`; use `resolvedLinkage()` to resolve it short inuse; // used to detect cycles uint8_t adFlags; Symbol* isym; // import version of csym @@ -127,6 +127,7 @@ public: Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); bool isStatic() const { return (storage_class & STCstatic) != 0; } + LINK resolvedLinkage() const; // returns the linkage, resolving the target-specific `System` one virtual bool isDelete(); virtual bool isDataseg(); virtual bool isThreadlocal(); diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d index 3d9730348f5..76042969b9b 100644 --- a/gcc/d/dmd/dmangle.d +++ b/gcc/d/dmd/dmangle.d @@ -1337,17 +1337,17 @@ extern (D) const(char)[] externallyMangledIdentifier(Declaration d) { assert(!d.mangleOverride, "mangle overrides should have been handled earlier"); + const linkage = d.resolvedLinkage(); const par = d.toParent(); //toParent() skips over mixin templates - if (!par || par.isModule() || d.linkage == LINK.cpp || - (d.linkage == LINK.c && d.isCsymbol() && + if (!par || par.isModule() || linkage == LINK.cpp || + (linkage == LINK.c && d.isCsymbol() && (d.isFuncDeclaration() || (d.isVarDeclaration() && d.isDataseg() && d.storage_class & STC.extern_)))) { - if (d.linkage != LINK.d && d.localNum) + if (linkage != LINK.d && d.localNum) d.error("the same declaration cannot be in multiple scopes with non-D linkage"); - const l = d.linkage == LINK.system ? target.systemLinkage() : d.linkage; - final switch (l) + final switch (linkage) { case LINK.d: break; diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 5415401e0e4..be8f9150903 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -376,7 +376,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // https://issues.dlang.org/show_bug.cgi?id=19482 if ((dsym.storage_class & (STC.foreach_ | STC.local)) == (STC.foreach_ | STC.local)) { - dsym.linkage = LINK.d; + dsym._linkage = LINK.d; dsym.visibility = Visibility(Visibility.Kind.public_); dsym.overlapped = false; // unset because it is modified early on this function dsym.userAttribDecl = null; // unset because it is set by Dsymbol.setScope() @@ -389,7 +389,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor dsym.storage_class |= (sc.stc & ~(STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_)); dsym.userAttribDecl = sc.userAttribDecl; dsym.cppnamespace = sc.namespace; - dsym.linkage = sc.linkage; + dsym._linkage = sc.linkage; dsym.visibility = sc.visibility; dsym.alignment = sc.alignment(); } @@ -1191,7 +1191,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor override void visit(TypeInfoDeclaration dsym) { - assert(dsym.linkage == LINK.c); + assert(dsym._linkage == LINK.c); } override void visit(BitFieldDeclaration dsym) @@ -2174,7 +2174,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor em.semanticRun = PASS.semantic; em.type = Type.tint32; - em.linkage = LINK.c; + em._linkage = LINK.c; em.storage_class |= STC.manifest; if (em.value) { @@ -2264,7 +2264,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor em.semanticRun = PASS.semantic; em.visibility = em.ed.isAnonymous() ? em.ed.visibility : Visibility(Visibility.Kind.public_); - em.linkage = LINK.d; + em._linkage = LINK.d; em.storage_class |= STC.manifest; // https://issues.dlang.org/show_bug.cgi?id=9701 @@ -3024,7 +3024,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (sc.flags & SCOPE.compile) funcdecl.flags |= FUNCFLAG.compileTimeOnly; // don't emit code for this function - funcdecl.linkage = sc.linkage; + funcdecl._linkage = sc.linkage; if (auto fld = funcdecl.isFuncLiteralDeclaration()) { if (fld.treq) @@ -3037,7 +3037,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor fld.tok = TOK.function_; else assert(0); - funcdecl.linkage = treq.nextOf().toTypeFunction().linkage; + funcdecl._linkage = treq.nextOf().toTypeFunction().linkage; } } @@ -3048,7 +3048,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // check pragma(crt_constructor) if (funcdecl.flags & (FUNCFLAG.CRTCtor | FUNCFLAG.CRTDtor)) { - if (funcdecl.linkage != LINK.c) + if (funcdecl._linkage != LINK.c) { funcdecl.error("must be `extern(C)` for `pragma(%s)`", (funcdecl.flags & FUNCFLAG.CRTCtor) ? "crt_constructor".ptr : "crt_destructor".ptr); @@ -3057,7 +3057,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor funcdecl.visibility = sc.visibility; funcdecl.userAttribDecl = sc.userAttribDecl; - UserAttributeDeclaration.checkGNUABITag(funcdecl, funcdecl.linkage); + UserAttributeDeclaration.checkGNUABITag(funcdecl, funcdecl._linkage); checkMustUseReserved(funcdecl); if (!funcdecl.originalType) @@ -3193,7 +3193,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor tf.isScopeQual = false; } - sc.linkage = funcdecl.linkage; + sc.linkage = funcdecl._linkage; if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested())) { diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index fb41e2bd05f..ed0126eeef6 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -2777,7 +2777,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, fd.storage_class == m.lastf.storage_class && fd.parent == m.lastf.parent && fd.visibility == m.lastf.visibility && - fd.linkage == m.lastf.linkage) + fd._linkage == m.lastf._linkage) { if (fd.fbody && !m.lastf.fbody) goto LfIsBetter; diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d index 41fb82b8266..17abb7d3b00 100644 --- a/gcc/d/dmd/dtoh.d +++ b/gcc/d/dmd/dtoh.d @@ -966,12 +966,13 @@ public: if (vd.storage_class & (AST.STC.static_ | AST.STC.extern_ | AST.STC.gshared) || vd.parent && vd.parent.isModule()) { - if (vd.linkage != LINK.c && vd.linkage != LINK.cpp && !(tdparent && (this.linkage == LINK.c || this.linkage == LINK.cpp))) + const vdLinkage = vd.resolvedLinkage(); + if (vdLinkage != LINK.c && vdLinkage != LINK.cpp && !(tdparent && (this.linkage == LINK.c || this.linkage == LINK.cpp))) { ignored("variable %s because of linkage", vd.toPrettyChars()); return; } - if (vd.mangleOverride && vd.linkage != LINK.c) + if (vd.mangleOverride && vdLinkage != LINK.c) { ignored("variable %s because C++ doesn't support explicit mangling", vd.toPrettyChars()); return; @@ -987,7 +988,7 @@ public: return; } writeProtection(vd.visibility.kind); - if (vd.linkage == LINK.c) + if (vdLinkage == LINK.c) buf.writestring("extern \"C\" "); else if (!adparent) buf.writestring("extern "); @@ -2805,7 +2806,10 @@ public: // Check against the internal information which might be missing, e.g. inside of template declarations if (auto dec = sym.isDeclaration()) - return dec.linkage == LINK.cpp || dec.linkage == LINK.c; + { + const l = dec.resolvedLinkage(); + return l == LINK.cpp || l == LINK.c; + } if (auto ad = sym.isAggregateDeclaration()) return ad.classKind == ClassKind.cpp; @@ -2853,8 +2857,11 @@ public: if (!res) { // Check against the internal information which might be missing, e.g. inside of template declarations - auto dec = sym.isDeclaration(); - res = dec && (dec.linkage == LINK.cpp || dec.linkage == LINK.c); + if (auto dec = sym.isDeclaration()) + { + const l = dec.resolvedLinkage(); + res = (l == LINK.cpp || l == LINK.c); + } } // Remember result for later calls diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index 44c3757248b..7c7ba96db0d 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -2360,5 +2360,5 @@ private bool setUnsafeDIP1000(FuncDeclaration f) { return global.params.useDIP1000 == FeatureState.enabled ? f.setUnsafe() - : f.isSafeBypassingInference(); + : false; // reverted for 2.100, retry in 2.101 } diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index d4e96bb0f09..717420910aa 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -2064,7 +2064,8 @@ private bool functionParameters(const ref Loc loc, Scope* sc, ale.type = ale.type.nextOf().sarrayOf(ale.elements ? ale.elements.length : 0); auto tmp = copyToTemp(0, "__arrayliteral_on_stack", ale); auto declareTmp = new DeclarationExp(ale.loc, tmp); - auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp), p.type); + auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp), + p.type.substWildTo(MODFlags.mutable)); arg = CommaExp.combine(declareTmp, castToSlice); arg = arg.expressionSemantic(sc); } @@ -6625,6 +6626,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.type = exp.type.addMod(t1.mod); + // https://issues.dlang.org/show_bug.cgi?id=23109 + // Run semantic on the DotVarExp type + if (auto handle = exp.type.isClassHandle()) + { + if (handle.semanticRun < PASS.semanticdone && !handle.isBaseInfoComplete()) + handle.dsymbolSemantic(null); + } + Dsymbol vparent = exp.var.toParent(); AggregateDeclaration ad = vparent ? vparent.isAggregateDeclaration() : null; if (Expression e1x = getRightThis(exp.loc, sc, ad, exp.e1, exp.var, 1)) @@ -8675,7 +8684,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { static if (LOGSEMANTIC) { - printf("AssignExp::semantic('%s')\n", exp.toChars()); + if (exp.op == EXP.blit) printf("BlitExp.toElem('%s')\n", exp.toChars()); + if (exp.op == EXP.assign) printf("AssignExp.toElem('%s')\n", exp.toChars()); + if (exp.op == EXP.construct) printf("ConstructExp.toElem('%s')\n", exp.toChars()); } //printf("exp.e1.op = %d, '%s'\n", exp.e1.op, EXPtoString(exp.e1.op).ptr); //printf("exp.e2.op = %d, '%s'\n", exp.e2.op, EXPtoString(exp.e2.op).ptr); @@ -9425,6 +9436,23 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Expression e1x = exp.e1; Expression e2x = exp.e2; + /* C strings come through as static arrays. May need to adjust the size of the + * string to match the size of e1. + */ + Type t2 = e2x.type.toBasetype(); + if (sc.flags & SCOPE.Cfile && e2x.isStringExp() && t2.isTypeSArray()) + { + uinteger_t dim1 = t1.isTypeSArray().dim.toInteger(); + uinteger_t dim2 = t2.isTypeSArray().dim.toInteger(); + if (dim1 + 1 == dim2 || dim2 < dim1) + { + auto tsa2 = t2.isTypeSArray(); + auto newt = tsa2.next.sarrayOf(dim1).immutableOf(); + e2x = castTo(e2x, sc, newt); + exp.e2 = e2x; + } + } + if (e2x.implicitConvTo(e1x.type)) { if (exp.op != EXP.blit && (e2x.op == EXP.slice && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op == EXP.cast_ && (cast(UnaExp)e2x).e1.isLvalue() || e2x.op != EXP.slice && e2x.isLvalue())) @@ -9686,13 +9714,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor tsa2 = cast(TypeSArray)toStaticArrayType(se); else tsa2 = t2.isTypeSArray(); + if (tsa1 && tsa2) { uinteger_t dim1 = tsa1.dim.toInteger(); uinteger_t dim2 = tsa2.dim.toInteger(); if (dim1 != dim2) { - exp.error("mismatched array lengths, %d and %d", cast(int)dim1, cast(int)dim2); + exp.error("mismatched array lengths %d and %d for assignment `%s`", cast(int)dim1, cast(int)dim2, exp.toChars()); return setError(); } } diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index 2e9c2bff1e0..55abe4d52e7 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -1207,12 +1207,12 @@ extern (C++) class FuncDeclaration : Declaration final bool isMain() const { - return ident == Id.main && linkage != LINK.c && !isMember() && !isNested(); + return ident == Id.main && resolvedLinkage() != LINK.c && !isMember() && !isNested(); } final bool isCMain() const { - return ident == Id.main && linkage == LINK.c && !isMember() && !isNested(); + return ident == Id.main && resolvedLinkage() == LINK.c && !isMember() && !isNested(); } final bool isWinMain() const @@ -1220,24 +1220,24 @@ extern (C++) class FuncDeclaration : Declaration //printf("FuncDeclaration::isWinMain() %s\n", toChars()); version (none) { - bool x = ident == Id.WinMain && linkage != LINK.c && !isMember(); + bool x = ident == Id.WinMain && resolvedLinkage() != LINK.c && !isMember(); printf("%s\n", x ? "yes" : "no"); return x; } else { - return ident == Id.WinMain && linkage != LINK.c && !isMember(); + return ident == Id.WinMain && resolvedLinkage() != LINK.c && !isMember(); } } final bool isDllMain() const { - return ident == Id.DllMain && linkage != LINK.c && !isMember(); + return ident == Id.DllMain && resolvedLinkage() != LINK.c && !isMember(); } final bool isRtInit() const { - return ident == Id.rt_init && linkage == LINK.c && !isMember() && !isNested(); + return ident == Id.rt_init && resolvedLinkage() == LINK.c && !isMember() && !isNested(); } override final bool isExport() const @@ -1776,7 +1776,7 @@ extern (C++) class FuncDeclaration : Declaration auto f = toAliasFunc(); //printf("\ttoParent2() = '%s'\n", f.toParent2().toChars()); return ((f.storage_class & STC.static_) == 0) && - (f.linkage == LINK.d) && + (f._linkage == LINK.d) && (f.toParent2().isFuncDeclaration() !is null || f.toParent2() !is f.toParentLocal()); } @@ -2663,7 +2663,7 @@ extern (C++) class FuncDeclaration : Declaration tf = new TypeFunction(ParameterList(fparams), treturn, LINK.c, stc); fd = new FuncDeclaration(Loc.initial, Loc.initial, id, STC.static_, tf); fd.visibility = Visibility(Visibility.Kind.public_); - fd.linkage = LINK.c; + fd._linkage = LINK.c; st.insert(fd); } @@ -2723,6 +2723,7 @@ extern (C++) class FuncDeclaration : Declaration const nparams = tf.parameterList.length; bool argerr; + const linkage = resolvedLinkage(); if (linkage == LINK.d) { if (nparams == 1) diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index c84a9f69ffa..16e7c3a5936 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -502,6 +502,18 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ i.exp = se.castTo(sc, t); goto L1; } + + /* Lop off terminating 0 of initializer for: + * static char s[5] = "hello"; + */ + if (sc.flags & SCOPE.Cfile && + typeb.ty == Tsarray && + tynto.isSomeChar && + tb.isTypeSArray().dim.toInteger() + 1 == typeb.isTypeSArray().dim.toInteger()) + { + i.exp = se.castTo(sc, t); + goto L1; + } } /* C11 6.7.9-14..15 * Initialize an array of unknown size with a string. diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d index fc270390fa4..b7ffa19d6ff 100644 --- a/gcc/d/dmd/json.d +++ b/gcc/d/dmd/json.d @@ -446,7 +446,7 @@ public: return; jsonProperties(cast(Dsymbol)d); propertyStorageClass("storageClass", d.storage_class); - property("linkage", d.linkage); + property("linkage", d._linkage); property("type", "deco", d.type); // Emit originalType if it differs from type if (d.type != d.originalType && d.originalType) diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 13df0d71f3f..32f57d46773 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -4764,12 +4764,31 @@ extern (C++) final class TypeFunction : TypeNext s ~= "@safe "; if (!f.isNogc && sc.func.setGC()) s ~= "nogc "; - s[$-1] = '\0'; - buf.printf("`%s` copy constructor cannot be called from a `%s` context", f.type.toChars(), s.ptr); - + if (s) + { + s[$-1] = '\0'; + buf.printf("`%s` copy constructor cannot be called from a `%s` context", f.type.toChars(), s.ptr); + } + else if (f.isGenerated() && f.isDisabled()) + { + /* https://issues.dlang.org/show_bug.cgi?id=23097 + * Compiler generated copy constructor failed. + */ + buf.printf("generating a copy constructor for `struct %s` failed, therefore instances of it are uncopyable", + argStruct.toChars()); + } + else + { + /* Although a copy constructor may exist, no suitable match was found. + * i.e: `inout` constructor creates `const` object, not mutable. + * Fallback to using the original generic error before bugzilla 22202. + */ + goto Lnocpctor; + } } else { + Lnocpctor: buf.printf("`struct %s` does not define a copy constructor for `%s` to `%s` copies", argStruct.toChars(), targ.toChars(), tprm.toChars()); } diff --git a/gcc/d/dmd/objc.d b/gcc/d/dmd/objc.d index 9e92212ada1..9afedc1c27b 100644 --- a/gcc/d/dmd/objc.d +++ b/gcc/d/dmd/objc.d @@ -578,7 +578,7 @@ extern(C++) private final class Supported : Objc override void checkLinkage(FuncDeclaration fd) { - if (fd.linkage != LINK.objc && fd.objc.selector) + if (fd._linkage != LINK.objc && fd.objc.selector) fd.error("must have Objective-C linkage to attach a selector"); } @@ -640,11 +640,11 @@ extern(C++) private final class Supported : Objc if (!fd.objc.isOptional) return; - if (fd.linkage != LINK.objc) + if (fd._linkage != LINK.objc) { fd.error("only functions with Objective-C linkage can be declared as optional"); - const linkage = linkageToString(fd.linkage); + const linkage = linkageToString(fd._linkage); errorSupplemental(fd.loc, "function is declared with %.*s linkage", cast(uint) linkage.length, linkage.ptr); diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d index cd65920e38b..73dcaa6c960 100644 --- a/gcc/d/dmd/semantic2.d +++ b/gcc/d/dmd/semantic2.d @@ -238,7 +238,7 @@ private extern(C++) final class Semantic2Visitor : Visitor return; } - UserAttributeDeclaration.checkGNUABITag(vd, vd.linkage); + UserAttributeDeclaration.checkGNUABITag(vd, vd._linkage); if (vd._init && !vd.toParent().isFuncDeclaration()) { @@ -379,6 +379,7 @@ private extern(C++) final class Semantic2Visitor : Visitor alias f1 = fd; auto tf1 = cast(TypeFunction) f1.type; auto parent1 = f1.toParent2(); + const linkage1 = f1.resolvedLinkage(); overloadApply(f1, (Dsymbol s) { @@ -391,7 +392,7 @@ private extern(C++) final class Semantic2Visitor : Visitor return 0; // Functions with different manglings can never conflict - if (f1.linkage != f2.linkage) + if (linkage1 != f2.resolvedLinkage()) return 0; // Functions with different names never conflict @@ -428,12 +429,12 @@ private extern(C++) final class Semantic2Visitor : Visitor // @@@DEPRECATED_2.104@@@ // Deprecated in 2020-08, make this an error in 2.104 if (parent1.isModule() && - f1.linkage != LINK.d && f1.linkage != LINK.cpp && + linkage1 != LINK.d && linkage1 != LINK.cpp && (!sameAttr || !sameParams) ) { f2.deprecation("cannot overload `extern(%s)` function at %s", - linkageToChars(f1.linkage), + linkageToChars(f1._linkage), f1.loc.toChars()); return 0; } @@ -443,7 +444,7 @@ private extern(C++) final class Semantic2Visitor : Visitor return 0; // Different attributes don't conflict in extern(D) - if (!sameAttr && f1.linkage == LINK.d) + if (!sameAttr && linkage1 == LINK.d) return 0; error(f2.loc, "%s `%s%s` conflicts with previous declaration at %s", @@ -460,7 +461,7 @@ private extern(C++) final class Semantic2Visitor : Visitor return; TypeFunction f = cast(TypeFunction) fd.type; - UserAttributeDeclaration.checkGNUABITag(fd, fd.linkage); + UserAttributeDeclaration.checkGNUABITag(fd, fd._linkage); //semantic for parameters' UDAs foreach (i, param; f.parameterList) { @@ -643,7 +644,7 @@ private extern(C++) final class Semantic2Visitor : Visitor { //printf(" found\n"); // Check that calling conventions match - if (fd.linkage != ifd.linkage) + if (fd._linkage != ifd._linkage) fd.error("linkage doesn't match interface function"); // Check that it is current diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index 2e459b1857f..41f8d525929 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -1353,7 +1353,7 @@ private extern(C++) final class Semantic3Visitor : Visitor if (funcdecl.isCtorDeclaration()) // https://issues.dlang.org/show_bug.cgi?id=#15665 f.isctor = true; sc.stc = 0; - sc.linkage = funcdecl.linkage; // https://issues.dlang.org/show_bug.cgi?id=8496 + sc.linkage = funcdecl._linkage; // https://issues.dlang.org/show_bug.cgi?id=8496 funcdecl.type = f.typeSemantic(funcdecl.loc, sc); sc = sc.pop(); } diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index db77107e4ae..9db0012dd01 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -1381,7 +1381,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) e.error("argument to `__traits(getFunctionVariadicStyle, %s)` is not a function", o.toChars()); return ErrorExp.get(); } - link = fd.linkage; + link = fd._linkage; varargs = fd.getParameterList().varargs; } string style; @@ -1515,7 +1515,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) if (tf) { - link = fd ? fd.toAliasFunc().linkage : tf.linkage; + link = fd ? fd.toAliasFunc()._linkage : tf.linkage; } else { @@ -1529,7 +1529,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) } if (d !is null) - link = d.linkage; + link = d._linkage; else { // Resolves forward references diff --git a/gcc/d/types.cc b/gcc/d/types.cc index d897ec4c5e4..c54049dfb98 100644 --- a/gcc/d/types.cc +++ b/gcc/d/types.cc @@ -375,7 +375,7 @@ fixup_anonymous_offset (tree fields, tree offset) /* Iterate over all MEMBERS of an aggregate, and add them as fields to CONTEXT. If INHERITED_P is true, then the members derive from a base class. - Returns the number of fields found. */ + Returns the number of named fields found. */ static size_t layout_aggregate_members (Dsymbols *members, tree context, bool inherited_p) @@ -418,7 +418,8 @@ layout_aggregate_members (Dsymbols *members, tree context, bool inherited_p) /* Insert the field declaration at its given offset. */ if (var->isField ()) { - const char *ident = var->ident ? var->ident->toChars () : NULL; + const char *ident = (var->ident && !var->ident->isAnonymous ()) + ? var->ident->toChars () : NULL; tree field = create_field_decl (declaration_type (var), ident, inherited_p, inherited_p); apply_user_attributes (var, field); @@ -442,7 +443,10 @@ layout_aggregate_members (Dsymbols *members, tree context, bool inherited_p) var->csym = field; } - fields += 1; + /* Only count the named fields in an aggregate. */ + if (ident != NULL) + fields += 1; + continue; } } diff --git a/gcc/testsuite/gdc.test/compilable/test23097.d b/gcc/testsuite/gdc.test/compilable/test23097.d new file mode 100644 index 00000000000..092bd774f22 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23097.d @@ -0,0 +1,33 @@ +/* https://issues.dlang.org/show_bug.cgi?id=23097 +REQUIRED_ARGS: -verrors=spec +TEST_OUTPUT: +--- +(spec:2) compilable/test23097.d(14): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable +(spec:2) compilable/test23097.d(14): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable +(spec:1) compilable/test23097.d(14): Error: generated function `test23097.S23097.opAssign(S23097 p)` is not callable using argument types `(const(S23097))` +(spec:2) compilable/test23097.d(14): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable +(spec:1) compilable/test23097.d(14): `struct S23097` does not define a copy constructor for `const(S23097)` to `S23097` copies +--- +*/ +void emplaceRef(UT, Args)(UT chunk, Args args) +{ + static if (__traits(compiles, chunk = args)) + chunk = args; +} + +struct CpCtor23097(T) +{ + T* payload; + this(ref inout typeof(this)) { } + ref opAssign(typeof(this)) { } +} + +struct S23097 +{ + CpCtor23097!int payload; +} + +void test23097(S23097 lhs, const S23097 rhs) +{ + emplaceRef(lhs, rhs); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/extra-files/test23109/object.d b/gcc/testsuite/gdc.test/fail_compilation/extra-files/test23109/object.d new file mode 100644 index 00000000000..747b6e9cc4d --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/extra-files/test23109/object.d @@ -0,0 +1,17 @@ +module object; + +alias size_t = typeof(int.sizeof); +class Object {} +auto opEquals(Object ) { return true; } +class TypeInfo {} +class TypeInfo_Const {} +bool _xopEquals() { return true; } + +bool __equals(T1, T2)(T1[] lhs, T2[] rhs) +{ + static at(R)(R[] r, size_t i) { return r.ptr[i]; } + foreach (u; 0 .. lhs.length) + if (at(lhs, u) != at(rhs, u)) + return false; + return true; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12604.d b/gcc/testsuite/gdc.test/fail_compilation/fail12604.d index 2ed8ebf9cc9..bed87351bc5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail12604.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail12604.d @@ -66,8 +66,8 @@ void test12606b() // ExpInitializer::semantic /* TEST_OUTPUT: --- -fail_compilation/fail12604.d(77): Error: mismatched array lengths, 4 and 3 -fail_compilation/fail12604.d(78): Error: mismatched array lengths, 4 and 3 +fail_compilation/fail12604.d(77): Error: mismatched array lengths 4 and 3 for assignment `sa1[0..4] = [1, 2, 3]` +fail_compilation/fail12604.d(78): Error: mismatched array lengths 4 and 3 for assignment `sa1[0..4] = sa2` --- */ void testc() diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23108a.d b/gcc/testsuite/gdc.test/fail_compilation/fail23108a.d new file mode 100644 index 00000000000..a974871a38a --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23108a.d @@ -0,0 +1,16 @@ +// https://issues.dlang.org/show_bug.cgi?id=23108 +/* TEST_OUTPUT: +--- +fail_compilation/fail23108a.d(9): Error: undefined identifier `_xopEquals` in module `object` +--- +*/ +module object; + +struct Interface +{ + void[] vtbl; +} + +class TypeInfo +{ +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23108b.d b/gcc/testsuite/gdc.test/fail_compilation/fail23108b.d new file mode 100644 index 00000000000..10eae37c401 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23108b.d @@ -0,0 +1,18 @@ +// https://issues.dlang.org/show_bug.cgi?id=23108 +/* TEST_OUTPUT: +--- +fail_compilation/fail23108b.d(10): Error: undefined identifier `_xopEquals` in module `object` +fail_compilation/fail23108b.d(10): Error: undefined identifier `_xopCmp` in module `object` +--- +*/ +module object; + +struct Interface +{ + void[] vtbl; + int opCmp() { return 0; } +} + +class TypeInfo +{ +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23109.d b/gcc/testsuite/gdc.test/fail_compilation/fail23109.d new file mode 100644 index 00000000000..91b4e79ad2d --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23109.d @@ -0,0 +1,12 @@ +// https://issues.dlang.org/show_bug.cgi?id=23109 +/* +EXTRA_FILES: imports/test23109a.d imports/test23109b.d imports/test23109c.d +EXTRA_SOURCES: extra-files/test23109/object.d +TEST_OUTPUT: +--- +Error: no property `getHash` for type `object.TypeInfo_Const` +Error: no property `getHash` for type `object.TypeInfo_Const` +fail_compilation/imports/test23109a.d(10): Error: template instance `imports.test23109a.Array!(Ensure)` error instantiating +--- +*/ +import imports.test23109a; diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail3703.d b/gcc/testsuite/gdc.test/fail_compilation/fail3703.d index 6b4edd5b629..d2d277f5065 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail3703.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail3703.d @@ -3,8 +3,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail3703.d(18): Error: mismatched array lengths, 2 and 1 -fail_compilation/fail3703.d(20): Error: mismatched array lengths, 2 and 1 +fail_compilation/fail3703.d(18): Error: mismatched array lengths 2 and 1 for assignment `b[] = a` +fail_compilation/fail3703.d(20): Error: mismatched array lengths 2 and 1 for assignment `b[] = a` fail_compilation/fail3703.d(22): Error: mismatched array lengths, 3 and 2 fail_compilation/fail3703.d(23): Error: mismatched array lengths, 2 and 3 fail_compilation/fail3703.d(25): Error: mismatched array lengths, 3 and 2 diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d index 07c3766d490..41a8c2d85e3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d @@ -2,13 +2,6 @@ REQUIRED_ARGS: TEST_OUTPUT: --- -fail_compilation/fail_scope.d(29): Deprecation: scope variable `da` may not be returned -fail_compilation/fail_scope.d(31): Deprecation: scope variable `o` may not be returned -fail_compilation/fail_scope.d(32): Deprecation: scope variable `dg` may not be returned -fail_compilation/fail_scope.d(34): Deprecation: scope variable `da` may not be returned -fail_compilation/fail_scope.d(36): Deprecation: scope variable `o` may not be returned -fail_compilation/fail_scope.d(37): Deprecation: scope variable `dg` may not be returned -fail_compilation/fail_scope.d(39): Deprecation: scope variable `p` may not be returned fail_compilation/fail_scope.d(44): Error: returning `cast(char[])string` escapes a reference to local variable `string` fail_compilation/fail_scope.d(62): Error: returning `s.bar()` escapes a reference to local variable `s` fail_compilation/fail_scope.d(73): Error: `fail_scope.foo8` called with argument types `(int)` matches both: @@ -22,19 +15,26 @@ fail_compilation/fail_scope.d(107): Deprecation: escaping reference to outer loc fail_compilation/fail_scope.d(126): Error: returning `s.bar()` escapes a reference to local variable `s` fail_compilation/fail_scope.d(136): Error: returning `foo16226(i)` escapes a reference to local variable `i` --- +//fail_compilation/fail_scope.d(30): Error: scope variable `da` may not be returned +//fail_compilation/fail_scope.d(32): Error: scope variable `o` may not be returned +//fail_compilation/fail_scope.d(33): Error: scope variable `dg` may not be returned +//fail_compilation/fail_scope.d(35): Error: scope variable `da` may not be returned +//fail_compilation/fail_scope.d(37): Error: scope variable `o` may not be returned +//fail_compilation/fail_scope.d(38): Error: scope variable `dg` may not be returned +//fail_compilation/fail_scope.d(40): Error: scope variable `p` may not be returned */ alias int delegate() dg_t; -int[] checkEscapeScope1(scope int[] da) @safe { return da; } -int[3] checkEscapeScope2(scope int[3] sa) @safe { return sa; } -Object checkEscapeScope3(scope Object o) @safe { return o; } -dg_t checkEscapeScope4(scope dg_t dg) @safe { return dg; } +int[] checkEscapeScope1(scope int[] da) { return da; } +int[3] checkEscapeScope2(scope int[3] sa) { return sa; } +Object checkEscapeScope3(scope Object o) { return o; } +dg_t checkEscapeScope4(scope dg_t dg) { return dg; } -int[] checkEscapeScope1() @safe { scope int[] da = []; return da; } -int[3] checkEscapeScope2() @safe { scope int[3] sa = [1,2,3]; return sa; } -Object checkEscapeScope3() @safe { scope Object o = new Object; return o; } // same with fail7294.d -dg_t checkEscapeScope4() @safe { scope dg_t dg = () => 1; return dg; } +int[] checkEscapeScope1() { scope int[] da = []; return da; } +int[3] checkEscapeScope2() { scope int[3] sa = [1,2,3]; return sa; } +Object checkEscapeScope3() { scope Object o = new Object; return o; } // same with fail7294.d +dg_t checkEscapeScope4() { scope dg_t dg = () => 1; return dg; } int* test(scope int* p) @safe { return p; } diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice23097.d b/gcc/testsuite/gdc.test/fail_compilation/ice23097.d new file mode 100644 index 00000000000..4fd1f61f828 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/ice23097.d @@ -0,0 +1,28 @@ +/* https://issues.dlang.org/show_bug.cgi?id=23097 +TEST_OUTPUT: +--- +fail_compilation/ice23097.d(12): Error: undefined identifier `ICE` +fail_compilation/ice23097.d(27): Error: template instance `ice23097.ice23097!(S23097)` error instantiating +fail_compilation/ice23097.d(27): Error: function `ice23097.ice23097!(S23097).ice23097(S23097 _param_0)` is not callable using argument types `(S23097)` +fail_compilation/ice23097.d(27): generating a copy constructor for `struct S23097` failed, therefore instances of it are uncopyable +--- +*/ +auto ice23097(I)(I) +{ + ICE; +} + +struct Cpctor23097 +{ + this(ref typeof(this)) { } +} + +struct S23097 +{ + Cpctor23097 cpctor; +} + +auto fail23097(S23097 s) +{ + s.ice23097; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test23109a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109a.d new file mode 100644 index 00000000000..5a11d9124c8 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109a.d @@ -0,0 +1,10 @@ +module imports.test23109a; +import imports.test23109c; +import imports.test23109b; +struct Array(T) +{ + T[] data; + enum SMALLARRAYCAP = 1; + T[SMALLARRAYCAP] smallarray; +} +alias Ensures = Array!Ensure; diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test23109b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109b.d new file mode 100644 index 00000000000..38680d3b986 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109b.d @@ -0,0 +1,10 @@ +module imports.test23109b; +import imports.test23109a; +import imports.test23109c; +struct Ensure +{ + Statement ensure; + Ensures* arraySyntaxCopy() + { + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test23109c.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109c.d new file mode 100644 index 00000000000..c6faf5c12da --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test23109c.d @@ -0,0 +1,3 @@ +module imports.test23109c; +import imports.test23109b; +class Statement {} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test9150.d b/gcc/testsuite/gdc.test/fail_compilation/test9150.d index e65afece6ff..5f66b360fec 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test9150.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test9150.d @@ -3,7 +3,7 @@ /* TEST_OUTPUT: --- -fail_compilation/test9150.d(14): Error: mismatched array lengths, 5 and 3 +fail_compilation/test9150.d(14): Error: mismatched array lengths 5 and 3 for assignment `row[] = __r2[__key3]` --- */ diff --git a/gcc/testsuite/gdc.test/runnable/test20734.d b/gcc/testsuite/gdc.test/runnable/test20734.d new file mode 100644 index 00000000000..264602bccc5 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test20734.d @@ -0,0 +1,28 @@ +/* +REQUIRED_ARGS: -betterC -preview=dip1000 +*/ + +__gshared int numDtor; + +struct S +{ + int a; + ~this() nothrow @nogc @trusted { ++numDtor; } +} + +void takeScopeSlice(const scope S[] slice) nothrow @nogc @safe {} + +extern(C) int main() nothrow @nogc @safe +{ + takeScopeSlice([ S(1), S(2) ]); // @nogc => no GC allocation + (() @trusted { assert(numDtor == 2); })(); // stack-allocated array literal properly destructed + return 0; +} + +// https://issues.dlang.org/show_bug.cgi?id=23098 +void f23098(scope inout(int)[] d) @safe {} + +void test23098() @safe +{ + f23098([10, 20]); +} diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index c51d237983d..ed9a02e1a0c 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -dba1bbe271a9b2d7f24edeebbc77846e29904e41 +604534d7cb29d49a6474f0aaaa5d166057a44f72 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. -- 2.34.1