diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-07-10 03:07:41 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-07-10 03:13:00 +0200 |
commit | 0cafc3b6272d1dd738e8d7e66e1d8741e08f74d3 (patch) | |
tree | 8c549ddd4b93c78f44959d47a4956837022a5cf1 | |
parent | d41a57c46df6f8f7dae0c0a8b349e734806a837b (diff) | |
download | gcc-0cafc3b6272d1dd738e8d7e66e1d8741e08f74d3.zip gcc-0cafc3b6272d1dd738e8d7e66e1d8741e08f74d3.tar.gz gcc-0cafc3b6272d1dd738e8d7e66e1d8741e08f74d3.tar.bz2 |
d: Merge upstream dmd, druntime 17ccd12af3, phobos 8d3800bee.
D front-end changes:
- Import dmd v2.104.0.
- Assignment-style syntax is now allowed for `alias this'.
- Overloading `extern(C)' functions is now an error.
D runtime changes:
- Import druntime v2.104.0.
Phobos changes:
- Import phobos v2.104.0.
- Better static assert messages when instantiating
`std.algorithm.iteration.permutations' with wrong inputs.
- Added `std.system.instructionSetArchitecture' and
`std.system.ISA'.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 17ccd12af3.
* dmd/VERSION: Bump version to v2.104.0.
* Make-lang.in (D_FRONTEND_OBJS): Rename d/apply.o to
d/postordervisitor.o.
* d-codegen.cc (make_location_t): Update for new front-end interface.
(build_filename_from_loc): Likewise.
(build_assert_call): Likewise.
(build_array_bounds_call): Likewise.
(build_bounds_index_condition): Likewise.
(build_bounds_slice_condition): Likewise.
(build_frame_type): Likewise.
(get_frameinfo): Likewise.
* d-diagnostic.cc (d_diagnostic_report_diagnostic): Likewise.
* decl.cc (build_decl_tree): Likewise.
(start_function): Likewise.
* expr.cc (ExprVisitor::visit (NewExp *)): Replace code generation of
`new pointer' with front-end lowering.
* runtime.def (NEWITEMT): Remove.
(NEWITEMIT): Remove.
* toir.cc (IRVisitor::visit (LabelStatement *)): Update for new
front-end interface.
* typeinfo.cc (check_typeinfo_type): Likewise.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 17ccd12af3.
* src/MERGE: Merge upstream phobos 8d3800bee.
gcc/testsuite/ChangeLog:
* gdc.dg/asm4.d: Update test.
147 files changed, 1822 insertions, 902 deletions
diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in index 4fbf209..264ae03 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -81,7 +81,6 @@ D_FRONTEND_OBJS = \ d/access.o \ d/aggregate.o \ d/aliasthis.o \ - d/apply.o \ d/arrayop.o \ d/arraytypes.o \ d/attrib.o \ @@ -160,6 +159,7 @@ D_FRONTEND_OBJS = \ d/parse.o \ d/parsetimevisitor.o \ d/permissivevisitor.o \ + d/postordervisitor.o \ d/printast.o \ d/root-aav.o \ d/root-array.o \ diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index 689d1c5..2738958 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -50,11 +50,11 @@ make_location_t (const Loc &loc) { location_t gcc_location = input_location; - if (loc.filename) + if (const char *filename = loc.filename ()) { - linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum); - linemap_line_start (line_table, loc.linnum, 0); - gcc_location = linemap_position_for_column (line_table, loc.charnum); + linemap_add (line_table, LC_ENTER, 0, filename, loc.linnum ()); + linemap_line_start (line_table, loc.linnum (), 0); + gcc_location = linemap_position_for_column (line_table, loc.charnum ()); linemap_add (line_table, LC_LEAVE, 0, NULL, 0); } @@ -1872,8 +1872,10 @@ void_okay_p (tree t) static tree build_filename_from_loc (const Loc &loc) { - const char *filename = loc.filename - ? loc.filename : d_function_chain->module->srcfile.toChars (); + const char *filename = loc.filename (); + + if (filename == NULL) + filename = d_function_chain->module->srcfile.toChars (); unsigned length = strlen (filename); tree str = build_string (length, filename); @@ -1890,17 +1892,17 @@ tree build_assert_call (const Loc &loc, libcall_fn libcall, tree msg) { tree file; - tree line = size_int (loc.linnum); + tree line = size_int (loc.linnum ()); switch (libcall) { case LIBCALL_ASSERT_MSG: case LIBCALL_UNITTEST_MSG: /* File location is passed as a D string. */ - if (loc.filename) + if (const char *filename = loc.filename ()) { - unsigned len = strlen (loc.filename); - tree str = build_string (len, loc.filename); + unsigned len = strlen (filename); + tree str = build_string (len, filename); TREE_TYPE (str) = make_array_type (Type::tchar, len); file = d_array_value (build_ctype (Type::tchar->arrayOf ()), @@ -1939,7 +1941,7 @@ build_array_bounds_call (const Loc &loc) { return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2, build_filename_from_loc (loc), - size_int (loc.linnum)); + size_int (loc.linnum ())); } } @@ -1968,7 +1970,8 @@ build_bounds_index_condition (IndexExp *ie, tree index, tree length) { boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4, build_filename_from_loc (ie->e2->loc), - size_int (ie->e2->loc.linnum), index, length); + size_int (ie->e2->loc.linnum ()), + index, length); } return build_condition (TREE_TYPE (index), condition, boundserr, index); @@ -2017,7 +2020,7 @@ build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length) boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP, Type::tvoid, 5, build_filename_from_loc (se->loc), - size_int (se->loc.linnum), + size_int (se->loc.linnum ()), lower, upper, length); } @@ -2659,8 +2662,8 @@ build_frame_type (tree ffi, FuncDeclaration *fd) of the calling function non-locally. So we add all parameters with nested refs to the function frame, this should also mean overriding methods will have the same frame layout when inheriting a contract. */ - if ((global.params.useIn == CHECKENABLEon && fd->frequire) - || (global.params.useOut == CHECKENABLEon && fd->fensure)) + if ((global.params.useIn == CHECKENABLEon && fd->frequire ()) + || (global.params.useOut == CHECKENABLEon && fd->fensure ())) { if (fd->parameters) { @@ -2870,8 +2873,8 @@ get_frameinfo (FuncDeclaration *fd) /* In checkNestedReference, references from contracts are not added to the closureVars array, so assume all parameters referenced. */ - if ((global.params.useIn == CHECKENABLEon && fd->frequire) - || (global.params.useOut == CHECKENABLEon && fd->fensure)) + if ((global.params.useIn == CHECKENABLEon && fd->frequire ()) + || (global.params.useOut == CHECKENABLEon && fd->fensure ())) FRAMEINFO_CREATES_FRAME (ffi) = 1; /* If however `fd` is nested (deeply) in a function that creates a diff --git a/gcc/d/d-diagnostic.cc b/gcc/d/d-diagnostic.cc index c3bde46..7e5b17c 100644 --- a/gcc/d/d-diagnostic.cc +++ b/gcc/d/d-diagnostic.cc @@ -189,7 +189,7 @@ d_diagnostic_report_diagnostic (const Loc &loc, int opt, const char *format, va_list argp; va_copy (argp, ap); - if (loc.filename || !verbatim) + if (loc.filename () || !verbatim) { rich_location rich_loc (line_table, make_location_t (loc)); diagnostic_info diagnostic; diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 0375ede..b866593 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -1083,7 +1083,7 @@ build_decl_tree (Dsymbol *d) location_t saved_location = input_location; /* Set input location, empty DECL_SOURCE_FILE can crash debug generator. */ - if (d->loc.filename) + if (d->loc.filename ()) input_location = make_location_t (d->loc); else input_location = make_location_t (Loc ("<no_file>", 1, 0)); @@ -2064,7 +2064,7 @@ start_function (FuncDeclaration *fd) allocate_struct_function (fndecl, false); /* Store the end of the function. */ - if (fd->endloc.filename) + if (fd->endloc.filename ()) cfun->function_end_locus = make_location_t (fd->endloc); else cfun->function_end_locus = DECL_SOURCE_LOCATION (fndecl); diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 95ea67d..1cff48a 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -28a3b24c2e45de39cd3df528142fd06b6456e8fd +17ccd12af386543c0b9935bf7e0a8e701b903105 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/README.md b/gcc/d/dmd/README.md index 57f56f3..79215b7 100644 --- a/gcc/d/dmd/README.md +++ b/gcc/d/dmd/README.md @@ -99,7 +99,7 @@ Note that these groups have no strict meaning, the category assignments are a bi | [strictvisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/strictvisitor.d) | Visitor that forces derived classes to implement `visit` for every possible node | | [visitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/visitor.d) | A visitor implementing `visit` for all nodes present in the compiler | | [transitivevisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/transitivevisitor.d) | Provide a mixin template with visit methods for the parse time AST | -| [apply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/apply.d) | Depth-first expression visitor | +| [postordervisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/postordervisitor.d) | Depth-first expression visitor | | [sapply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/sapply.d) | Depth-first statement visitor | | [statement_rewrite_walker.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/statement_rewrite_walker.d) | Statement visitor that allows replacing the currently visited node | diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 7cf9127..d5aee89 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.104.0-beta.1 +v2.104.0 diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d index 1306a10..42b926b 100644 --- a/gcc/d/dmd/aggregate.d +++ b/gcc/d/dmd/aggregate.d @@ -18,7 +18,6 @@ import core.stdc.stdio; import core.checkedint; import dmd.aliasthis; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.attrib; @@ -764,21 +763,18 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol if (s) { // Finish all constructors semantics to determine this.noDefaultCtor. - struct SearchCtor + static int searchCtor(Dsymbol s, void*) { - extern (C++) static int fp(Dsymbol s, void* ctxt) - { - auto f = s.isCtorDeclaration(); - if (f && f.semanticRun == PASS.initial) - f.dsymbolSemantic(null); - return 0; - } + auto f = s.isCtorDeclaration(); + if (f && f.semanticRun == PASS.initial) + f.dsymbolSemantic(null); + return 0; } for (size_t i = 0; i < members.length; i++) { auto sm = (*members)[i]; - sm.apply(&SearchCtor.fp, null); + sm.apply(&searchCtor, null); } } return s; @@ -814,3 +810,36 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol v.visit(this); } } + +/********************************* + * Iterate this dsymbol or members of this scoped dsymbol, then + * call `fp` with the found symbol and `params`. + * Params: + * symbol = the dsymbol or parent of members to call fp on + * fp = function pointer to process the iterated symbol. + * If it returns nonzero, the iteration will be aborted. + * ctx = context parameter passed to fp. + * Returns: + * nonzero if the iteration is aborted by the return value of fp, + * or 0 if it's completed. + */ +int apply(Dsymbol symbol, int function(Dsymbol, void*) fp, void* ctx) +{ + if (auto nd = symbol.isNspace()) + { + return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } ); + } + if (auto ad = symbol.isAttribDeclaration()) + { + return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, ctx); } ); + } + if (auto tm = symbol.isTemplateMixin()) + { + if (tm._scope) // if fwd reference + dsymbolSemantic(tm, null); // try to resolve it + + return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } ); + } + + return fp(symbol, ctx); +} diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d index 7dfec8a..09d39ca 100644 --- a/gcc/d/dmd/canthrow.d +++ b/gcc/d/dmd/canthrow.d @@ -14,7 +14,6 @@ module dmd.canthrow; import dmd.aggregate; -import dmd.apply; import dmd.arraytypes; import dmd.attrib; import dmd.astenums; @@ -26,6 +25,7 @@ import dmd.func; import dmd.globals; import dmd.init; import dmd.mtype; +import dmd.postordervisitor; import dmd.root.rootobject; import dmd.tokens; import dmd.visitor; @@ -133,16 +133,9 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN */ if (ce.f && ce.f == func) return; - Type t = ce.e1.type.toBasetype(); - auto tf = t.isTypeFunction(); + const tf = ce.calledFunctionType(); if (tf && tf.isnothrow) return; - else - { - auto td = t.isTypeDelegate(); - if (td && td.nextOf().isTypeFunction().isnothrow) - return; - } if (ce.f) checkFuncThrows(ce, ce.f); diff --git a/gcc/d/dmd/chkformat.d b/gcc/d/dmd/chkformat.d index 21a1b5e..feaa3c7 100644 --- a/gcc/d/dmd/chkformat.d +++ b/gcc/d/dmd/chkformat.d @@ -177,6 +177,8 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre errorMsg(null, e, (c_longsize == 4 ? "uint" : "ulong"), t); else errorMsg(null, e, (c_longsize == 4 ? "int" : "long"), t); + if (t.isintegral() && t.size() != c_longsize) + errorSupplemental(e.loc, "C `long` is %d bytes on your system", c_longsize); } break; diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index 60e373c..3586f20 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -106,18 +106,18 @@ FuncDeclaration hasIdentityOpAssign(AggregateDeclaration ad, Scope* sc) scope er = new NullExp(ad.loc, ad.type); // dummy rvalue scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue el.type = ad.type; - auto a = Expressions(1); + auto a = new Expressions(1); const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it. sc = sc.push(); sc.tinst = null; sc.minst = null; - a[0] = er; - auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet); + (*a)[0] = er; + auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet); if (!f) { - a[0] = el; - f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet); + (*a)[0] = el; + f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet); } sc = sc.pop(); @@ -465,7 +465,7 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc) */ scope er = new NullExp(ad.loc, null); // dummy rvalue scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue - auto a = Expressions(1); + auto a = new Expressions(1); bool hasIt(Type tthis) { @@ -476,9 +476,9 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc) FuncDeclaration rfc(Expression e) { - a[0] = e; - a[0].type = tthis; - return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(&a), FuncResolveFlag.quiet); + (*a)[0] = e; + (*a)[0].type = tthis; + return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(a), FuncResolveFlag.quiet); } f = rfc(er); diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d index c40936c..fcb50e0 100644 --- a/gcc/d/dmd/cond.d +++ b/gcc/d/dmd/cond.d @@ -259,7 +259,7 @@ extern (C++) final class StaticForeach : RootObject auto sdecl = new StructDeclaration(loc, sid, false); sdecl.storage_class |= STC.static_; sdecl.members = new Dsymbols(); - auto fid = Identifier.idPool(tupleFieldName.ptr, tupleFieldName.length); + auto fid = Identifier.idPool(tupleFieldName); auto ty = new TypeTypeof(loc, new TupleExp(loc, e)); sdecl.members.push(new VarDeclaration(loc, ty, fid, null, 0)); auto r = cast(TypeStruct)sdecl.type; diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index 9b7db1f..33669e3 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -324,6 +324,8 @@ final class CParser(AST) : Parser!AST // atomic-type-specifier or type_qualifier case TOK._Atomic: + case TOK.__attribute__: + Ldeclaration: { cparseDeclaration(LVL.local); @@ -2356,6 +2358,8 @@ final class CParser(AST) : Parser!AST cparseGnuAttributes(tagSpecifier); else if (token.value == TOK.__declspec) cparseDeclspec(tagSpecifier); + else if (token.value == TOK.__pragma) + uupragmaDirective(sloc); else break; } @@ -2710,7 +2714,7 @@ final class CParser(AST) : Parser!AST * * Params: * declarator = declarator kind - * t = base type to start with + * tbase = base type to start with * pident = set to Identifier if there is one, null if not * specifier = specifiers in and out * Returns: @@ -2718,12 +2722,26 @@ final class CParser(AST) : Parser!AST * symbol table for the parameter-type-list, which will contain any * declared struct, union or enum tags. */ - private AST.Type cparseDeclarator(DTR declarator, AST.Type t, + private AST.Type cparseDeclarator(DTR declarator, AST.Type tbase, out Identifier pident, ref Specifier specifier) { //printf("cparseDeclarator(%d, %p)\n", declarator, t); AST.Types constTypes; // all the Types that will need `const` applied to them + /* Insert tx -> t into + * ts -> ... -> t + * so that + * ts -> ... -> tx -> t + */ + static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t) + { + AST.Type* pt; + for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next) + { + } + *pt = tx; + } + AST.Type parseDecl(AST.Type t) { AST.Type ts; @@ -2789,20 +2807,6 @@ final class CParser(AST) : Parser!AST // parse DeclaratorSuffixes while (1) { - /* Insert tx -> t into - * ts -> ... -> t - * so that - * ts -> ... -> tx -> t - */ - static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t) - { - AST.Type* pt; - for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next) - { - } - *pt = tx; - } - switch (token.value) { case TOK.leftBracket: @@ -2915,7 +2919,17 @@ final class CParser(AST) : Parser!AST return ts; } - t = parseDecl(t); + auto t = parseDecl(tbase); + + if (specifier.vector_size) + { + auto length = new AST.IntegerExp(token.loc, specifier.vector_size / tbase.size(), AST.Type.tuns32); + auto tsa = new AST.TypeSArray(tbase, length); + AST.Type tv = new AST.TypeVector(tsa); + specifier.vector_size = 0; // used it up + + insertTx(t, tv, tbase); // replace tbase with tv + } /* Because const is transitive, cannot assemble types from * fragments. Instead, types to be annotated with const are put @@ -3553,7 +3567,19 @@ final class CParser(AST) : Parser!AST { nextToken(); check(TOK.leftParenthesis); - cparseConstantExp(); // TODO implement + if (token.value == TOK.int32Literal) + { + const n = token.unsvalue; + if (n < 1 || n & (n - 1) || ushort.max < n) + error("__attribute__((vector_size(%lld))) must be an integer positive power of 2 and be <= 32,768", cast(ulong)n); + specifier.vector_size = cast(uint) n; + nextToken(); + } + else + { + error("value for vector_size expected, not `%s`", token.toChars()); + nextToken(); + } check(TOK.rightParenthesis); } else @@ -3852,6 +3878,10 @@ final class CParser(AST) : Parser!AST else if (!tag) error("missing tag `identifier` after `%s`", Token.toChars(structOrUnion)); + // many ways and places to declare alignment + if (packalign.isUnknown() && !this.packalign.isUnknown()) + packalign.set(this.packalign.get()); + /* Need semantic information to determine if this is a declaration, * redeclaration, or reference to existing declaration. * Defer to the semantic() pass with a TypeTag. @@ -4694,6 +4724,7 @@ final class CParser(AST) : Parser!AST // atomic-type-specifier case TOK._Atomic: case TOK.typeof_: + case TOK.__attribute__: t = peek(t); if (t.value != TOK.leftParenthesis || !skipParens(t, &t)) @@ -4959,6 +4990,7 @@ final class CParser(AST) : Parser!AST bool dllexport; /// dllexport attribute bool _deprecated; /// deprecated attribute AST.Expression depMsg; /// deprecated message + uint vector_size; /// positive power of 2 multipe of base type size SCW scw; /// storage-class specifiers MOD mod; /// type qualifiers @@ -5400,6 +5432,24 @@ final class CParser(AST) : Parser!AST pragmaDirective(scanloc); return true; } + else if (n.ident == Id.ident) // #ident "string" + { + scan(&n); + if (n.value == TOK.string_ && n.ptr[0] == '"' && n.postfix == 0) + { + /* gcc inserts string into the .comment section in the object file. + * Just ignore it for now, but can support it later by writing + * the string to obj_exestr() + */ + //auto comment = n.ustring; + + scan(&n); + if (n.value == TOK.endOfFile || n.value == TOK.endOfLine) + return true; + } + error("\"string\" expected after `#ident`"); + return false; + } } if (n.ident != Id.undef) error("C preprocessor directive `#%s` is not supported", n.toChars()); @@ -5416,20 +5466,39 @@ final class CParser(AST) : Parser!AST private void uupragmaDirective(const ref Loc startloc) { const loc = startloc; - nextToken(); + nextToken(); // move past __pragma if (token.value != TOK.leftParenthesis) { - error(loc, "left parenthesis expected to follow `__pragma`"); + error(loc, "left parenthesis expected to follow `__pragma` instead of `%s`", token.toChars()); + nextToken(); return; } nextToken(); - if (token.value == TOK.identifier && token.ident == Id.pack) - pragmaPack(startloc, false); + + if (token.value == TOK.identifier) + { + if (token.ident == Id.pack) + pragmaPack(startloc, false); + else + { + nextToken(); + if (token.value == TOK.leftParenthesis) + cparseParens(); + } + + } + else if (token.value == TOK.endOfFile) + { + } + else if (token.value == TOK.rightParenthesis) + { + } else - error(loc, "unrecognized __pragma"); + error(loc, "unrecognized `__pragma(%s)`", token.toChars()); + if (token.value != TOK.rightParenthesis) { - error(loc, "right parenthesis expected to close `__pragma(...)`"); + error(loc, "right parenthesis expected to close `__pragma(...)` instead of `%s`", token.toChars()); return; } nextToken(); diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d index 40092c3..ee1340d 100644 --- a/gcc/d/dmd/cppmangle.d +++ b/gcc/d/dmd/cppmangle.d @@ -446,7 +446,15 @@ private final class CppMangleVisitor : Visitor if (this.context.res.dyncast() == DYNCAST.dsymbol) parentti = this.context.res.asFuncDecl().parent.isTemplateInstance(); else - parentti = this.context.res.asType().toDsymbol(null).parent.isTemplateInstance(); + { + auto parent = this.context.res.asType().toDsymbol(null).parent; + parentti = parent.isTemplateInstance(); + // https://issues.dlang.org/show_bug.cgi?id=22760 + // The template instance may sometimes have the form + // S1!int.S1, therefore the above instruction might yield null + if (parentti is null && parent.parent) + parentti = parent.parent.isTemplateInstance(); + } return (*parentti.tiargs)[arg]; }()); scope (exit) this.context.pop(prev); diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 8ffbef3c..6fcc280 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -71,6 +71,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t) if (const match = (sc && sc.flags & SCOPE.Cfile) ? e.cimplicitConvTo(t) : e.implicitConvTo(t)) { + // no need for an extra cast when matching is exact + if (match == MATCH.convert && e.type.isTypeNoreturn()) { return specialNoreturnCast(e, t); @@ -88,6 +90,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t) auto ad = isAggregate(e.type); if (ad && ad.aliasthis) { + if (!ad.type || ad.type.isTypeError()) + return e; auto ts = ad.type.isTypeStruct(); const adMatch = ts ? ts.implicitConvToWithoutAliasThis(t) diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d index e458593..1b8e8ef 100644 --- a/gcc/d/dmd/dclass.d +++ b/gcc/d/dmd/dclass.d @@ -17,7 +17,6 @@ import core.stdc.stdio; import core.stdc.string; import dmd.aggregate; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.attrib; @@ -867,7 +866,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration * Resolve forward references to all class member functions, * and determine whether this class is abstract. */ - static int func(Dsymbol s) + static int func(Dsymbol s, void*) { auto fd = s.isFuncDeclaration(); if (!fd) @@ -883,7 +882,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration for (size_t i = 0; i < members.length; i++) { auto s = (*members)[i]; - if (s.apply(&func)) + if (s.apply(&func, null)) { return yes(); } @@ -910,7 +909,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration * each of the virtual functions, * which will fill in the vtbl[] overrides. */ - static int virtualSemantic(Dsymbol s) + static int virtualSemantic(Dsymbol s, void*) { auto fd = s.isFuncDeclaration(); if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration()) @@ -921,7 +920,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration for (size_t i = 0; i < members.length; i++) { auto s = (*members)[i]; - s.apply(&virtualSemantic); + s.apply(&virtualSemantic,null); } } diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index 0e5df5e..cfa6988 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -44,6 +44,10 @@ import dmd.tokens; import dmd.typesem; import dmd.visitor; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + /************************************ * Check to see the aggregate type is nested and its context pointer is * accessible from the current scope. @@ -633,9 +637,7 @@ extern (C++) final class TupleDeclaration : Declaration version (none) { buf.printf("_%s_%d", ident.toChars(), i); - const len = buf.offset; - const name = buf.extractSlice().ptr; - auto id = Identifier.idPool(name, len); + auto id = Identifier.idPool(buf.extractSlice()); auto arg = new Parameter(STC.in_, t, id, null); } else diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index 7a69382..197091e 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -534,22 +534,19 @@ enum class BUILTIN : unsigned char Expression *eval_builtin(const Loc &loc, FuncDeclaration *fd, Expressions *arguments); BUILTIN isBuiltin(FuncDeclaration *fd); +struct ContractInfo; + class FuncDeclaration : public Declaration { public: - Statements *frequires; // in contracts - Ensures *fensures; // out contracts - Statement *frequire; // lowered in contract - Statement *fensure; // lowered out contract Statement *fbody; FuncDeclarations foverrides; // functions this function overrides - FuncDeclaration *fdrequire; // function that does the in contract - FuncDeclaration *fdensure; // function that does the out contract - Expressions *fdrequireParams; // argument list for __require - Expressions *fdensureParams; // argument list for __ensure +private: + ContractInfo *contracts; // contract information +public: const char *mangleString; // mangled symbol created from mangleExact() VarDeclaration *vresult; // result variable for out contracts @@ -686,6 +683,22 @@ public: static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type, bool noreturn = false); FuncDeclaration *syntaxCopy(Dsymbol *) override; + Statements *frequires(); + Ensures *fensures(); + Statement *frequire(); + Statement *fensure(); + FuncDeclaration *fdrequire(); + FuncDeclaration *fdensure(); + Expressions *fdrequireParams(); + Expressions *fdensureParams(); + Statements *frequires(Statements *frs); + Ensures *fensures(Statements *fes); + Statement *frequire(Statement *fr); + Statement *fensure(Statement *fe); + FuncDeclaration *fdrequire(FuncDeclaration *fdr); + FuncDeclaration *fdensure(FuncDeclaration *fde); + Expressions *fdrequireParams(Expressions *fdrp); + Expressions *fdensureParams(Expressions *fdep); bool functionSemantic(); bool functionSemantic3(); bool equals(const RootObject * const o) const override final; diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d index fd95691..b135bfa 100644 --- a/gcc/d/dmd/delegatize.d +++ b/gcc/d/dmd/delegatize.d @@ -14,7 +14,6 @@ module dmd.delegatize; import core.stdc.stdio; -import dmd.apply; import dmd.astenums; import dmd.declaration; import dmd.dscope; @@ -27,6 +26,7 @@ import dmd.init; import dmd.initsem; import dmd.location; import dmd.mtype; +import dmd.postordervisitor; import dmd.statement; import dmd.tokens; import dmd.visitor; diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d index 221250b..87b40b8 100644 --- a/gcc/d/dmd/denum.d +++ b/gcc/d/dmd/denum.d @@ -169,7 +169,12 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol return defaultval; } //printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars()); - if (defaultval) + // https://issues.dlang.org/show_bug.cgi?id=23904 + // Return defaultval only if it is not ErrorExp. + // A speculative context may set defaultval to ErrorExp; + // subsequent non-speculative contexts need to be able + // to print the error. + if (defaultval && !defaultval.isErrorExp()) return defaultval; if (isCsymbol()) diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d index b653d9b..c4d5ddb 100644 --- a/gcc/d/dmd/dimport.d +++ b/gcc/d/dmd/dimport.d @@ -26,6 +26,7 @@ import dmd.location; import dmd.mtype; import dmd.visitor; +import core.stdc.stdio; /*********************************************************** */ extern (C++) final class Import : Dsymbol @@ -232,7 +233,20 @@ extern (C++) final class Import : Dsymbol * most likely because of parsing errors. * Therefore we cannot trust the resulting AST. */ - if (load(sc)) return; + if (load(sc)) + { + // https://issues.dlang.org/show_bug.cgi?id=23873 + // For imports that are not at module or function level, + // e.g. aggregate level, the import symbol is added to the + // symbol table and later semantic is performed on it. + // This leads to semantic analysis on an malformed AST + // which causes all kinds of segfaults. + // The fix is to note that the module has errors and avoid + // semantic analysis on it. + if(mod) + mod.errors = true; + return; + } if (!mod) return; // Failed diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index 4ef6a39..5b27a07 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -16,7 +16,6 @@ module dmd.dinterpret; import core.stdc.stdio; import core.stdc.stdlib; import core.stdc.string; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.attrib; diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d index 7674f77..3e60dc4 100644 --- a/gcc/d/dmd/doc.d +++ b/gcc/d/dmd/doc.d @@ -429,9 +429,9 @@ extern(C++) void gendocfile(Module m) if (m.filetype == FileType.ddoc) { const ploc = m.md ? &m.md.loc : &m.loc; - const loc = Loc(ploc.filename ? ploc.filename : srcfilename.ptr, - ploc.linnum, - ploc.charnum); + Loc loc = *ploc; + if (!loc.filename) + loc.filename = srcfilename.ptr; size_t commentlen = strlen(cast(char*)m.comment); Dsymbols a; @@ -4151,7 +4151,7 @@ private size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, con private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset) { const incrementLoc = loc.linnum == 0 ? 1 : 0; - loc.linnum += incrementLoc; + loc.linnum = loc.linnum + incrementLoc; loc.charnum = 0; //printf("highlightText()\n"); bool leadingBlank = true; @@ -4256,7 +4256,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s lineQuoted = false; tableRowDetected = false; iLineStart = i + 1; - loc.linnum += incrementLoc; + loc.linnum = loc.linnum + incrementLoc; // update the paragraph start if we just entered a macro if (previousMacroLevel < macroLevel && iParagraphStart < iLineStart) diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 506946f..a5cd63b 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -17,7 +17,6 @@ import core.stdc.string; import dmd.aggregate; import dmd.aliasthis; -import dmd.apply; import dmd.arraytypes; import dmd.astcodegen; import dmd.astenums; @@ -78,6 +77,10 @@ import dmd.templateparamsem; import dmd.typesem; import dmd.visitor; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + enum LOG = false; private uint setMangleOverride(Dsymbol s, const(char)[] sym) @@ -484,7 +487,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // Infering the type requires running semantic, // so mark the scope as ctfe if required - bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0; + bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0 || !sc.func; if (needctfe) { sc.flags |= SCOPE.condition; @@ -1366,9 +1369,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { static if (LOG) { - printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars()); + printf("Import::semantic('%s') %s\n", imp.toPrettyChars(), imp.id.toChars()); scope(exit) - printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg); + printf("-Import::semantic('%s'), pkg = %p\n", imp.toChars(), imp.pkg); } if (imp.semanticRun > PASS.initial) return; @@ -1434,7 +1437,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor imp.addPackageAccess(scopesym); } - imp.mod.dsymbolSemantic(null); + // if a module has errors it means that parsing has failed. + if (!imp.mod.errors) + imp.mod.dsymbolSemantic(null); if (imp.mod.needmoduleinfo) { @@ -1463,7 +1468,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else { Dsymbol s = imp.mod.search_correct(imp.names[i]); - if (s) + // https://issues.dlang.org/show_bug.cgi?id=23908 + // Don't suggest symbols from the importer's module + if (s && s.parent != importer) imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars()); else imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars()); @@ -7124,8 +7131,9 @@ bool determineFields(AggregateDeclaration ad) // determineFields can be called recursively from one of the fields's v.semantic ad.fields.setDim(0); - static int func(Dsymbol s, AggregateDeclaration ad) + static int func(Dsymbol s, void* ctx) { + auto ad = cast(AggregateDeclaration)ctx; auto v = s.isVarDeclaration(); if (!v) return 0; @@ -7141,7 +7149,7 @@ bool determineFields(AggregateDeclaration ad) if (v.aliasTuple) { // If this variable was really a tuple, process each element. - return v.aliasTuple.foreachVar(tv => tv.apply(&func, ad)); + return v.aliasTuple.foreachVar(tv => tv.apply(&func, cast(void*) ad)); } if (v.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.ctfe | STC.templateparameter)) @@ -7173,7 +7181,7 @@ bool determineFields(AggregateDeclaration ad) for (size_t i = 0; i < ad.members.length; i++) { auto s = (*ad.members)[i]; - if (s.apply(&func, ad)) + if (s.apply(&func, cast(void *)ad)) { if (ad.sizeok != Sizeok.none) { diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index ef743d6..5b98d2f 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -4141,185 +4141,207 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param goto Lnomatch; L2: - for (size_t i = 0; 1; i++) + if (!resolveTemplateInstantiation(t.tempinst.tiargs, &t.tempinst.tdtypes, tempdecl, tp, dedtypes)) + goto Lnomatch; + } + visit(cast(Type)t); + return; + + Lnomatch: + //printf("no match\n"); + result = MATCH.nomatch; + } + + /******************** + * Match template `parameters` to the target template instance. + * Example: + * struct Temp(U, int Z) {} + * void foo(T)(Temp!(T, 3)); + * foo(Temp!(int, 3)()); + * Input: + * this.parameters = template params of foo -> [T] + * tiargs = <Temp!(int, 3)>.tiargs -> [int, 3] + * tdtypes = <Temp!(int, 3)>.tdtypes -> [int, 3] + * tempdecl = <struct Temp!(T, int Z)> -> [T, Z] + * tp = <Temp!(T, 3)> + * Output: + * dedtypes = deduced params of `foo(Temp!(int, 3)())` -> [int] + */ + private bool resolveTemplateInstantiation(Objects* tiargs, Objects* tdtypes, TemplateDeclaration tempdecl, TypeInstance tp, Objects* dedtypes) + { + for (size_t i = 0; 1; i++) + { + //printf("\ttest: tempinst.tiargs[%zu]\n", i); + RootObject o1 = null; + if (i < tiargs.length) + o1 = (*tiargs)[i]; + else if (i < tdtypes.length && i < tp.tempinst.tiargs.length) { - //printf("\ttest: tempinst.tiargs[%zu]\n", i); - RootObject o1 = null; - if (i < t.tempinst.tiargs.length) - o1 = (*t.tempinst.tiargs)[i]; - else if (i < t.tempinst.tdtypes.length && i < tp.tempinst.tiargs.length) - { - // Pick up default arg - o1 = t.tempinst.tdtypes[i]; - } - else if (i >= tp.tempinst.tiargs.length) - break; - //printf("\ttest: o1 = %s\n", o1.toChars()); - if (i >= tp.tempinst.tiargs.length) + // Pick up default arg + o1 = (*tdtypes)[i]; + } + else if (i >= tp.tempinst.tiargs.length) + break; + //printf("\ttest: o1 = %s\n", o1.toChars()); + if (i >= tp.tempinst.tiargs.length) + { + size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0); + while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg())) { - size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0); - while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg())) - { - i++; - } - if (i >= dim) - break; // match if all remained parameters are dependent - goto Lnomatch; + i++; } + if (i >= dim) + break; // match if all remained parameters are dependent + return false; + } - RootObject o2 = (*tp.tempinst.tiargs)[i]; - Type t2 = isType(o2); - //printf("\ttest: o2 = %s\n", o2.toChars()); - size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1) - ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND; - if (j != IDX_NOTFOUND && j == parameters.length - 1 && - (*parameters)[j].isTemplateTupleParameter()) - { - /* Given: + RootObject o2 = (*tp.tempinst.tiargs)[i]; + Type t2 = isType(o2); + //printf("\ttest: o2 = %s\n", o2.toChars()); + size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1) + ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND; + if (j != IDX_NOTFOUND && j == parameters.length - 1 && + (*parameters)[j].isTemplateTupleParameter()) + { + /* Given: * struct A(B...) {} * alias A!(int, float) X; * static if (is(X Y == A!(Z), Z...)) {} * deduce that Z is a tuple(int, float) */ - /* Create tuple from remaining args + /* Create tuple from remaining args */ - size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.length : t.tempinst.tdtypes.length) - i; - auto vt = new Tuple(vtdim); - for (size_t k = 0; k < vtdim; k++) - { - RootObject o; - if (k < t.tempinst.tiargs.length) - o = (*t.tempinst.tiargs)[i + k]; - else // Pick up default arg - o = t.tempinst.tdtypes[i + k]; - vt.objects[k] = o; - } - - Tuple v = cast(Tuple)(*dedtypes)[j]; - if (v) - { - if (!match(v, vt)) - goto Lnomatch; - } - else - (*dedtypes)[j] = vt; - break; - } - else if (!o1) - break; - - Type t1 = isType(o1); - Dsymbol s1 = isDsymbol(o1); - Dsymbol s2 = isDsymbol(o2); - Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1)); - Expression e2 = isExpression(o2); - version (none) + size_t vtdim = (tempdecl.isVariadic() ? tiargs.length : tdtypes.length) - i; + auto vt = new Tuple(vtdim); + for (size_t k = 0; k < vtdim; k++) { - Tuple v1 = isTuple(o1); - Tuple v2 = isTuple(o2); - if (t1) - printf("t1 = %s\n", t1.toChars()); - if (t2) - printf("t2 = %s\n", t2.toChars()); - if (e1) - printf("e1 = %s\n", e1.toChars()); - if (e2) - printf("e2 = %s\n", e2.toChars()); - if (s1) - printf("s1 = %s\n", s1.toChars()); - if (s2) - printf("s2 = %s\n", s2.toChars()); - if (v1) - printf("v1 = %s\n", v1.toChars()); - if (v2) - printf("v2 = %s\n", v2.toChars()); + RootObject o; + if (k < tiargs.length) + o = (*tiargs)[i + k]; + else // Pick up default arg + o = (*tdtypes)[i + k]; + vt.objects[k] = o; } - if (t1 && t2) + Tuple v = cast(Tuple)(*dedtypes)[j]; + if (v) { - if (!deduceType(t1, sc, t2, parameters, dedtypes)) - goto Lnomatch; + if (!match(v, vt)) + return false; } - else if (e1 && e2) - { - Le: - e1 = e1.ctfeInterpret(); + else + (*dedtypes)[j] = vt; + break; + } + else if (!o1) + break; - /* If it is one of the template parameters for this template, + Type t1 = isType(o1); + Dsymbol s1 = isDsymbol(o1); + Dsymbol s2 = isDsymbol(o2); + Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1)); + Expression e2 = isExpression(o2); + version (none) + { + Tuple v1 = isTuple(o1); + Tuple v2 = isTuple(o2); + if (t1) + printf("t1 = %s\n", t1.toChars()); + if (t2) + printf("t2 = %s\n", t2.toChars()); + if (e1) + printf("e1 = %s\n", e1.toChars()); + if (e2) + printf("e2 = %s\n", e2.toChars()); + if (s1) + printf("s1 = %s\n", s1.toChars()); + if (s2) + printf("s2 = %s\n", s2.toChars()); + if (v1) + printf("v1 = %s\n", v1.toChars()); + if (v2) + printf("v2 = %s\n", v2.toChars()); + } + + if (t1 && t2) + { + if (!deduceType(t1, sc, t2, parameters, dedtypes)) + return false; + } + else if (e1 && e2) + { + Le: + e1 = e1.ctfeInterpret(); + + /* If it is one of the template parameters for this template, * we should not attempt to interpret it. It already has a value. */ - if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter)) - { - /* + if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter)) + { + /* * (T:Number!(e2), int e2) */ - j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters); - if (j != IDX_NOTFOUND) - goto L1; - // The template parameter was not from this template - // (it may be from a parent template, for example) - } - - e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417 - e2 = e2.ctfeInterpret(); + j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters); + if (j != IDX_NOTFOUND) + goto L1; + // The template parameter was not from this template + // (it may be from a parent template, for example) + } - //printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty); - //printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty); - if (!e1.equals(e2)) - { - if (!e2.implicitConvTo(e1.type)) - goto Lnomatch; + e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417 + e2 = e2.ctfeInterpret(); - e2 = e2.implicitCastTo(sc, e1.type); - e2 = e2.ctfeInterpret(); - if (!e1.equals(e2)) - goto Lnomatch; - } - } - else if (e1 && t2 && t2.ty == Tident) + //printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty); + //printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty); + if (!e1.equals(e2)) { - j = templateParameterLookup(t2, parameters); - L1: - if (j == IDX_NOTFOUND) - { - t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2); - if (e2) - goto Le; - goto Lnomatch; - } - if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null)) - goto Lnomatch; + if (!e2.implicitConvTo(e1.type)) + return false; + + e2 = e2.implicitCastTo(sc, e1.type); + e2 = e2.ctfeInterpret(); + if (!e1.equals(e2)) + return false; } - else if (s1 && s2) + } + else if (e1 && t2 && t2.ty == Tident) + { + j = templateParameterLookup(t2, parameters); + L1: + if (j == IDX_NOTFOUND) { - Ls: - if (!s1.equals(s2)) - goto Lnomatch; + t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2); + if (e2) + goto Le; + return false; } - else if (s1 && t2 && t2.ty == Tident) + if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null)) + return false; + } + else if (s1 && s2) + { + Ls: + if (!s1.equals(s2)) + return false; + } + else if (s1 && t2 && t2.ty == Tident) + { + j = templateParameterLookup(t2, parameters); + if (j == IDX_NOTFOUND) { - j = templateParameterLookup(t2, parameters); - if (j == IDX_NOTFOUND) - { - t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2); - if (s2) - goto Ls; - goto Lnomatch; - } - if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null)) - goto Lnomatch; + t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2); + if (s2) + goto Ls; + return false; } - else - goto Lnomatch; + if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null)) + return false; } + else + return false; } - visit(cast(Type)t); - return; - - Lnomatch: - //printf("no match\n"); - result = MATCH.nomatch; + return true; } override void visit(TypeStruct t) diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index 4f1edaa..c0dd17f 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -377,13 +377,18 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId, desc ~ " `%s` assigned to non-scope parameter calling `assert()`", v); return; } + + bool isThis = fdc && fdc.needThis() && fdc.vthis == vPar; // implicit `this` parameter to member function + const(char)* msg = + (isThis) ? (desc ~ " `%s` calling non-scope member function `%s.%s()`") : (fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`") : (fdc && !parId) ? (desc ~ " `%s` assigned to non-scope anonymous parameter calling `%s`") : (!fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s`") : (desc ~ " `%s` assigned to non-scope anonymous parameter"); - if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, parId ? parId : fdc, fdc)) + auto param = isThis ? v : (parId ? parId : fdc); + if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, param, fdc)) { result = true; printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10); @@ -1746,20 +1751,8 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re /* Check each argument that is * passed as 'return scope'. */ - Type t1 = e.e1.type.toBasetype(); - TypeFunction tf; - TypeDelegate dg; - if (t1.ty == Tdelegate) - { - dg = t1.isTypeDelegate(); - tf = dg.next.isTypeFunction(); - } - else if (t1.ty == Tfunction) - tf = t1.isTypeFunction(); - else - return; - - if (!e.type.hasPointers()) + TypeFunction tf = e.calledFunctionType(); + if (!tf || !e.type.hasPointers()) return; if (e.arguments && e.arguments.length) @@ -1815,6 +1808,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re } } // If 'this' is returned, check it too + Type t1 = e.e1.type.toBasetype(); if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction) { DotVarExp dve = e.e1.isDotVarExp(); @@ -1880,7 +1874,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re /* If returning the result of a delegate call, the .ptr * field of the delegate must be checked. */ - if (dg) + if (t1.isTypeDelegate()) { if (tf.isreturn) escapeByValue(e.e1, er, live, retRefTransition); @@ -2066,13 +2060,8 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR /* If the function returns by ref, check each argument that is * passed as 'return ref'. */ - Type t1 = e.e1.type.toBasetype(); - TypeFunction tf; - if (t1.ty == Tdelegate) - tf = t1.isTypeDelegate().next.isTypeFunction(); - else if (t1.ty == Tfunction) - tf = t1.isTypeFunction(); - else + TypeFunction tf = e.calledFunctionType(); + if (!tf) return; if (tf.isref) { @@ -2107,6 +2096,7 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR } } // If 'this' is returned by ref, check it too + Type t1 = e.e1.type.toBasetype(); if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction) { DotVarExp dve = e.e1.isDotVarExp(); diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 067d22f..473efb8 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -19,7 +19,6 @@ import core.stdc.string; import dmd.aggregate; import dmd.aliasthis; -import dmd.apply; import dmd.arrayop; import dmd.arraytypes; import dmd.astenums; @@ -56,6 +55,7 @@ import dmd.nspace; import dmd.objc; import dmd.opover; import dmd.optimize; +import dmd.postordervisitor; import dmd.root.complex; import dmd.root.ctfloat; import dmd.root.filename; @@ -699,6 +699,20 @@ VarDeclaration expToVariable(Expression e) case EXP.super_: return (cast(ThisExp)e).var.isVarDeclaration(); + // Temporaries for rvalues that need destruction + // are of form: (T s = rvalue, s). For these cases + // we can just return var declaration of `s`. However, + // this is intentionally not calling `Expression.extractLast` + // because at this point we cannot infer the var declaration + // of more complex generated comma expressions such as the + // one for the array append hook. + case EXP.comma: + { + if (auto ve = e.isCommaExp().e2.isVarExp()) + return ve.var.isVarDeclaration(); + + return null; + } default: return null; } @@ -723,7 +737,6 @@ extern (C++) abstract class Expression : ASTNode Type type; // !=null means that semantic() has been run Loc loc; // file location const EXP op; // to minimize use of dynamic_cast - bool parens; // if this is a parenthesized expression extern (D) this(const ref Loc loc, EXP op) scope { @@ -1530,6 +1543,11 @@ extern (C++) abstract class Expression : ASTNode return false; if (sc.flags & (SCOPE.ctfe | SCOPE.debug_)) return false; + /* The original expression (`new S(...)`) will be verified instead. This + * is to keep errors related to the original code and not the lowering. + */ + if (f.ident == Id._d_newitemT) + return false; if (!f.isNogc()) { @@ -2338,6 +2356,7 @@ extern (C++) final class ComplexExp : Expression extern (C++) class IdentifierExp : Expression { Identifier ident; + bool parens; // if it appears as (identifier) extern (D) this(const ref Loc loc, Identifier ident) scope { @@ -3520,6 +3539,8 @@ extern (C++) final class CompoundLiteralExp : Expression */ extern (C++) final class TypeExp : Expression { + bool parens; // if this is a parenthesized expression + extern (D) this(const ref Loc loc, Type type) { super(loc, EXP.type); @@ -3672,7 +3693,7 @@ extern (C++) final class NewExp : Expression bool onstack; // allocate on stack bool thrownew; // this NewExp is the expression of a ThrowStatement - Expression lowering; // lowered druntime hook: `_d_newclass` + Expression lowering; // lowered druntime hook: `_d_new{class,itemT}` /// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around. /// The fields are still separate for backwards compatibility @@ -5188,6 +5209,7 @@ extern (C++) final class CallExp : UnaExp bool directcall; // true if a virtual call is devirtualized bool inDebugStatement; /// true if this was in a debug statement bool ignoreAttributes; /// don't enforce attributes (e.g. call @gc function in @nogc code) + bool isUfcsRewrite; /// the first argument was pushed in here by a UFCS rewrite VarDeclaration vthis2; // container for multi-context /// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around. @@ -5329,6 +5351,26 @@ extern (C++) final class CallExp : UnaExp } } +/** + * Get the called function type from a call expression + * Params: + * ce = function call expression. Must have had semantic analysis done. + * Returns: called function type, or `null` if error / no semantic analysis done + */ +TypeFunction calledFunctionType(CallExp ce) +{ + Type t = ce.e1.type; + if (!t) + return null; + t = t.toBasetype(); + if (auto tf = t.isTypeFunction()) + return tf; + else if (auto td = t.isTypeDelegate()) + return td.nextOf().isTypeFunction(); + else + return null; +} + FuncDeclaration isFuncAddress(Expression e, bool* hasOverloads = null) { if (auto ae = e.isAddrExp()) @@ -7058,9 +7100,7 @@ extern (C++) final class FileInitExp : DefaultInitExp s = loc.isValid() ? loc.filename : sc._module.ident.toChars(); Expression e = new StringExp(loc, s.toDString()); - e = e.expressionSemantic(sc); - e = e.castTo(sc, type); - return e; + return e.expressionSemantic(sc); } override void accept(Visitor v) @@ -7082,8 +7122,7 @@ extern (C++) final class LineInitExp : DefaultInitExp override Expression resolveLoc(const ref Loc loc, Scope* sc) { Expression e = new IntegerExp(loc, loc.linnum, Type.tint32); - e = e.castTo(sc, type); - return e; + return e.expressionSemantic(sc); } override void accept(Visitor v) @@ -7106,9 +7145,7 @@ extern (C++) final class ModuleInitExp : DefaultInitExp { const auto s = (sc.callsc ? sc.callsc : sc)._module.toPrettyChars().toDString(); Expression e = new StringExp(loc, s); - e = e.expressionSemantic(sc); - e = e.castTo(sc, type); - return e; + return e.expressionSemantic(sc); } override void accept(Visitor v) @@ -7137,9 +7174,7 @@ extern (C++) final class FuncInitExp : DefaultInitExp else s = ""; Expression e = new StringExp(loc, s.toDString()); - e = e.expressionSemantic(sc); - e.type = Type.tstring; - return e; + return e.expressionSemantic(sc); } override void accept(Visitor v) diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index a4b18b9..770c3e7 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -83,7 +83,6 @@ public: Type *type; // !=NULL means that semantic() has been run Loc loc; // file location EXP op; // to minimize use of dynamic_cast - d_bool parens; // if this is a parenthesized expression size_t size() const; static void _init(); @@ -316,6 +315,7 @@ class IdentifierExp : public Expression { public: Identifier *ident; + d_bool parens; static IdentifierExp *create(const Loc &loc, Identifier *ident); bool isLvalue() override final; @@ -839,6 +839,7 @@ public: d_bool directcall; // true if a virtual call is devirtualized d_bool inDebugStatement; // true if this was in a debug statement d_bool ignoreAttributes; // don't enforce attributes (e.g. call @gc function in @nogc code) + d_bool isUfcsRewrite; // the first argument was pushed in here by a UFCS rewrite VarDeclaration *vthis2; // container for multi-context static CallExp *create(const Loc &loc, Expression *e, Expressions *exps); diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index cf4aac4..8ac8866 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -653,7 +653,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce) if (!ce.names) ce.names = new Identifiers(); ce.names.shift(null); - + ce.isUfcsRewrite = true; return null; } @@ -1254,12 +1254,12 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = return ErrorExp.get(); e2 = resolveProperties(sc, e2); - Expressions a; + Expressions* a = new Expressions(); a.push(e2); for (size_t i = 0; i < os.a.length; i++) { - if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet)) + if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet)) { if (f.errors) return ErrorExp.get(); @@ -1378,10 +1378,10 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = return ErrorExp.get(); e2 = resolveProperties(sc, e2); - Expressions a; + Expressions* a = new Expressions(); a.push(e2); - FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet); + FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet); if (fd && fd.type) { if (fd.errors) @@ -3574,6 +3574,51 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor result = exp; } + /** + * Sets the `lowering` field of a `NewExp` to a call to `_d_newitemT` unless + * compiling with `-betterC` or within `__traits(compiles)`. + * + * Params: + * ne = the `NewExp` to lower + */ + private void tryLowerToNewItem(NewExp ne) + { + if (global.params.betterC || !sc.needsCodegen()) + return; + + auto hook = global.params.tracegc ? Id._d_newitemTTrace : Id._d_newitemT; + if (!verifyHookExist(ne.loc, *sc, hook, "new struct")) + return; + + /* Lower the memory allocation and initialization of `new T()` to + * `_d_newitemT!T()`. + */ + Expression id = new IdentifierExp(ne.loc, Id.empty); + id = new DotIdExp(ne.loc, id, Id.object); + auto tiargs = new Objects(); + /* + * Remove `inout`, `const`, `immutable` and `shared` to reduce the + * number of generated `_d_newitemT` instances. + */ + auto t = ne.type.nextOf.unqualify(MODFlags.wild | MODFlags.const_ | + MODFlags.immutable_ | MODFlags.shared_); + tiargs.push(t); + id = new DotTemplateInstanceExp(ne.loc, id, hook, tiargs); + + auto arguments = new Expressions(); + if (global.params.tracegc) + { + auto funcname = (sc.callsc && sc.callsc.func) ? + sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars(); + arguments.push(new StringExp(ne.loc, ne.loc.filename.toDString())); + arguments.push(new IntegerExp(ne.loc, ne.loc.linnum, Type.tint32)); + arguments.push(new StringExp(ne.loc, funcname.toDString())); + } + id = new CallExp(ne.loc, id, arguments); + + ne.lowering = id.expressionSemantic(sc); + } + override void visit(NewExp exp) { static if (LOGSEMANTIC) @@ -4007,6 +4052,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } exp.type = exp.type.pointerTo(); + tryLowerToNewItem(exp); } else if (tb.ty == Tarray) { @@ -4078,6 +4124,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } exp.type = exp.type.pointerTo(); + tryLowerToNewItem(exp); } else if (tb.ty == Taarray) { @@ -5192,7 +5239,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { s = (cast(TemplateExp)exp.e1).td; L2: - exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList, FuncResolveFlag.standard); + exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList, + exp.isUfcsRewrite ? FuncResolveFlag.ufcs : FuncResolveFlag.standard); if (!exp.f || exp.f.errors) return setError(); if (exp.f.needThis()) @@ -5301,6 +5349,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor buf.writeByte(')'); //printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco); + if (exp.isUfcsRewrite) + { + const arg = (*exp.argumentList.arguments)[0]; + .error(exp.loc, "no property `%s` for `%s` of type `%s`", exp.f.ident.toChars(), arg.toChars(), arg.type.toChars()); + .errorSupplemental(exp.loc, "the following error occured while looking for a UFCS match"); + } + .error(exp.loc, "%s `%s%s` is not callable using argument types `%s`", exp.f.kind(), exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList), buf.peekChars()); if (failMessage) @@ -6733,7 +6788,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.ident != Id.__sizeof) { - result = fieldLookup(exp.e1, sc, exp.ident); + result = fieldLookup(exp.e1, sc, exp.ident, exp.arrow); return; } } @@ -9068,7 +9123,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor else if (sc.flags & SCOPE.Cfile && e1x.isDotIdExp()) { auto die = e1x.isDotIdExp(); - e1x = fieldLookup(die.e1, sc, die.ident); + e1x = fieldLookup(die.e1, sc, die.ident, die.arrow); } else if (auto die = e1x.isDotIdExp()) { @@ -11023,7 +11078,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor /* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be * used with `-betterC`, but only during CTFE. */ - if (global.params.betterC) + if (global.params.betterC || !sc.needsCodegen()) return; if (auto ce = exp.isCatExp()) @@ -13175,10 +13230,20 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag) Expression se = new ScopeExp(exp.loc, imp.pkg); return se.expressionSemantic(sc); } + + if (auto attr = s.isAttribDeclaration()) + { + if (auto sm = ie.sds.search(exp.loc, exp.ident, flags)) + { + auto es = new DsymbolExp(exp.loc, sm); + return es; + } + } + // BUG: handle other cases like in IdentifierExp::semantic() debug { - printf("s = '%s', kind = '%s'\n", s.toChars(), s.kind()); + printf("s = %p '%s', kind = '%s'\n", s, s.toChars(), s.kind()); } assert(0); } diff --git a/gcc/d/dmd/foreachvar.d b/gcc/d/dmd/foreachvar.d index 7a96469..1293057 100644 --- a/gcc/d/dmd/foreachvar.d +++ b/gcc/d/dmd/foreachvar.d @@ -15,7 +15,6 @@ import core.stdc.stdio; import core.stdc.stdlib; import core.stdc.string; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.attrib; @@ -33,6 +32,7 @@ import dmd.identifier; import dmd.init; import dmd.initsem; import dmd.mtype; +import dmd.postordervisitor; import dmd.printast; import dmd.root.array; import dmd.root.rootobject; diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index 8e11ab1..a714d2d 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -59,6 +59,10 @@ import dmd.statementsem; import dmd.tokens; import dmd.visitor; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + /// Inline Status enum ILS : ubyte { @@ -259,21 +263,30 @@ extern (C++) struct Ensure } /*********************************************************** + * Most functions don't have contracts, so save memory by grouping + * this information into a separate struct */ -extern (C++) class FuncDeclaration : Declaration +private struct ContractInfo { Statements* frequires; /// in contracts Ensures* fensures; /// out contracts Statement frequire; /// lowered in contract Statement fensure; /// lowered out contract - Statement fbody; /// function body - - FuncDeclarations foverrides; /// functions this function overrides FuncDeclaration fdrequire; /// function that does the in contract FuncDeclaration fdensure; /// function that does the out contract - Expressions* fdrequireParams; /// argument list for __require Expressions* fdensureParams; /// argument list for __ensure +} + +/*********************************************************** + */ +extern (C++) class FuncDeclaration : Declaration +{ + Statement fbody; /// function body + + FuncDeclarations foverrides; /// functions this function overrides + + private ContractInfo* contracts; /// contract information const(char)* mangleString; /// mangled symbol created from mangleExact() @@ -403,6 +416,44 @@ extern (C++) class FuncDeclaration : Declaration return new FuncDeclaration(loc, endloc, id, storage_class, type, noreturn); } + final nothrow pure @safe + { + private ref ContractInfo getContracts() + { + if (!contracts) + contracts = new ContractInfo(); + return *contracts; + } + + // getters + inout(Statements*) frequires() inout { return contracts ? contracts.frequires : null; } + inout(Ensures*) fensures() inout { return contracts ? contracts.fensures : null; } + inout(Statement) frequire() inout { return contracts ? contracts.frequire: null; } + inout(Statement) fensure() inout { return contracts ? contracts.fensure : null; } + inout(FuncDeclaration) fdrequire() inout { return contracts ? contracts.fdrequire : null; } + inout(FuncDeclaration) fdensure() inout { return contracts ? contracts.fdensure: null; } + inout(Expressions*) fdrequireParams() inout { return contracts ? contracts.fdrequireParams: null; } + inout(Expressions*) fdensureParams() inout { return contracts ? contracts.fdensureParams: null; } + + extern (D) private static string generateContractSetter(string field, string type) + { + return type ~ " " ~ field ~ "(" ~ type ~ " param)" ~ + "{ + if (!param && !contracts) return null; + return getContracts()." ~ field ~ " = param; + }"; + } + + mixin(generateContractSetter("frequires", "Statements*")); + mixin(generateContractSetter("fensures", "Ensures*")); + mixin(generateContractSetter("frequire", "Statement")); + mixin(generateContractSetter("fensure", "Statement")); + mixin(generateContractSetter("fdrequire", "FuncDeclaration")); + mixin(generateContractSetter("fdensure", "FuncDeclaration")); + mixin(generateContractSetter("fdrequireParams", "Expressions*")); + mixin(generateContractSetter("fdensureParams", "Expressions*")); + } + override FuncDeclaration syntaxCopy(Dsymbol s) { //printf("FuncDeclaration::syntaxCopy('%s')\n", toChars()); @@ -2717,7 +2768,7 @@ extern (C++) class FuncDeclaration : Declaration */ static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, StorageClass stc = 0) { - return genCfunc(fparams, treturn, Identifier.idPool(name, cast(uint)strlen(name)), stc); + return genCfunc(fparams, treturn, Identifier.idPool(name[0 .. strlen(name)]), stc); } static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, Identifier id, StorageClass stc = 0) @@ -3199,6 +3250,7 @@ enum FuncResolveFlag : ubyte quiet = 1, /// do not issue error message on no match, just return `null`. overloadOnly = 2, /// only resolve overloads, i.e. do not issue error on ambiguous /// matches and need explicit this. + ufcs = 4, /// trying to resolve UFCS call } /******************************************* @@ -3316,12 +3368,22 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, } // no match, generate an error messages + if (flags & FuncResolveFlag.ufcs) + { + auto arg = (*fargs)[0]; + .error(loc, "no property `%s` for `%s` of type `%s`", s.ident.toChars(), arg.toChars(), arg.type.toChars()); + .errorSupplemental(loc, "the following error occured while looking for a UFCS match"); + } + if (!fd) { // all of overloads are templates if (td) { - .error(loc, "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`", + const(char)* msg = "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`"; + if (!od && !td.overnext) + msg = "%s `%s.%s` is not callable using argument types `!(%s)%s`"; + .error(loc, msg, td.kind(), td.parent.toPrettyChars(), td.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars()); diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 45b4528..0ac6042 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -26,6 +26,10 @@ import dmd.location; import dmd.lexer : CompileEnv; import dmd.utils; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + /// Defines a setting for how compiler warnings and deprecations are handled enum DiagnosticReporting : ubyte { diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 902cf83..66345ac 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -353,10 +353,11 @@ typedef unsigned long long uinteger_t; // file location struct Loc { - const char *filename; // either absolute or relative to cwd - unsigned linnum; - unsigned charnum; - +private: + unsigned _linnum; + unsigned short _charnum; + unsigned short fileIndex; +public: static void set(bool showColumns, MessageStyle messageStyle); static bool showColumns; @@ -364,18 +365,25 @@ struct Loc Loc() { - linnum = 0; - charnum = 0; - filename = NULL; + _linnum = 0; + _charnum = 0; + fileIndex = 0; } Loc(const char *filename, unsigned linnum, unsigned charnum) { - this->linnum = linnum; - this->charnum = charnum; - this->filename = filename; + this->linnum(linnum); + this->charnum(charnum); + this->filename(filename); } + uint32_t charnum() const; + uint32_t charnum(uint32_t num); + uint32_t linnum() const; + uint32_t linnum(uint32_t num); + const char *filename() const; + void filename(const char *name); + const char *toChars( bool showColumns = Loc::showColumns, MessageStyle messageStyle = Loc::messageStyle) const; diff --git a/gcc/d/dmd/gluelayer.d b/gcc/d/dmd/gluelayer.d index 7b52eff..1793700 100644 --- a/gcc/d/dmd/gluelayer.d +++ b/gcc/d/dmd/gluelayer.d @@ -48,25 +48,6 @@ version (NoBackend) } } } -else version (MARS) -{ - public import dmd.backend.cc : block, Blockx, Symbol; - public import dmd.backend.type : type; - public import dmd.backend.el : elem; - public import dmd.backend.code_x86 : code; - - extern (C++) - { - Statement asmSemantic(AsmStatement s, Scope* sc); - - void toObjFile(Dsymbol ds, bool multiobj); - - extern(C++) abstract class ObjcGlue - { - static void initialize(); - } - } -} else version (IN_GCC) { extern (C++) union tree_node; @@ -88,4 +69,12 @@ else version (IN_GCC) } } else - static assert(false, "Unsupported compiler backend"); +{ + public import dmd.backend.cc : block, Blockx, Symbol; + public import dmd.backend.type : type; + public import dmd.backend.el : elem; + public import dmd.backend.code_x86 : code; + public import dmd.iasm : asmSemantic; + public import dmd.objc_glue : ObjcGlue; + public import dmd.toobj : toObjFile; +} diff --git a/gcc/d/dmd/iasm.d b/gcc/d/dmd/iasm.d index 66829da..1fdfe40 100644 --- a/gcc/d/dmd/iasm.d +++ b/gcc/d/dmd/iasm.d @@ -23,13 +23,14 @@ import dmd.tokens; import dmd.statement; import dmd.statementsem; -version (MARS) +version (IN_GCC) { - import dmd.iasmdmd; + import dmd.iasmgcc; } -else version (IN_GCC) +else { - import dmd.iasmgcc; + import dmd.iasmdmd; + version = MARS; } /************************ AsmStatement ***************************************/ diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d index a2271d5..a2daf60 100644 --- a/gcc/d/dmd/id.d +++ b/gcc/d/dmd/id.d @@ -315,6 +315,8 @@ immutable Msgtable[] msgtable = { "_d_newThrowable" }, { "_d_newclassT" }, { "_d_newclassTTrace" }, + { "_d_newitemT" }, + { "_d_newitemTTrace" }, { "_d_assert_fail" }, { "dup" }, { "_aaApply" }, @@ -549,6 +551,7 @@ immutable Msgtable[] msgtable = { "_pure", "pure" }, { "define" }, { "undef" }, + { "ident" }, ]; diff --git a/gcc/d/dmd/identifier.d b/gcc/d/dmd/identifier.d index 2233d77..b1c421c 100644 --- a/gcc/d/dmd/identifier.d +++ b/gcc/d/dmd/identifier.d @@ -274,12 +274,7 @@ nothrow: return idPool(s[0 .. len]); } - extern (D) static Identifier idPool(const(char)[] s) - { - return idPool(s, false); - } - - extern (D) private static Identifier idPool(const(char)[] s, bool isAnonymous) + extern (D) static Identifier idPool(const(char)[] s, bool isAnonymous = false) { auto sv = stringtable.update(s); auto id = sv.value; @@ -291,18 +286,18 @@ nothrow: return id; } - extern (D) static Identifier idPool(const(char)* s, size_t len, int value) - { - return idPool(s[0 .. len], value); - } - - extern (D) static Identifier idPool(const(char)[] s, int value) + /****************************************** + * Used for inserting keywords into the string table. + * Params: + * s = string for keyword + * value = TOK.xxxx for the keyword + */ + extern (D) static void idPool(const(char)[] s, TOK value) { auto sv = stringtable.insert(s, null); assert(sv); auto id = new Identifier(sv.toString(), value); sv.value = id; - return id; } /********************************** diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d index 97710b8..fe0aa17 100644 --- a/gcc/d/dmd/importc.d +++ b/gcc/d/dmd/importc.d @@ -108,11 +108,12 @@ Expression arrayFuncConv(Expression e, Scope* sc) * e = evaluates to an instance of a struct * sc = context * id = identifier of a field in that struct + * arrow = -> was used * Returns: * if successful `e.ident` * if not then `ErrorExp` and message is printed */ -Expression fieldLookup(Expression e, Scope* sc, Identifier id) +Expression fieldLookup(Expression e, Scope* sc, Identifier id, bool arrow) { e = e.expressionSemantic(sc); if (e.isErrorExp()) @@ -123,6 +124,9 @@ Expression fieldLookup(Expression e, Scope* sc, Identifier id) if (t.isTypePointer()) { t = t.isTypePointer().next; + auto pe = e.toChars(); + if (!arrow) + e.error("since `%s` is a pointer, use `%s->%s` instead of `%s.%s`", pe, pe, id.toChars(), pe, id.toChars()); e = new PtrExp(e.loc, e); } if (auto ts = t.isTypeStruct()) @@ -237,15 +241,16 @@ Expression castCallAmbiguity(Expression e, Scope* sc) case EXP.call: auto ce = (*pe).isCallExp(); - if (ce.e1.parens) + auto ie = ce.e1.isIdentifierExp(); + if (ie && ie.parens) { - ce.e1 = expressionSemantic(ce.e1, sc); + ce.e1 = expressionSemantic(ie, sc); if (ce.e1.op == EXP.type) { const numArgs = ce.arguments ? ce.arguments.length : 0; if (numArgs >= 1) { - ce.e1.parens = false; + ie.parens = false; Expression arg; foreach (a; (*ce.arguments)[]) { diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index 893d2a6..ca770bd 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -587,6 +587,9 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ */ t = t.toBasetype(); + if (auto tv = t.isTypeVector()) + t = tv.basetype; + /* If `{ expression }` return the expression initializer */ ExpInitializer isBraceExpression() diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index 0ec468b..a878cc9 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -119,7 +119,7 @@ class Lexer this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset, bool doDocComment, bool commentToken, ErrorSink errorSink, - const CompileEnv* compileEnv) pure scope + const CompileEnv* compileEnv) scope { scanloc = Loc(filename, 1, 1); // debug printf("Lexer::Lexer(%p)\n", base); @@ -573,7 +573,7 @@ class Lexer } break; } - Identifier id = Identifier.idPool(cast(char*)t.ptr, cast(uint)(p - t.ptr)); + Identifier id = Identifier.idPool((cast(char*)t.ptr)[0 .. p - t.ptr], false); t.ident = id; t.value = cast(TOK)id.getValue(); @@ -2672,9 +2672,9 @@ class Lexer return result; } - final Loc loc() pure @nogc + final Loc loc() @nogc { - scanloc.charnum = cast(uint)(1 + p - line); + scanloc.charnum = cast(ushort)(1 + p - line); version (LocOffset) scanloc.fileOffset = cast(uint)(p - base); return scanloc; @@ -3098,9 +3098,9 @@ class Lexer /************************** * `p` should be at start of next line */ - private void endOfLine() pure @nogc @safe + private void endOfLine() @nogc @safe { - scanloc.linnum++; + scanloc.linnum = scanloc.linnum + 1; line = p; } } diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d index 020d297..b2b3661 100644 --- a/gcc/d/dmd/location.d +++ b/gcc/d/dmd/location.d @@ -11,7 +11,10 @@ module dmd.location; +import core.stdc.stdio; + import dmd.common.outbuffer; +import dmd.root.array; import dmd.root.filename; version (DMDLIB) @@ -34,10 +37,9 @@ debug info etc. */ struct Loc { - /// zero-terminated filename string, either absolute or relative to cwd - const(char)* filename; - uint linnum; /// line number, starting from 1 - uint charnum; /// utf8 code unit index relative to start of line, starting from 1 + private uint _linnum; + private ushort _charnum; + private ushort fileIndex; // index into filenames[], starting from 1 (0 means no filename) version (LocOffset) uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0 @@ -46,6 +48,8 @@ struct Loc extern (C++) __gshared bool showColumns; extern (C++) __gshared MessageStyle messageStyle; + __gshared Array!(const(char)*) filenames; + nothrow: /******************************* @@ -60,19 +64,69 @@ nothrow: this.messageStyle = messageStyle; } - extern (D) this(const(char)* filename, uint linnum, uint charnum) pure + extern (D) this(const(char)* filename, uint linnum, uint charnum) { - this.linnum = linnum; - this.charnum = charnum; + this._linnum = linnum; + this._charnum = cast(ushort) charnum; this.filename = filename; } + /// utf8 code unit index relative to start of line, starting from 1 + extern (C++) uint charnum() const @nogc @safe + { + return _charnum; + } + + /// ditto + extern (C++) uint charnum(uint num) @nogc @safe + { + return _charnum = cast(ushort) num; + } + + /// line number, starting from 1 + extern (C++) uint linnum() const @nogc @safe + { + return _linnum; + } + + /// ditto + extern (C++) uint linnum(uint num) @nogc @safe + { + return _linnum = num; + } + + /*** + * Returns: filename for this location, null if none + */ + extern (C++) const(char)* filename() const @nogc + { + return fileIndex ? filenames[fileIndex - 1] : null; + } + + /*** + * Set file name for this location + * Params: + * name = file name for location, null for no file name + */ + extern (C++) void filename(const(char)* name) + { + if (name) + { + //printf("setting %s\n", name); + filenames.push(name); + fileIndex = cast(ushort)filenames.length; + assert(fileIndex); // no overflow + } + else + fileIndex = 0; + } + extern (C++) const(char)* toChars( bool showColumns = Loc.showColumns, - MessageStyle messageStyle = Loc.messageStyle) const pure nothrow + MessageStyle messageStyle = Loc.messageStyle) const nothrow { OutBuffer buf; - if (filename) + if (fileIndex) { buf.writestring(filename); } @@ -126,7 +180,7 @@ nothrow: * may lead to multiple equivalent filenames (`foo.d-mixin-<line>`), * e.g., for test/runnable/test18880.d. */ - extern (D) bool opEquals(ref const(Loc) loc) const @trusted pure nothrow @nogc + extern (D) bool opEquals(ref const(Loc) loc) const @trusted nothrow @nogc { import core.stdc.string : strcmp; @@ -137,7 +191,7 @@ nothrow: } /// ditto - extern (D) size_t toHash() const @trusted pure nothrow + extern (D) size_t toHash() const @trusted nothrow { import dmd.root.string : toDString; @@ -153,6 +207,6 @@ nothrow: */ bool isValid() const pure { - return filename !is null; + return fileIndex != 0; } } diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index badc579..cb3e6cd 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -2448,7 +2448,7 @@ extern (C++) abstract class Type : ASTNode //printf("%p %s, deco = %s, name = %s\n", this, toChars(), deco, name); assert(0 < length && length < namelen); // don't overflow the buffer - auto id = Identifier.idPool(name, length); + auto id = Identifier.idPool(name[0 .. length]); if (name != namebuf.ptr) free(name); @@ -7119,9 +7119,9 @@ bool isCopyable(Type t) assert(ctor); scope el = new IdentifierExp(Loc.initial, Id.p); // dummy lvalue el.type = cast() ts; - Expressions args; + Expressions* args = new Expressions(); args.push(el); - FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(&args), FuncResolveFlag.quiet); + FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(args), FuncResolveFlag.quiet); if (!f || f.storage_class & STC.disable) return false; } diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index a0f3e60..9a8f242 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -16,7 +16,6 @@ module dmd.nogc; import core.stdc.stdio; import dmd.aggregate; -import dmd.apply; import dmd.astenums; import dmd.declaration; import dmd.dscope; @@ -26,6 +25,7 @@ import dmd.func; import dmd.globals; import dmd.init; import dmd.mtype; +import dmd.postordervisitor; import dmd.tokens; import dmd.visitor; diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d index 89728b6..56243a0 100644 --- a/gcc/d/dmd/ob.d +++ b/gcc/d/dmd/ob.d @@ -20,7 +20,6 @@ import dmd.root.rootobject; import dmd.root.rmem; import dmd.aggregate; -import dmd.apply; import dmd.arraytypes; import dmd.astenums; import dmd.declaration; diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d index d7b90d7..0e64d9c 100644 --- a/gcc/d/dmd/opover.d +++ b/gcc/d/dmd/opover.d @@ -607,8 +607,6 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) //printf("BinExp::op_overload() (%s)\n", e.toChars()); Identifier id = opId(e); Identifier id_r = opId_r(e); - Expressions args1; - Expressions args2; int argsset = 0; AggregateDeclaration ad1 = isAggregate(e.e1.type); AggregateDeclaration ad2 = isAggregate(e.e2.type); @@ -701,6 +699,8 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) } } } + Expressions* args1 = new Expressions(); + Expressions* args2 = new Expressions(); if (s || s_r) { /* Try: @@ -709,16 +709,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) * and see which is better. */ args1.setDim(1); - args1[0] = e.e1; - expandTuples(&args1); + (*args1)[0] = e.e1; + expandTuples(args1); args2.setDim(1); - args2[0] = e.e2; - expandTuples(&args2); + (*args2)[0] = e.e2; + expandTuples(args2); argsset = 1; MatchAccumulator m; if (s) { - functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2)); + functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -727,7 +727,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) FuncDeclaration lastf = m.lastf; if (s_r) { - functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1)); + functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -791,16 +791,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (!argsset) { args1.setDim(1); - args1[0] = e.e1; - expandTuples(&args1); + (*args1)[0] = e.e1; + expandTuples(args1); args2.setDim(1); - args2[0] = e.e2; - expandTuples(&args2); + (*args2)[0] = e.e2; + expandTuples(args2); } MatchAccumulator m; if (s_r) { - functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2)); + functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -809,7 +809,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) FuncDeclaration lastf = m.lastf; if (s) { - functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1)); + functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -1197,7 +1197,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) return ErrorExp.get(); } Identifier id = opId(e); - Expressions args2; + Expressions* args2 = new Expressions(); AggregateDeclaration ad1 = isAggregate(e.e1.type); Dsymbol s = null; Objects* tiargs = null; @@ -1240,10 +1240,10 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) * a.opOpAssign(b) */ args2.setDim(1); - args2[0] = e.e2; - expandTuples(&args2); + (*args2)[0] = e.e2; + expandTuples(args2); MatchAccumulator m; - functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2)); + functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); @@ -1322,12 +1322,12 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop * b.opEquals(a) * and see which is better. */ - Expressions args1 = Expressions(1); - args1[0] = e.e1; - expandTuples(&args1); - Expressions args2 = Expressions(1); - args2[0] = e.e2; - expandTuples(&args2); + Expressions* args1 = new Expressions(1); + (*args1)[0] = e.e1; + expandTuples(args1); + Expressions* args2 = new Expressions(1); + (*args2)[0] = e.e2; + expandTuples(args2); MatchAccumulator m; if (0 && s && s_r) { @@ -1336,7 +1336,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop } if (s) { - functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2)); + functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) return ErrorExp.get(); } @@ -1344,7 +1344,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop int count = m.count; if (s_r) { - functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1)); + functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1)); if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) return ErrorExp.get(); } diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index 61c385f..335310d 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -769,11 +769,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) return; if (e.arguments) { - Type t1 = e.e1.type.toBasetype(); - if (auto td = t1.isTypeDelegate()) - t1 = td.next; // t1 can apparently be void for __ArrayDtor(T) calls - if (auto tf = t1.isTypeFunction()) + if (auto tf = e.calledFunctionType()) { foreach (i, ref arg; (*e.arguments)[]) { diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index 68a2506..b7e0791 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -4515,10 +4515,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } if (_init) { - if (isThis) - error(token.loc, "cannot use syntax `alias this = %s`, use `alias %s this` instead", _init.toChars(), _init.toChars()); - else - error("alias cannot have initializer"); + error("alias cannot have initializer"); } v = new AST.AliasDeclaration(aliasLoc, ident, t); @@ -4780,23 +4777,20 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer addComment(s, comment); return a; } - version (none) + /* Look for: + * alias this = identifier; + */ + if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier) { - /* Look for: - * alias this = identifier; - */ - if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier) - { - check(TOK.this_); - check(TOK.assign); - auto s = new AliasThis(loc, token.ident); - nextToken(); - check(TOK.semicolon, "`alias this = Identifier`"); - auto a = new Dsymbols(); - a.push(s); - addComment(s, comment); - return a; - } + check(TOK.this_); + check(TOK.assign); + auto s = new AST.AliasThis(loc, token.ident); + nextToken(); + check(TOK.semicolon, "`alias this = Identifier`"); + auto a = new AST.Dsymbols(); + a.push(s); + addComment(s, comment); + return a; } /* Look for: * alias identifier = type; @@ -5032,7 +5026,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer stc = STC.ref_; nextToken(); } - if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly) + if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly && + token.value != TOK.goesTo) { // function type (parameters) { statements... } // delegate type (parameters) { statements... } @@ -5331,7 +5326,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer error("cannot use function constraints for non-template functions. Use `static if` instead"); } else - error("semicolon expected following function declaration"); + error("semicolon expected following function declaration, not `%s`", token.toChars()); } break; } @@ -7081,7 +7076,7 @@ LagainStc: private void checkParens(TOK value, AST.Expression e) { - if (precedence[e.op] == PREC.rel && !e.parens) + if (precedence[e.op] == PREC.rel) error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`", e.toChars(), Token.toChars(value)); } @@ -8485,7 +8480,6 @@ LagainStc: // ( expression ) nextToken(); e = parseExpression(); - e.parens = true; check(loc, TOK.rightParenthesis); break; } @@ -8806,9 +8800,9 @@ LagainStc: nextToken(); return AST.ErrorExp.get(); } - e = new AST.TypeExp(loc, t); - e.parens = true; - e = parsePostExp(e); + auto te = new AST.TypeExp(loc, t); + te.parens = true; + e = parsePostExp(te); } else { @@ -9115,14 +9109,18 @@ LagainStc: private AST.Expression parseAndExp() { Loc loc = token.loc; + bool parens = token.value == TOK.leftParenthesis; auto e = parseCmpExp(); while (token.value == TOK.and) { - checkParens(TOK.and, e); - nextToken(); + if (!parens) + checkParens(TOK.and, e); + parens = nextToken() == TOK.leftParenthesis; auto e2 = parseCmpExp(); - checkParens(TOK.and, e2); + if (!parens) + checkParens(TOK.and, e2); e = new AST.AndExp(loc, e, e2); + parens = true; // don't call checkParens() for And loc = token.loc; } return e; @@ -9130,32 +9128,42 @@ LagainStc: private AST.Expression parseXorExp() { - const loc = token.loc; + Loc loc = token.loc; + bool parens = token.value == TOK.leftParenthesis; auto e = parseAndExp(); while (token.value == TOK.xor) { - checkParens(TOK.xor, e); - nextToken(); + if (!parens) + checkParens(TOK.xor, e); + parens = nextToken() == TOK.leftParenthesis; auto e2 = parseAndExp(); - checkParens(TOK.xor, e2); + if (!parens) + checkParens(TOK.xor, e2); e = new AST.XorExp(loc, e, e2); + parens = true; + loc = token.loc; } return e; } private AST.Expression parseOrExp() { - const loc = token.loc; + Loc loc = token.loc; + bool parens = token.value == TOK.leftParenthesis; auto e = parseXorExp(); while (token.value == TOK.or) { - checkParens(TOK.or, e); - nextToken(); + if (!parens) + checkParens(TOK.or, e); + parens = nextToken() == TOK.leftParenthesis; auto e2 = parseXorExp(); - checkParens(TOK.or, e2); + if (!parens) + checkParens(TOK.or, e2); e = new AST.OrExp(loc, e, e2); + parens = true; + loc = token.loc; } return e; } @@ -9206,6 +9214,7 @@ LagainStc: AST.Expression parseAssignExp() { + bool parens = token.value == TOK.leftParenthesis; AST.Expression e; e = parseCondExp(); if (e is null) @@ -9214,7 +9223,7 @@ LagainStc: // require parens for e.g. `t ? a = 1 : b = 2` void checkRequiredParens() { - if (e.op == EXP.question && !e.parens) + if (e.op == EXP.question && !parens) eSink.error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`", e.toChars(), Token.toChars(token.value)); } diff --git a/gcc/d/dmd/apply.d b/gcc/d/dmd/postordervisitor.d index d18b81f..a0c7115 100644 --- a/gcc/d/dmd/apply.d +++ b/gcc/d/dmd/postordervisitor.d @@ -9,11 +9,9 @@ * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/apply.d */ -module dmd.apply; +module dmd.postordervisitor; import dmd.arraytypes; -import dmd.dsymbol; -import dmd.dsymbolsem; import dmd.dtemplate; import dmd.expression; import dmd.root.array; @@ -26,39 +24,6 @@ bool walkPostorder(Expression e, StoppableVisitor v) return v.stop; } -/********************************* - * Iterate this dsymbol or members of this scoped dsymbol, then - * call `fp` with the found symbol and `params`. - * Params: - * symbol = the dsymbol or parent of members to call fp on - * fp = function pointer to process the iterated symbol. - * If it returns nonzero, the iteration will be aborted. - * params = any parameters passed to fp. - * Returns: - * nonzero if the iteration is aborted by the return value of fp, - * or 0 if it's completed. - */ -int apply(FP, Params...)(Dsymbol symbol, FP fp, Params params) -{ - if (auto nd = symbol.isNspace()) - { - return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } ); - } - if (auto ad = symbol.isAttribDeclaration()) - { - return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, params); } ); - } - if (auto tm = symbol.isTemplateMixin()) - { - if (tm._scope) // if fwd reference - dsymbolSemantic(tm, null); // try to resolve it - - return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } ); - } - - return fp(symbol, params); -} - /************************************** * An Expression tree walker that will visit each Expression e in the tree, * in depth-first evaluation order, and call fp(e,param) on it. diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d index ee268d9..c40e72c 100644 --- a/gcc/d/dmd/semantic2.d +++ b/gcc/d/dmd/semantic2.d @@ -447,14 +447,12 @@ private extern(C++) final class Semantic2Visitor : Visitor const sameParams = tf1.parameterList == tf2.parameterList; // Allow the hack to declare overloads with different parameters/STC's - // @@@DEPRECATED_2.104@@@ - // Deprecated in 2020-08, make this an error in 2.104 if (parent1.isModule() && linkage1 != LINK.d && linkage1 != LINK.cpp && (!sameAttr || !sameParams) ) { - f2.deprecation("cannot overload `extern(%s)` function at %s", + f2.error("cannot overload `extern(%s)` function at %s", linkageToChars(f1._linkage), f1.loc.toChars()); return 0; diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d index 3f3e7e6..90b86df 100644 --- a/gcc/d/dmd/sideeffect.d +++ b/gcc/d/dmd/sideeffect.d @@ -11,7 +11,6 @@ module dmd.sideeffect; -import dmd.apply; import dmd.astenums; import dmd.declaration; import dmd.dscope; @@ -22,6 +21,7 @@ import dmd.globals; import dmd.identifier; import dmd.init; import dmd.mtype; +import dmd.postordervisitor; import dmd.tokens; import dmd.visitor; @@ -101,9 +101,11 @@ extern (C++) bool hasSideEffect(Expression e, bool assumeImpureCalls = false) int callSideEffectLevel(FuncDeclaration f) { /* https://issues.dlang.org/show_bug.cgi?id=12760 - * ctor call always has side effects. + * https://issues.dlang.org/show_bug.cgi?id=16384 + * + * ctor calls and invariant calls always have side effects */ - if (f.isCtorDeclaration()) + if (f.isCtorDeclaration() || f.isInvariantDeclaration()) return 0; assert(f.type.ty == Tfunction); TypeFunction tf = cast(TypeFunction)f.type; diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index f849ce1..f0454163 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -1273,8 +1273,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) } else if (auto td = sfront.isTemplateDeclaration()) { - Expressions a; - if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(&a), FuncResolveFlag.quiet)) + if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(), FuncResolveFlag.quiet)) tfront = f.type; } else if (auto d = sfront.toAlias().isDeclaration()) @@ -2733,7 +2732,8 @@ Statement statementSemanticVisit(Statement s, Scope* sc) tbret = tret.toBasetype(); } - if (inferRef) // deduce 'auto ref' + // https://issues.dlang.org/show_bug.cgi?id=23914 + if (inferRef && !resType.isTypeNoreturn()) // deduce 'auto ref' tf.isref = false; if (tbret.ty != Tvoid && !resType.isTypeNoreturn()) // if non-void return @@ -3593,6 +3593,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc) cas.error("`asm` statement is assumed to be impure - mark it with `pure` if it is not"); if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "`asm` statement in %s `%s` is assumed to use the GC - mark it with `@nogc` if it does not")) cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not"); + // @@@DEPRECATED_2.114@@@ + // change deprecation() to error(), add `else` and remove `| STC.safe` + // to turn deprecation into an error when deprecation cycle is over + if (cas.stc & STC.safe) + cas.deprecation("`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead"); if (!(cas.stc & (STC.trusted | STC.safe))) { sc.setUnsafe(false, cas.loc, "`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not"); @@ -4045,6 +4050,13 @@ void catchSemantic(Catch c, Scope* sc) // reference .object.Throwable c.type = getThrowable(); } + else if (!c.type.isNaked() && !c.type.isConst()) + { + // @@@DEPRECATED_2.113@@@ + // Deprecated in 2.103, change into an error & uncomment in 2.113 + deprecation(c.loc, "can only catch mutable or const qualified types, not `%s`", c.type.toChars()); + //c.errors = true; + } c.type = c.type.typeSemantic(c.loc, sc); if (c.type == Type.terror) { diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d index 352c89e..5871762 100644 --- a/gcc/d/dmd/tokens.d +++ b/gcc/d/dmd/tokens.d @@ -593,7 +593,7 @@ shared static this() nothrow foreach (kw; keywords) { //printf("keyword[%d] = '%s'\n",kw, Token.tochars[kw].ptr); - Identifier.idPool(Token.tochars[kw].ptr, Token.tochars[kw].length, cast(uint)kw); + Identifier.idPool(Token.tochars[kw], kw); } } diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index 0f36353..53c8fb0 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -1215,7 +1215,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) { if (fd.overnext) { - deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", fd.toChars()); + deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", fd.toChars()); deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from"); } } @@ -1225,7 +1225,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) { if (td.overnext || td.funcroot) { - deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", td.ident.toChars()); + deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", td.ident.toChars()); deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from"); } } diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d index c588270..a82a268 100644 --- a/gcc/d/dmd/transitivevisitor.d +++ b/gcc/d/dmd/transitivevisitor.d @@ -161,6 +161,16 @@ package mixin template ParseVisitMethods(AST) s._body.accept(this); } + override void visit(AST.StaticForeachStatement s) + { + // printf("Visiting StaticForeachStatement\n"); + if (s.sfe.aggrfe) + s.sfe.aggrfe.accept(this); + + if (s.sfe.rangefe) + s.sfe.rangefe.accept(this); + } + override void visit(AST.IfStatement s) { //printf("Visiting IfStatement\n"); diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index f0decf2..09eef83 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -163,7 +163,7 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb /* Look for what user might have intended */ const p = mt.mutableOf().unSharedOf().toChars(); - auto id = Identifier.idPool(p, cast(uint)strlen(p)); + auto id = Identifier.idPool(p[0 .. strlen(p)]); if (const n = importHint(id.toString())) error(loc, "`%s` is not defined, perhaps `import %.*s;` ?", p, cast(int)n.length, n.ptr); else if (auto s2 = sc.search_correct(id)) diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 23f2f0b..8fb1eea 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -2296,11 +2296,12 @@ public: return; } + /* This case should have been rewritten to `_d_newitemT' during the + semantic phase. */ + gcc_assert (e->lowering); + /* Generate: _d_newitemT() */ - libcall_fn libcall = htype->isZeroInit () - ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; - tree arg = build_typeinfo (e, e->newtype); - new_call = build_libcall (libcall, tb, 1, arg); + new_call = build_expr (e->lowering); if (e->member || !e->arguments) { @@ -2423,11 +2424,12 @@ public: return; } - libcall_fn libcall = tpointer->next->isZeroInit (e->loc) - ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; + /* This case should have been rewritten to `_d_newitemT' during the + semantic phase. */ + gcc_assert (e->lowering); - tree arg = build_typeinfo (e, e->newtype); - result = build_libcall (libcall, tb, 1, arg); + /* Generate: _d_newitemT() */ + result = build_expr (e->lowering); if (e->arguments && e->arguments->length == 1) { diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def index fd83cc9..4d1ba09 100644 --- a/gcc/d/runtime.def +++ b/gcc/d/runtime.def @@ -70,11 +70,6 @@ DEF_D_RUNTIME (DYNAMIC_CAST, "_d_dynamic_cast", RT(OBJECT), DEF_D_RUNTIME (INTERFACE_CAST, "_d_interface_cast", RT(OBJECT), P2(OBJECT, CLASSINFO), 0) -/* Used when calling new on a pointer. The `i' variant is for when the - initializer is nonzero. */ -DEF_D_RUNTIME (NEWITEMT, "_d_newitemT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0) -DEF_D_RUNTIME (NEWITEMIT, "_d_newitemiT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0) - /* Used when calling new on an array. The `i' variant is for when the initializer is nonzero, and the `m' variant is when initializing a multi-dimensional array. */ diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc index 8bd6eb6..db6f71b 100644 --- a/gcc/d/toir.cc +++ b/gcc/d/toir.cc @@ -780,8 +780,8 @@ public: this->do_label (label); - if (this->is_return_label (s->ident) && this->func_->fensure != NULL) - this->build_stmt (this->func_->fensure); + if (this->is_return_label (s->ident) && this->func_->fensure () != NULL) + this->build_stmt (this->func_->fensure ()); else if (s->statement) this->build_stmt (s->statement); } diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc index 1c5e50c..bf17438 100644 --- a/gcc/d/typeinfo.cc +++ b/gcc/d/typeinfo.cc @@ -1421,7 +1421,7 @@ check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr) /* If TypeInfo has not been declared, warn about each location once. */ static Loc warnloc; - if (loc.filename && !warnloc.equals (loc)) + if (loc.filename () && !warnloc.equals (loc)) { error_at (make_location_t (loc), "%<object.TypeInfo%> could not be found, " diff --git a/gcc/testsuite/gdc.dg/asm4.d b/gcc/testsuite/gdc.dg/asm4.d index e243c08..db857af 100644 --- a/gcc/testsuite/gdc.dg/asm4.d +++ b/gcc/testsuite/gdc.dg/asm4.d @@ -6,7 +6,7 @@ module asm4; void test1() { asm pure nothrow @nogc @trusted {} - asm @safe {} + asm @system {} } void test2() pure nothrow @nogc @safe diff --git a/gcc/testsuite/gdc.test/compilable/aliasdecl.d b/gcc/testsuite/gdc.test/compilable/aliasdecl.d index 5bacbc6..74a674d 100644 --- a/gcc/testsuite/gdc.test/compilable/aliasdecl.d +++ b/gcc/testsuite/gdc.test/compilable/aliasdecl.d @@ -36,12 +36,12 @@ void main() enum a = 1; } - /+ struct S + struct S2 { int value; alias this = value; } - auto s = S(10); + auto s = S2(10); int n = s; - assert(n == 10); +/ + assert(n == 10); } diff --git a/gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d b/gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d new file mode 100644 index 0000000..0d8cd74 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/atomic_store_2_shared_classes.d @@ -0,0 +1,13 @@ +// REQUIRED_ARGS: -preview=nosharedaccess +import core.atomic; + +class Foo +{ +} + +void oops() +{ + auto f0 = new shared Foo; + auto f1 = new shared Foo; + atomicStore(f0, f1); +} diff --git a/gcc/testsuite/gdc.test/compilable/imports/library.c b/gcc/testsuite/gdc.test/compilable/imports/library.c new file mode 100644 index 0000000..4951e46 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/library.c @@ -0,0 +1,5 @@ +typedef enum SomeEnum +{ + foo = 0, + bar = -10000, +} SomeEnum; diff --git a/gcc/testsuite/gdc.test/compilable/noreturn3.d b/gcc/testsuite/gdc.test/compilable/noreturn3.d index 69689d2..2538a0d 100644 --- a/gcc/testsuite/gdc.test/compilable/noreturn3.d +++ b/gcc/testsuite/gdc.test/compilable/noreturn3.d @@ -91,8 +91,8 @@ auto ref forwardOrExit(ref int num) static assert( is(typeof(forwardOrExit(global)) == int)); -// // Must not infer ref due to the noreturn rvalue -static assert(!is(typeof(&forwardOrExit(global)))); +// Noreturn types do not affect `auto ref` deduction +static assert(is(typeof(&forwardOrExit(global)))); auto ref forwardOrExit2(ref int num) { @@ -104,8 +104,8 @@ auto ref forwardOrExit2(ref int num) static assert( is(typeof(forwardOrExit2(global)) == int)); -// // Must not infer ref due to the noreturn rvalue -static assert(!is(typeof(&forwardOrExit2(global)))); +// Noreturn types do not affect `auto ref` deduction +static assert(is(typeof(&forwardOrExit2(global)))); /*****************************************************************************/ diff --git a/gcc/testsuite/gdc.test/compilable/test22760.d b/gcc/testsuite/gdc.test/compilable/test22760.d new file mode 100644 index 0000000..5957db3 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22760.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=22760 + +extern(C++) void f(T)(T) +{ +} +struct S1(T) +{ + struct S2 + { + } +} +void fun() +{ + f(S1!int.S2()); +} diff --git a/gcc/testsuite/gdc.test/compilable/test23874.d b/gcc/testsuite/gdc.test/compilable/test23874.d new file mode 100644 index 0000000..81ee9d5 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23874.d @@ -0,0 +1,10 @@ +// https://issues.dlang.org/show_bug.cgi?id=23874 +// REQUIRED_ARGS: -profile=gc + +string myToString() +{ + return ""; +} + +enum x = myToString ~ ""; +immutable x2 = myToString ~ ""; diff --git a/gcc/testsuite/gdc.test/compilable/test23912.d b/gcc/testsuite/gdc.test/compilable/test23912.d new file mode 100644 index 0000000..d89d302 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23912.d @@ -0,0 +1,17 @@ +// https://issues.dlang.org/show_bug.cgi?id=23912 +// REQUIRED_ARGS: -preview=dip1000 + +struct Test +{ + string val; + + this(return scope string val) scope @safe {} + ~this() scope @safe {} +} + +void giver(scope string input) @safe +{ + accepts(Test(input)); +} + +void accepts(scope Test test) @safe {} diff --git a/gcc/testsuite/gdc.test/compilable/test23913.d b/gcc/testsuite/gdc.test/compilable/test23913.d new file mode 100644 index 0000000..e39c6de --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23913.d @@ -0,0 +1,7 @@ +// EXTRA_FILES: imports/library.c + +// https://issues.dlang.org/show_bug.cgi?id=23913 + +import imports.library; + +alias x = __traits(getMember, imports.library, "SomeEnum"); diff --git a/gcc/testsuite/gdc.test/compilable/test23948.d b/gcc/testsuite/gdc.test/compilable/test23948.d new file mode 100644 index 0000000..4f7b8da0 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23948.d @@ -0,0 +1,29 @@ +// https://issues.dlang.org/show_bug.cgi?id=23948 + +void foo1(const(char)* fun = __FILE__)() { + +} + +void foo2(const(char)* fun = __FILE_FULL_PATH__)() { + +} + +void foo3(const(char)* fun = __MODULE__)() { + +} + +void foo4(const(char)* fun = __FUNCTION__)() { + +} + +void foo5(const(char)* fun = __PRETTY_FUNCTION__)() { + +} + +void main() { + foo1(); + foo2(); + foo3(); + foo4(); + foo5(); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d index 802d1c2..f0a9456 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d +++ b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d @@ -91,9 +91,9 @@ TEST_OUTPUT: --- fail_compilation/bug9631.d(106): Error: function `bug9631.targ.ft!().ft(S __param_0)` is not callable using argument types `(S)` fail_compilation/bug9631.d(106): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S __param_0` -fail_compilation/bug9631.d(107): Error: none of the overloads of template `bug9631.targ.ft` are callable using argument types `!()(S)` +fail_compilation/bug9631.d(107): Error: template `bug9631.targ.ft` is not callable using argument types `!()(S)` fail_compilation/bug9631.d(105): Candidate is: `ft()(tem!().S)` -fail_compilation/bug9631.d(109): Error: none of the overloads of template `bug9631.targ.ft2` are callable using argument types `!()(S, int)` +fail_compilation/bug9631.d(109): Error: template `bug9631.targ.ft2` is not callable using argument types `!()(S, int)` fail_compilation/bug9631.d(108): Candidate is: `ft2(T)(S, T)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/chkformat.d b/gcc/testsuite/gdc.test/fail_compilation/chkformat.d index fa8915e..eb75f42 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/chkformat.d +++ b/gcc/testsuite/gdc.test/fail_compilation/chkformat.d @@ -19,7 +19,11 @@ fail_compilation/chkformat.d(115): Deprecation: argument `& u` for format specif fail_compilation/chkformat.d(116): Deprecation: argument `16L` for format specification `"%c"` must be `char`, not `long` fail_compilation/chkformat.d(117): Deprecation: argument `17L` for format specification `"%c"` must be `char`, not `long` fail_compilation/chkformat.d(118): Deprecation: argument `& u` for format specification `"%s"` must be `char*`, not `int*` -fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*` +fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`$?:windows= +fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong` +fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system|32= +fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong` +fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system$ fail_compilation/chkformat.d(201): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long` fail_compilation/chkformat.d(202): Deprecation: more format specifiers than 1 arguments fail_compilation/chkformat.d(203): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long` @@ -81,6 +85,7 @@ void test18() { int u; printf("%s\n", &u); } void test19() { int u; printf("%ls\n", &u); } //void test20() { int u; char[] s; sprintf(&s[0], "%d\n", &u); } //void test21() { int u; fprintf(null, "%d\n", &u); } +void test20() { printf("%lu", ulong.init); } #line 200 diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d index 9f12ae6..a3ad34a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d @@ -2,12 +2,12 @@ EXTRA_FILES: imports/constraints.d TEST_OUTPUT: --- -fail_compilation/constraints_aggr.d(32): Error: none of the overloads of template `imports.constraints.C.f` are callable using argument types `!()(int)` +fail_compilation/constraints_aggr.d(32): Error: template `imports.constraints.C.f` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(60): Candidate is: `f(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_aggr.d(33): Error: none of the overloads of template `imports.constraints.C.g` are callable using argument types `!()()` +fail_compilation/constraints_aggr.d(33): Error: template `imports.constraints.C.g` is not callable using argument types `!()()` fail_compilation/imports/constraints.d(63): Candidate is: `g(this T)()` with `T = imports.constraints.C` must satisfy the following constraint: diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d index aac8760..fbb4aa9 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d @@ -2,72 +2,72 @@ EXTRA_FILES: imports/constraints.d TEST_OUTPUT: --- -fail_compilation/constraints_func1.d(79): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(79): Error: template `imports.constraints.test1` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func1.d(80): Error: none of the overloads of template `imports.constraints.test2` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(80): Error: template `imports.constraints.test2` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(10): Candidate is: `test2(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_func1.d(81): Error: none of the overloads of template `imports.constraints.test3` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(81): Error: template `imports.constraints.test3` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(11): Candidate is: `test3(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func1.d(82): Error: none of the overloads of template `imports.constraints.test4` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(82): Error: template `imports.constraints.test4` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(12): Candidate is: `test4(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func1.d(83): Error: none of the overloads of template `imports.constraints.test5` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(83): Error: template `imports.constraints.test5` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(13): Candidate is: `test5(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func1.d(84): Error: none of the overloads of template `imports.constraints.test6` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(84): Error: template `imports.constraints.test6` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(14): Candidate is: `test6(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T !P!T` -fail_compilation/constraints_func1.d(85): Error: none of the overloads of template `imports.constraints.test7` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(85): Error: template `imports.constraints.test7` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(15): Candidate is: `test7(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func1.d(86): Error: none of the overloads of template `imports.constraints.test8` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(86): Error: template `imports.constraints.test8` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(16): Candidate is: `test8(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func1.d(87): Error: none of the overloads of template `imports.constraints.test9` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(87): Error: template `imports.constraints.test9` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(17): Candidate is: `test9(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_func1.d(88): Error: none of the overloads of template `imports.constraints.test10` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(88): Error: template `imports.constraints.test10` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(18): Candidate is: `test10(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_func1.d(89): Error: none of the overloads of template `imports.constraints.test11` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(89): Error: template `imports.constraints.test11` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(19): Candidate is: `test11(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T !P!T` -fail_compilation/constraints_func1.d(90): Error: none of the overloads of template `imports.constraints.test12` are callable using argument types `!()(int)` +fail_compilation/constraints_func1.d(90): Error: template `imports.constraints.test12` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(20): Candidate is: `test12(T)(T v)` with `T = int` must satisfy the following constraint: ` !P!T` -fail_compilation/constraints_func1.d(92): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int, int)` +fail_compilation/constraints_func1.d(92): Error: template `imports.constraints.test1` is not callable using argument types `!()(int, int)` fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d index a20426d..4b8ebd5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d @@ -2,83 +2,83 @@ EXTRA_FILES: imports/constraints.d TEST_OUTPUT: --- -fail_compilation/constraints_func2.d(94): Error: none of the overloads of template `imports.constraints.test13` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(94): Error: template `imports.constraints.test13` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(23): Candidate is: `test13(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T !P!T` -fail_compilation/constraints_func2.d(95): Error: none of the overloads of template `imports.constraints.test14` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(95): Error: template `imports.constraints.test14` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(24): Candidate is: `test14(T)(T v)` with `T = int` must satisfy one of the following constraints: ` !P!T N!T` -fail_compilation/constraints_func2.d(96): Error: none of the overloads of template `imports.constraints.test15` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(96): Error: template `imports.constraints.test15` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(25): Candidate is: `test15(T)(T v)` with `T = int` must satisfy one of the following constraints: ` !P!T !P!T` -fail_compilation/constraints_func2.d(97): Error: none of the overloads of template `imports.constraints.test16` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(97): Error: template `imports.constraints.test16` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(26): Candidate is: `test16(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func2.d(98): Error: none of the overloads of template `imports.constraints.test17` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(98): Error: template `imports.constraints.test17` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(27): Candidate is: `test17(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func2.d(99): Error: none of the overloads of template `imports.constraints.test18` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(99): Error: template `imports.constraints.test18` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(28): Candidate is: `test18(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func2.d(100): Error: none of the overloads of template `imports.constraints.test19` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(100): Error: template `imports.constraints.test19` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(29): Candidate is: `test19(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T !P!T N!T` -fail_compilation/constraints_func2.d(101): Error: none of the overloads of template `imports.constraints.test20` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(101): Error: template `imports.constraints.test20` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(30): Candidate is: `test20(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func2.d(102): Error: none of the overloads of template `imports.constraints.test21` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(102): Error: template `imports.constraints.test21` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(31): Candidate is: `test21(T)(T v)` with `T = int` must satisfy one of the following constraints: ` N!T N!T` -fail_compilation/constraints_func2.d(103): Error: none of the overloads of template `imports.constraints.test22` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(103): Error: template `imports.constraints.test22` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(32): Candidate is: `test22(T)(T v)` with `T = int` must satisfy one of the following constraints: ` !P!T !P!T` -fail_compilation/constraints_func2.d(104): Error: none of the overloads of template `imports.constraints.test23` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(104): Error: template `imports.constraints.test23` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(33): Candidate is: `test23(T)(T v)` with `T = int` must satisfy one of the following constraints: ` !P!T N!T !P!T` -fail_compilation/constraints_func2.d(105): Error: none of the overloads of template `imports.constraints.test24` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(105): Error: template `imports.constraints.test24` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(34): Candidate is: `test24(R)(R r)` with `R = int` must satisfy the following constraint: ` __traits(hasMember, R, "stuff")` -fail_compilation/constraints_func2.d(106): Error: none of the overloads of template `imports.constraints.test25` are callable using argument types `!()(int)` +fail_compilation/constraints_func2.d(106): Error: template `imports.constraints.test25` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(35): Candidate is: `test25(T)(T v)` with `T = int` must satisfy the following constraint: ` N!T` -fail_compilation/constraints_func2.d(107): Error: none of the overloads of template `imports.constraints.test26` are callable using argument types `!(float)(int)` +fail_compilation/constraints_func2.d(107): Error: template `imports.constraints.test26` is not callable using argument types `!(float)(int)` fail_compilation/imports/constraints.d(36): Candidate is: `test26(T, U)(U u)` with `T = float, U = int` diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d index 6f214b9..d16bdf0 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d @@ -23,21 +23,21 @@ fail_compilation/imports/constraints.d(42): `overload(T, must satisfy one of the following constraints: ` N!T N!V` -fail_compilation/constraints_func3.d(56): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()` +fail_compilation/constraints_func3.d(56): Error: template `imports.constraints.variadic` is not callable using argument types `!()()` fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` -fail_compilation/constraints_func3.d(57): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)` +fail_compilation/constraints_func3.d(57): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)` fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` with `A = int, T = ()` must satisfy the following constraint: ` N!int` -fail_compilation/constraints_func3.d(58): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)` +fail_compilation/constraints_func3.d(58): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)` fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` with `A = int, T = (int)` must satisfy the following constraint: ` N!int` -fail_compilation/constraints_func3.d(59): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)` +fail_compilation/constraints_func3.d(59): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)` fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` with `A = int, T = (int, int)` diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d index 4048bae..c4dea0e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d +++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d @@ -44,13 +44,13 @@ fail_compilation/imports/constraints.d(42): `overload(T, N!V` void overload(T, V)(T v1, V v2) if (N!T || N!V); ^ -fail_compilation/constraints_func4.d(93): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()` +fail_compilation/constraints_func4.d(93): Error: template `imports.constraints.variadic` is not callable using argument types `!()()` variadic(); ^ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` void variadic(A, T...)(A a, T v) if (N!int); ^ -fail_compilation/constraints_func4.d(94): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)` +fail_compilation/constraints_func4.d(94): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)` variadic(0); ^ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` @@ -60,7 +60,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T. ` N!int` void variadic(A, T...)(A a, T v) if (N!int); ^ -fail_compilation/constraints_func4.d(95): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)` +fail_compilation/constraints_func4.d(95): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)` variadic(0, 1); ^ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` @@ -70,7 +70,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T. ` N!int` void variadic(A, T...)(A a, T v) if (N!int); ^ -fail_compilation/constraints_func4.d(96): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)` +fail_compilation/constraints_func4.d(96): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)` variadic(0, 1, 2); ^ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)` diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag13942.d b/gcc/testsuite/gdc.test/fail_compilation/diag13942.d index aeee107..25e0515 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag13942.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag13942.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/diag13942.d(18): Error: template instance `isRawStaticArray!()` does not match template declaration `isRawStaticArray(T, A...)` -fail_compilation/diag13942.d(26): Error: none of the overloads of template `diag13942.to!double.to` are callable using argument types `!()()` +fail_compilation/diag13942.d(26): Error: template `diag13942.to!double.to` is not callable using argument types `!()()` fail_compilation/diag13942.d(17): Candidate is: `to(A...)(A args)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16977.d b/gcc/testsuite/gdc.test/fail_compilation/diag16977.d index 73d6285..fc8f660 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag16977.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag16977.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/diag16977.d(25): Error: undefined identifier `undefined`, did you mean function `undefinedId`? fail_compilation/diag16977.d(26): Error: cannot implicitly convert expression `"\x01string"` of type `string` to `int` -fail_compilation/diag16977.d(27): Error: none of the overloads of template `diag16977.templ` are callable using argument types `!()(int)` +fail_compilation/diag16977.d(27): Error: template `diag16977.templ` is not callable using argument types `!()(int)` fail_compilation/diag16977.d(20): Candidate is: `templ(S)(S s)` with `S = int` must satisfy the following constraint: diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag20268.d b/gcc/testsuite/gdc.test/fail_compilation/diag20268.d index a314561..053626a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag20268.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag20268.d @@ -3,7 +3,7 @@ /* TEST_OUTPUT: --- -fail_compilation/diag20268.d(12): Error: none of the overloads of template `diag20268.__lambda4` are callable using argument types `!()(int)` +fail_compilation/diag20268.d(12): Error: template `diag20268.__lambda4` is not callable using argument types `!()(int)` fail_compilation/diag20268.d(11): Candidate is: `__lambda4(__T1, __T2)(x, y)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag23355.d b/gcc/testsuite/gdc.test/fail_compilation/diag23355.d index 586cbb0..a530eb6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag23355.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag23355.d @@ -2,10 +2,10 @@ TEST_OUTPUT: --- fail_compilation/diag23355.d(1): Error: undefined identifier `n` -fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi1` are callable using argument types `!()(int[4])` +fail_compilation/diag23355.d(4): Error: template `diag23355.ffi1` is not callable using argument types `!()(int[4])` fail_compilation/diag23355.d(1): Candidate is: `ffi1(T)(T[n] s)` fail_compilation/diag23355.d(2): Error: undefined identifier `n` -fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi2` are callable using argument types `!()(int[4])` +fail_compilation/diag23355.d(4): Error: template `diag23355.ffi2` is not callable using argument types `!()(int[4])` fail_compilation/diag23355.d(2): Candidate is: `ffi2()(T[n] s)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d index ddc74e2..4c8dfe8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d @@ -14,7 +14,7 @@ fail_compilation/diag8101.d(41): `diag8101.f_2(int, int, fail_compilation/diag8101.d(42): `diag8101.f_2(int, int, int, int, int)` fail_compilation/diag8101.d(43): `diag8101.f_2(int, int, int, int, int, int)` fail_compilation/diag8101.d(63): ... (1 more, -v to show) ... -fail_compilation/diag8101.d(65): Error: none of the overloads of template `diag8101.t_0` are callable using argument types `!()()` +fail_compilation/diag8101.d(65): Error: template `diag8101.t_0` is not callable using argument types `!()()` fail_compilation/diag8101.d(46): Candidate is: `t_0(T1)()` fail_compilation/diag8101.d(66): Error: none of the overloads of template `diag8101.t_1` are callable using argument types `!()()` fail_compilation/diag8101.d(48): Candidates are: `t_1(T1)()` diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8648.d b/gcc/testsuite/gdc.test/fail_compilation/diag8648.d index a04ed7c..e48f569 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag8648.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag8648.d @@ -2,13 +2,13 @@ TEST_OUTPUT: --- fail_compilation/diag8648.d(18): Error: undefined identifier `X` -fail_compilation/diag8648.d(29): Error: none of the overloads of template `diag8648.foo` are callable using argument types `!()(Foo!(int, 1))` +fail_compilation/diag8648.d(29): Error: template `diag8648.foo` is not callable using argument types `!()(Foo!(int, 1))` fail_compilation/diag8648.d(18): Candidate is: `foo(T, n)(X!(T, n))` fail_compilation/diag8648.d(20): Error: undefined identifier `a` -fail_compilation/diag8648.d(31): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, 1))` +fail_compilation/diag8648.d(31): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, 1))` fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))` fail_compilation/diag8648.d(20): Error: undefined identifier `a` -fail_compilation/diag8648.d(32): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, f))` +fail_compilation/diag8648.d(32): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, f))` fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9004.d b/gcc/testsuite/gdc.test/fail_compilation/diag9004.d index 37d5bd8..30589bf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag9004.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag9004.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/diag9004.d(21): Error: none of the overloads of template `diag9004.bar` are callable using argument types `!()(Foo!int, int)` +fail_compilation/diag9004.d(21): Error: template `diag9004.bar` is not callable using argument types `!()(Foo!int, int)` fail_compilation/diag9004.d(14): Candidate is: `bar(FooT)(FooT foo, FooT.T x)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9574.d b/gcc/testsuite/gdc.test/fail_compilation/diag9574.d deleted file mode 100644 index b280b3b..0000000 --- a/gcc/testsuite/gdc.test/fail_compilation/diag9574.d +++ /dev/null @@ -1,19 +0,0 @@ -/* -TEST_OUTPUT: ---- -fail_compilation/diag9574.d(12): Error: cannot use syntax `alias this = x`, use `alias x this` instead -fail_compilation/diag9574.d(18): Error: cannot use syntax `alias this = x`, use `alias x this` instead ---- -*/ - -struct S -{ - int x; - alias this = x; -} - -class C -{ - int x; - alias this = x; -} diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d b/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d index bbfb5a0..151bb42 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag_template_alias.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/diag_template_alias.d(1): Error: identifier expected for template `alias` parameter fail_compilation/diag_template_alias.d(1): Error: found `alias` when expecting `(` -fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration +fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration, not `(` fail_compilation/diag_template_alias.d(1): Error: declaration expected, not `(` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d b/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d index 778f68e..25de03c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag_template_this.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/diag_template_this.d(1): Error: identifier expected for template `this` parameter fail_compilation/diag_template_this.d(1): Error: found `this` when expecting `(` -fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration +fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration, not `(` fail_compilation/diag_template_this.d(1): Error: declaration expected, not `(` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/diagin.d b/gcc/testsuite/gdc.test/fail_compilation/diagin.d index 0d1f8f1..1748e92 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diagin.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diagin.d @@ -4,7 +4,7 @@ TEST_OUTPUT: --- fail_compilation/diagin.d(14): Error: function `diagin.foo(in int)` is not callable using argument types `()` fail_compilation/diagin.d(14): too few arguments, expected 1, got 0 -fail_compilation/diagin.d(16): Error: none of the overloads of template `diagin.foo1` are callable using argument types `!()(bool[])` +fail_compilation/diagin.d(16): Error: template `diagin.foo1` is not callable using argument types `!()(bool[])` fail_compilation/diagin.d(20): Candidate is: `foo1(T)(in T v, string)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d index fe7d546..0ac7229 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d +++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d @@ -21,7 +21,7 @@ __error__ } } )` -fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration +fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration, not `End of File` --- */ d(={for diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12744.d b/gcc/testsuite/gdc.test/fail_compilation/fail12744.d index 2056c0e..711e57f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail12744.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail12744.d @@ -14,10 +14,10 @@ fail_compilation/fail12744.d(61): Error: template instance `fail12744.bar12744L! fail_compilation/fail12744.d(40): Error: incompatible parameter storage classes `lazy` and `out` fail_compilation/fail12744.d(62): Error: template instance `fail12744.bar12744L!(foo12744O)` error instantiating fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `out` -fail_compilation/fail12744.d(67): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744O)(int)` +fail_compilation/fail12744.d(67): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744O)(int)` fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)` fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `lazy` -fail_compilation/fail12744.d(68): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744L)(int)` +fail_compilation/fail12744.d(68): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744L)(int)` fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail14669.d b/gcc/testsuite/gdc.test/fail_compilation/fail14669.d index 5621ecc..45fe146 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail14669.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail14669.d @@ -4,7 +4,7 @@ TEST_OUTPUT: fail_compilation/fail14669.d(11): Error: `auto` can only be used as part of `auto ref` for template function parameters fail_compilation/fail14669.d(16): Error: template instance `fail14669.foo1!()` error instantiating fail_compilation/fail14669.d(12): Error: `auto` can only be used as part of `auto ref` for template function parameters -fail_compilation/fail14669.d(17): Error: none of the overloads of template `fail14669.foo2` are callable using argument types `!()(int)` +fail_compilation/fail14669.d(17): Error: template `fail14669.foo2` is not callable using argument types `!()(int)` fail_compilation/fail14669.d(12): Candidate is: `foo2()(auto int a)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15414.d b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d index 1fb6e23..ed576b5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail15414.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail15414.d @@ -5,7 +5,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `fun` +fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not the overload set `fun` fail_compilation/fail15414.d(20): the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail162.d b/gcc/testsuite/gdc.test/fail_compilation/fail162.d index a537f10..c79f8d8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail162.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail162.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail162.d(25): Error: none of the overloads of template `fail162.testHelper` are callable using argument types `!()(string, string)` +fail_compilation/fail162.d(25): Error: template `fail162.testHelper` is not callable using argument types `!()(string, string)` fail_compilation/fail162.d(10): Candidate is: `testHelper(A...)()` fail_compilation/fail162.d(30): Error: template instance `fail162.test!("hello", "world")` error instantiating --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d b/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d index 00dd9fd..d36bb0b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d @@ -3,7 +3,7 @@ REQUIRED_ARGS: -verrors=spec -o- TEST_OUTPUT: --- (spec:1) fail_compilation/fail20730b.d-mixin-43(43): Error: C style cast illegal, use `cast(int)mod` -fail_compilation/fail20730b.d(26): Error: none of the overloads of template `fail20730b.atomicOp` are callable using argument types `!("+=")(shared(uint), int)` +fail_compilation/fail20730b.d(26): Error: template `fail20730b.atomicOp` is not callable using argument types `!("+=")(shared(uint), int)` fail_compilation/fail20730b.d(41): Candidate is: `atomicOp(string op, T, V1)(shared ref T val, V1 mod)` with `op = "+=", T = uint, diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail236.d b/gcc/testsuite/gdc.test/fail_compilation/fail236.d index 626ec00..accc0e1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail236.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail236.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/fail236.d(14): Error: undefined identifier `x` -fail_compilation/fail236.d(22): Error: none of the overloads of template `fail236.Templ2` are callable using argument types `!()(int)` +fail_compilation/fail236.d(22): Error: template `fail236.Templ2` is not callable using argument types `!()(int)` fail_compilation/fail236.d(12): Candidate is: `Templ2(alias a)(x)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d b/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d index 2943f1a..559e0e2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23626a.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- fail_compilation/fail23626a.d(10): Deprecation: function `fail23626a.ambig` cannot overload `extern(D)` function at fail_compilation/fail23626a.d(9) -fail_compilation/fail23626a.d(13): Deprecation: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12) +fail_compilation/fail23626a.d(13): Error: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12) fail_compilation/fail23626a.d(16): Error: function `fail23626a.ambigCxx(int a)` conflicts with previous declaration at fail_compilation/fail23626a.d(15) --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail2456.d b/gcc/testsuite/gdc.test/fail_compilation/fail2456.d index 08e11da..5d7d6ee 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail2456.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail2456.d @@ -108,3 +108,17 @@ void test2456b() catch (Throwable) {} // NG } } + +/* +TEST_OUTPUT: +--- +fail_compilation/fail2456.d(121): Deprecation: can only catch mutable or const qualified types, not `immutable(Exception)` +--- +*/ +void main() { + try { + throw new Exception(""); + } catch (immutable Exception e) { + assert(0); + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail2789.d b/gcc/testsuite/gdc.test/fail_compilation/fail2789.d index 2d6c8e2..261e412 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail2789.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail2789.d @@ -61,8 +61,8 @@ auto f6() { return ""; } // string(), conflict TEST_OUTPUT: --- fail_compilation/fail2789.d(67): Error: function `fail2789.f_ExternC1()` conflicts with previous declaration at fail_compilation/fail2789.d(66) -fail_compilation/fail2789.d(70): Deprecation: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69) -fail_compilation/fail2789.d(73): Deprecation: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72) +fail_compilation/fail2789.d(70): Error: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69) +fail_compilation/fail2789.d(73): Error: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72) --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d index 96489d9..a4844bf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail8009.d(9): Error: none of the overloads of template `fail8009.filter` are callable using argument types `!()(void)` +fail_compilation/fail8009.d(9): Error: template `fail8009.filter` is not callable using argument types `!()(void)` fail_compilation/fail8009.d(8): Candidate is: `filter(R)(scope bool delegate(ref BAD!R) func)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail95.d b/gcc/testsuite/gdc.test/fail_compilation/fail95.d index a1b3906..7065bc1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail95.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail95.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail95.d(19): Error: none of the overloads of template `fail95.A` are callable using argument types `!()(int)` +fail_compilation/fail95.d(19): Error: template `fail95.A` is not callable using argument types `!()(int)` fail_compilation/fail95.d(11): Candidate is: `A(alias T)(T)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d index 6612a67..9ba2970 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d +++ b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d @@ -4,8 +4,8 @@ fail_compilation/failcontracts.d(18): Error: missing `{ ... }` for function lite fail_compilation/failcontracts.d(18): Error: semicolon expected following auto declaration, not `bode` fail_compilation/failcontracts.d(19): Error: function declaration without return type. (Note that constructors are always named `this`) fail_compilation/failcontracts.d(19): Error: no identifier for declarator `test1()` -fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration -fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration +fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration, not `bode` +fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration, not `bode` fail_compilation/failcontracts.d(22): Error: unexpected `(` in declarator fail_compilation/failcontracts.d(22): Error: found `T` when expecting `)` fail_compilation/failcontracts.d(22): Error: enum declaration is invalid diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d b/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d index 24e39da..448e629 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d @@ -1,8 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/ice11856_1.d(16): Error: none of the overloads of template `ice11856_1.g` are callable using argument types `!()(A)` -fail_compilation/ice11856_1.d(14): Candidate is: `g(T)(T x)` +fail_compilation/ice11856_1.d(18): Error: no property `g` for `A()` of type `A` +fail_compilation/ice11856_1.d(18): the following error occured while looking for a UFCS match +fail_compilation/ice11856_1.d(18): Error: template `ice11856_1.g` is not callable using argument types `!()(A)` +fail_compilation/ice11856_1.d(16): Candidate is: `g(T)(T x)` with `T = A` must satisfy the following constraint: ` is(typeof(x.f()))` diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice14130.d b/gcc/testsuite/gdc.test/fail_compilation/ice14130.d index c64fb84..151bf17 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice14130.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice14130.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/ice14130.d(10): Error: undefined identifier `Undef` -fail_compilation/ice14130.d(14): Error: none of the overloads of template `ice14130.foo` are callable using argument types `!()(int)` +fail_compilation/ice14130.d(14): Error: template `ice14130.foo` is not callable using argument types `!()(int)` fail_compilation/ice14130.d(10): Candidate is: `foo(R, F = Undef)(R r, F s = 0)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice14907.d b/gcc/testsuite/gdc.test/fail_compilation/ice14907.d index e1d7aac..5d676cd 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice14907.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice14907.d @@ -6,7 +6,7 @@ fail_compilation/ice14907.d(19): while looking for match for `S!()` fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion fail_compilation/ice14907.d(20): while looking for match for `f!()` fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion -fail_compilation/ice14907.d(21): Error: none of the overloads of template `ice14907.f` are callable using argument types `!()()` +fail_compilation/ice14907.d(21): Error: template `ice14907.f` is not callable using argument types `!()()` fail_compilation/ice14907.d(15): Candidate is: `f(int v = f)()` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d index 1c6cf4b..af7c554 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d @@ -7,7 +7,7 @@ TEST_OUTPUT: --- fail_compilation/ice6538.d(23): Error: expression `super` is not a valid template value argument -fail_compilation/ice6538.d(28): Error: none of the overloads of template `ice6538.D.foo` are callable using argument types `!()()` +fail_compilation/ice6538.d(28): Error: template `ice6538.D.foo` is not callable using argument types `!()()` fail_compilation/ice6538.d(23): Candidate is: `foo()()` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d index 00602d2..47fd44c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/ice9284.d(14): Error: none of the overloads of template `ice9284.C.__ctor` are callable using argument types `!()(int)` +fail_compilation/ice9284.d(14): Error: template `ice9284.C.__ctor` is not callable using argument types `!()(int)` fail_compilation/ice9284.d(12): Candidate is: `__ctor()(string)` fail_compilation/ice9284.d(20): Error: template instance `ice9284.C.__ctor!()` error instantiating --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d b/gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d new file mode 100644 index 0000000..39334cf --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/import23873.d @@ -0,0 +1,2 @@ +static if ; +else auto x diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d new file mode 100644 index 0000000..4c369e3 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908a.d @@ -0,0 +1,3 @@ +module imports.spell23908a; + +import imports.spell23908b : nonexistent; diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d new file mode 100644 index 0000000..316b4fe --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/spell23908b.d @@ -0,0 +1,3 @@ +module imports.spell23908b; + +import imports.spell23908a; diff --git a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d index 0900e60..5129f30 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d +++ b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d @@ -15,7 +15,7 @@ fail_compilation/named_arguments_error.d(38): Error: no named argument `element` fail_compilation/named_arguments_error.d(39): Error: no named argument `number` allowed for scalar fail_compilation/named_arguments_error.d(40): Error: cannot implicitly convert expression `g(x: 3, y: 4, z: 5)` of type `int` to `string` fail_compilation/named_arguments_error.d(41): Error: named arguments with Implicit Function Template Instantiation are not supported yet -fail_compilation/named_arguments_error.d(41): Error: none of the overloads of template `named_arguments_error.tempfun` are callable using argument types `!()(string, int)` +fail_compilation/named_arguments_error.d(41): Error: template `named_arguments_error.tempfun` is not callable using argument types `!()(string, int)` fail_compilation/named_arguments_error.d(45): Candidate is: `tempfun(T, U)(T t, U u)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d index 7bc5e96..50cfdd3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d @@ -403,7 +403,7 @@ class Foo13 /* TEST_OUTPUT: --- -fail_compilation/retscope.d(1205): Error: scope variable `f14` assigned to non-scope parameter `this` calling `foo` +fail_compilation/retscope.d(1205): Error: scope variable `f14` calling non-scope member function `f14.foo()` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/spell23908.d b/gcc/testsuite/gdc.test/fail_compilation/spell23908.d new file mode 100644 index 0000000..a7501e1 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/spell23908.d @@ -0,0 +1,11 @@ +/* +EXTRA_FILES: imports/spell23908a.d imports/spell23908b.d +TEST_OUTPUT: +--- +fail_compilation/imports/spell23908a.d(3): Error: module `imports.spell23908b` import `nonexistent` not found +--- +*/ + +// https://issues.dlang.org/show_bug.cgi?id=23908 + +import imports.spell23908a; diff --git a/gcc/testsuite/gdc.test/fail_compilation/static_import.d b/gcc/testsuite/gdc.test/fail_compilation/static_import.d new file mode 100644 index 0000000..24b7bc1 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/static_import.d @@ -0,0 +1,8 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/static_import.d(8): Error: static import `core` cannot have an import bind list +--- +*/ + +static import core.stdc.stdio : p = q; diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18385.d b/gcc/testsuite/gdc.test/fail_compilation/test18385.d index 3f87885..2e48192 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test18385.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test18385.d @@ -2,7 +2,7 @@ REQUIRED_ARGS: -de TEST_OUTPUT: --- -fail_compilation/test18385.d(13): Deprecation: function `test18385.foo` cannot overload `extern(C)` function at fail_compilation/test18385.d(12) +fail_compilation/test18385.d(13): Error: function `test18385.foo` cannot overload `extern(C)` function at fail_compilation/test18385.d(12) --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test19107.d b/gcc/testsuite/gdc.test/fail_compilation/test19107.d index 93d86bf..c802122 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test19107.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test19107.d @@ -2,7 +2,7 @@ EXTRA_FILES: imports/imp19661.d imports/test19107a.d imports/test19107b.d TEST_OUTPUT: --- -fail_compilation/test19107.d(24): Error: none of the overloads of template `test19107.all` are callable using argument types `!((c) => c)(string[])` +fail_compilation/test19107.d(24): Error: template `test19107.all` is not callable using argument types `!((c) => c)(string[])` fail_compilation/test19107.d(18): Candidate is: `all(alias pred, T)(T t)` with `pred = __lambda2, T = string[]` diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20245.d b/gcc/testsuite/gdc.test/fail_compilation/test20245.d index 98caa03..3c43c5c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test20245.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test20245.d @@ -9,7 +9,7 @@ fail_compilation/test20245.d(27): Error: cannot take address of `scope` variable fail_compilation/test20245.d(33): Error: reference to local variable `x` assigned to non-scope parameter `ptr` calling `escape` fail_compilation/test20245.d(34): Error: copying `&x` into allocated memory escapes a reference to parameter `x` fail_compilation/test20245.d(50): Error: reference to local variable `price` assigned to non-scope `this.minPrice` -fail_compilation/test20245.d(69): Error: reference to local variable `this` assigned to non-scope parameter `msg` calling `this` +fail_compilation/test20245.d(69): Error: reference to local variable `this` calling non-scope member function `this.this()` fail_compilation/test20245.d(89): Error: reference to local variable `this` assigned to non-scope parameter `content` calling `listUp` fail_compilation/test20245.d(82): which is not `scope` because of `charPtr = content` --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23873.d b/gcc/testsuite/gdc.test/fail_compilation/test23873.d new file mode 100644 index 0000000..bb6a71d --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23873.d @@ -0,0 +1,14 @@ +// https://issues.dlang.org/show_bug.cgi?id=23873 + +/* +TEST_OUTPUT: +--- +fail_compilation/imports/import23873.d(1): Error: (expression) expected following `static if` +fail_compilation/imports/import23873.d(1): Error: declaration expected following attribute, not `;` +fail_compilation/imports/import23873.d(3): Error: no identifier for declarator `x` +--- +*/ +struct Foo +{ + import imports.import23873; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23882.d b/gcc/testsuite/gdc.test/fail_compilation/test23882.d new file mode 100644 index 0000000..f6b57c4 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23882.d @@ -0,0 +1,37 @@ +// https://issues.dlang.org/show_bug.cgi?id=23882 + +/* +TEST_OUTPUT: +--- +fail_compilation/test23882.d(26): Error: `typeof((*YC).S).init` is used as a type +--- +*/ + +struct G(H) +{ + Tuple!(R) S; +} + +struct BB(H) +{ + H* YC; + alias YC this; +} + +struct R +{ + BB!(G!float) CB; + alias CB this; + + this(typeof(CB.S).init); +} + +struct Tuple(Specs) +{ + Specs expand; + + this(Specs values) + { + expand = values; + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23905.d b/gcc/testsuite/gdc.test/fail_compilation/test23905.d new file mode 100644 index 0000000..5b30fa8 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23905.d @@ -0,0 +1,25 @@ +// https://issues.dlang.org/show_bug.cgi?id=23905 + +/* +TEST_OUTPUT: +--- +fail_compilation/test23905.d(24): Error: enum `test23905.Foo` is opaque and has no default initializer +--- +*/ + +struct SumType(T) +{ + T storage; + + bool opEquals(Rhs)(Rhs rhs) + if (is(typeof(Rhs.init))) + { + } + +} + +enum Foo; + +void main(){ + SumType!Foo data = Foo.init; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/udaparams.d b/gcc/testsuite/gdc.test/fail_compilation/udaparams.d index 453ebba..76df55f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/udaparams.d +++ b/gcc/testsuite/gdc.test/fail_compilation/udaparams.d @@ -23,7 +23,7 @@ fail_compilation/udaparams.d(57): Error: identifier expected for template value fail_compilation/udaparams.d(57): Error: found `@` when expecting `)` fail_compilation/udaparams.d(57): Error: basic type expected, not `3` fail_compilation/udaparams.d(57): Error: found `3` when expecting `)` -fail_compilation/udaparams.d(57): Error: semicolon expected following function declaration +fail_compilation/udaparams.d(57): Error: semicolon expected following function declaration, not `)` fail_compilation/udaparams.d(57): Error: declaration expected, not `)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ufcs.d b/gcc/testsuite/gdc.test/fail_compilation/ufcs.d new file mode 100644 index 0000000..501ef81 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/ufcs.d @@ -0,0 +1,34 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/ufcs.d(25): Error: no property `regularF` for `s` of type `S` +fail_compilation/ufcs.d(25): the following error occured while looking for a UFCS match +fail_compilation/ufcs.d(25): Error: function `ufcs.regularF()` is not callable using argument types `(S)` +fail_compilation/ufcs.d(25): expected 0 argument(s), not 1 +fail_compilation/ufcs.d(26): Error: no property `templateF` for `s` of type `S` +fail_compilation/ufcs.d(26): the following error occured while looking for a UFCS match +fail_compilation/ufcs.d(26): Error: template `ufcs.templateF` is not callable using argument types `!()(S)` +fail_compilation/ufcs.d(31): Candidate is: `templateF()()` +fail_compilation/ufcs.d(27): Error: no property `templateO` for `s` of type `S` +fail_compilation/ufcs.d(27): the following error occured while looking for a UFCS match +fail_compilation/ufcs.d(27): Error: none of the overloads of template `ufcs.templateO` are callable using argument types `!()(S)` +fail_compilation/ufcs.d(33): Candidates are: `templateO()(int x)` +fail_compilation/ufcs.d(34): `templateO()(float y)` +--- +*/ + +struct S { } + +void f() +{ + S s; + s.regularF(); + s.templateF(); + s.templateO(); +} + +void regularF(); +void templateF()(); + +void templateO()(int x); +void templateO()(float y); diff --git a/gcc/testsuite/gdc.test/runnable/betterc.d b/gcc/testsuite/gdc.test/runnable/betterc.d index 74967e9..3d8f7da 100644 --- a/gcc/testsuite/gdc.test/runnable/betterc.d +++ b/gcc/testsuite/gdc.test/runnable/betterc.d @@ -42,6 +42,7 @@ extern (C) void main() test18472(); testRuntimeLowerings(); test18457(); + test20737(); } /*******************************************/ @@ -199,3 +200,13 @@ void test18457() } assert(dtor == 1); } + +/**********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=20737 +int tlsVar; + +int test20737() +{ + tlsVar = 123; + return 0; +} diff --git a/gcc/testsuite/gdc.test/runnable/eh2.d b/gcc/testsuite/gdc.test/runnable/eh2.d index 2b469d2..775e83d 100644 --- a/gcc/testsuite/gdc.test/runnable/eh2.d +++ b/gcc/testsuite/gdc.test/runnable/eh2.d @@ -72,11 +72,11 @@ int main() a.test(); Abc.x |= 0x40; } - catch (shared(Abc) b) + catch (Abc b) { Abc.x |= 0x80; printf("Caught %p, x = x%x\n", b, Abc.x); - assert(a is b); + assert(cast() a is b); assert(Abc.x == 0xB5); } printf("Success!\n"); diff --git a/gcc/testsuite/gdc.test/runnable/funclit.d b/gcc/testsuite/gdc.test/runnable/funclit.d index e6e4fec..c4b70dc 100644 --- a/gcc/testsuite/gdc.test/runnable/funclit.d +++ b/gcc/testsuite/gdc.test/runnable/funclit.d @@ -1263,6 +1263,7 @@ void assign16271(T)(ref T a, T b) void test16271() { int x; + (delegate ref => x)() = -1; assert(x == -1); (ref () => x )() = 1; assert(x == 1); func16271!(ref () => x) = 2; assert(x == 2); assign16271(x, 3); assert(x == 3); diff --git a/gcc/testsuite/gdc.test/runnable/test20687.d b/gcc/testsuite/gdc.test/runnable/test20687.d new file mode 100644 index 0000000..47c33f1 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test20687.d @@ -0,0 +1,28 @@ +// PERMUTE_ARGS: +// https://issues.dlang.org/show_bug.cgi?id=20687 + +struct S +{ + void foo(){} +} + +void main() +{ + S i; + enum fpe = &S.foo; + const fp = &S.foo; + const dg = &i.foo; + + // Allow these + static dgfp = &S.foo; + static const dgfpc = &S.foo; + static immutable dgfpi = &S.foo; + __gshared dgfpg = &S.foo; + __gshared const dgfpgc = &S.foo; + __gshared immutable dgfpgi = &S.foo; + + static foreach (v; [fp, dgfpc, dgfpi, dgfpgc, dgfpgi]) + static assert(fpe == v); + + assert(fp == dg.funcptr && fp == dgfp && fp == dgfpg); +} diff --git a/gcc/testsuite/gdc.test/runnable/testinvariant.d b/gcc/testsuite/gdc.test/runnable/testinvariant.d index d3b3b6f..0ce8557 100644 --- a/gcc/testsuite/gdc.test/runnable/testinvariant.d +++ b/gcc/testsuite/gdc.test/runnable/testinvariant.d @@ -176,6 +176,58 @@ void test13147() s.test(); } +/***************************************************/ +// https://issues.dlang.org/show_bug.cgi?id=16384 + +struct S(T) +{ + T x = 5; + invariant { assert(x == 6); } + invariant { assert(x > 0); } + + void foo() {} +} + +void f(int i) pure { assert( i == 6); } + +struct S2(T) +{ + T x = 5; + invariant { f(x); } + invariant { assert(x > 0); } + + void foo() {} +} + +void test16384() +{ + string s; + S!int y; + try + { + y.foo(); + } + catch(Error) + { + s = "needs to be thrown"; + } + + assert(s == "needs to be thrown"); + + S2!int y2; + + try + { + y2.foo(); + } + catch(Error) + { + s = "needs to be thrown2"; + } + + assert(s == "needs to be thrown2"); +} + /***************************************************/ @@ -183,6 +235,7 @@ void main() { testinvariant(); test6453(); + test16384(); test13113(); test13147(); } diff --git a/gcc/testsuite/gdc.test/runnable/variadic.d b/gcc/testsuite/gdc.test/runnable/variadic.d index 2d0736d..7e9473c 100644 --- a/gcc/testsuite/gdc.test/runnable/variadic.d +++ b/gcc/testsuite/gdc.test/runnable/variadic.d @@ -1119,6 +1119,53 @@ void test15417() /***************************************/ +// https://issues.dlang.org/show_bug.cgi?id=21425 + +import core.stdc.stdarg; +import core.stdc.stdio; + +extern(C) void f5(int dummy, ...) +{ + va_list ap; + + va_start(ap, dummy); + int x = va_arg!int(ap); + assert(x == 5); + va_end(ap); + + va_start(ap, dummy); + int y = va_arg!int(ap); + assert(y == 5); + va_end(ap); +} + +void test21425() +{ + f5(0, 5); +} + +/*********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=23409 + +import core.stdc.string; + +void printf10(const(char)* fmt, ...){ + char[30] s; + for(int i = 0; i < 10; i++){ + va_list args; + va_start(args, fmt); + vsprintf(s.ptr, fmt, args); + va_end(args); + assert(strcmp(s.ptr, "Hello world\n") == 0); + } +} + +void test23409() +{ + printf10("Hello %s\n".ptr, "world".ptr); +} + +/***************************************/ int main() { @@ -1169,6 +1216,8 @@ int main() testCopy(); test14179(); test15417(); + test21425(); + test23409(); return 0; } diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 95ea67d..1cff48a 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -28a3b24c2e45de39cd3df528142fd06b6456e8fd +17ccd12af386543c0b9935bf7e0a8e701b903105 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/libphobos/libdruntime/__builtins.di b/libphobos/libdruntime/__builtins.di index 1c49035..74147a0 100644 --- a/libphobos/libdruntime/__builtins.di +++ b/libphobos/libdruntime/__builtins.di @@ -67,8 +67,7 @@ version (DigitalMars) ushort __builtin_bswap16()(ushort value) { - import core.bitop; - return core.bitop.byteswap(value); + return cast(ushort) (((value >> 8) & 0xFF) | ((value << 8) & 0xFF00U)); } uint __builtin_bswap32()(uint value) diff --git a/libphobos/libdruntime/core/atomic.d b/libphobos/libdruntime/core/atomic.d index 1fba06c..5a7d00c 100644 --- a/libphobos/libdruntime/core/atomic.d +++ b/libphobos/libdruntime/core/atomic.d @@ -162,7 +162,7 @@ void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, V new } /// Ditto -void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, shared V newval) pure nothrow @nogc @trusted +void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, auto ref shared V newval) pure nothrow @nogc @trusted if (is(T == class)) { static assert (is (V : T), "Can't assign `newval` of type `shared " ~ V.stringof ~ "` to `shared " ~ T.stringof ~ "`."); diff --git a/libphobos/libdruntime/core/internal/string.d b/libphobos/libdruntime/core/internal/string.d index e09bba4..7bb319e 100644 --- a/libphobos/libdruntime/core/internal/string.d +++ b/libphobos/libdruntime/core/internal/string.d @@ -152,7 +152,7 @@ T[] signedToTempString(uint radix = 10, bool upperCase = false, T)(long value, r if (neg) { // about to do a slice without a bounds check - auto trustedSlice(return scope char[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; } + auto trustedSlice(return scope T[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; } r = trustedSlice(r); r[0] = '-'; } @@ -190,6 +190,12 @@ unittest assert(long.max.signedToTempString(buf) == "9223372036854775807"); assert(long.min.signedToTempString(buf) == "-9223372036854775808"); + wchar[65] wbuf = void; + assert(1.signedToTempString(wbuf) == "1"w); + + dchar[65] dbuf = void; + assert(1.signedToTempString(dbuf) == "1"d); + // use stack allocated struct version assert(0.signedToTempString() == "0"); assert(1.signedToTempString == "1"); diff --git a/libphobos/libdruntime/core/internal/util/array.d b/libphobos/libdruntime/core/internal/util/array.d index 6136cfe..066ee7e 100644 --- a/libphobos/libdruntime/core/internal/util/array.d +++ b/libphobos/libdruntime/core/internal/util/array.d @@ -26,14 +26,6 @@ private char[] errorMessage(Args...)(scope const(char*) format, @safe /* pure dmd @@@BUG11461@@@ */ nothrow: -void enforceTypedArraysConformable(T)(const char[] action, - const T[] a1, const T[] a2, const bool allowOverlap = false) -{ - _enforceSameLength(action, a1.length, a2.length); - if (!allowOverlap) - _enforceNoOverlap(action, arrayToPtr(a1), arrayToPtr(a2), T.sizeof * a1.length); -} - void enforceRawArraysConformable(const char[] action, const size_t elementSize, const void[] a1, const void[] a2, const bool allowOverlap = false) { @@ -76,14 +68,6 @@ private void _enforceNoOverlap(const char[] action, assert(0, msg); } -void enforceTypedArraysConformableNogc(T)(const char[] action, - const T[] a1, const T[] a2, const bool allowOverlap = false) -{ - _enforceSameLengthNogc(action, a1.length, a2.length); - if (!allowOverlap) - _enforceNoOverlapNogc(action, arrayToPtr(a1), arrayToPtr(a2), T.sizeof * a1.length); -} - void enforceRawArraysConformableNogc(const char[] action, const size_t elementSize, const void[] a1, const void[] a2, const bool allowOverlap = false) { diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d index 5e339c0..ae047cb 100644 --- a/libphobos/libdruntime/core/lifetime.d +++ b/libphobos/libdruntime/core/lifetime.d @@ -2777,6 +2777,70 @@ if (is(T == class)) return cast(T) p; } +/** + * TraceGC wrapper around $(REF _d_newclassT, core,lifetime). + */ +T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted +{ + version (D_TypeInfo) + { + import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure; + mixin(TraceHook!(T.stringof, "_d_newclassT")); + + return _d_newclassT!T(); + } + else + assert(0, "Cannot create new class if compiling without support for runtime type information!"); +} + +/** + * Allocate an initialized non-array item. + * + * This is an optimization to avoid things needed for arrays like the __arrayPad(size). + * Used to allocate struct instances on the heap. + * + * --- + * struct Sz {int x = 0;} + * struct Si {int x = 3;} + * + * void main() + * { + * new Sz(); // uses zero-initialization + * new Si(); // uses Si.init + * } + * --- + * + * Returns: + * newly allocated item + */ +T* _d_newitemT(T)() @trusted +{ + import core.internal.lifetime : emplaceInitializer; + import core.internal.traits : hasElaborateDestructor, hasIndirections; + import core.memory : GC; + + auto flags = !hasIndirections!T ? GC.BlkAttr.NO_SCAN : GC.BlkAttr.NONE; + immutable tiSize = hasElaborateDestructor!T ? size_t.sizeof : 0; + immutable itemSize = T.sizeof; + immutable totalSize = itemSize + tiSize; + if (tiSize) + flags |= GC.BlkAttr.STRUCTFINAL | GC.BlkAttr.FINALIZE; + + auto blkInfo = GC.qalloc(totalSize, flags, null); + auto p = blkInfo.base; + + if (tiSize) + { + // The GC might not have cleared the padding area in the block. + *cast(TypeInfo*) (p + (itemSize & ~(size_t.sizeof - 1))) = null; + *cast(TypeInfo*) (p + blkInfo.size - tiSize) = cast() typeid(T); + } + + emplaceInitializer(*(cast(T*) p)); + + return cast(T*) p; +} + // Test allocation @safe unittest { @@ -2805,15 +2869,134 @@ if (is(T == class)) } } -T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted +// Test allocation +@safe unittest +{ + struct S { } + S* s = _d_newitemT!S(); + + assert(s !is null); +} + +// Test initializers +@safe unittest { - version (D_TypeInfo) { - import core.internal.array.utils: TraceHook, gcStatsPure, accumulatePure; - mixin(TraceHook!(T.stringof, "_d_newclassT")); + // zero-initialization + struct S { int x, y; } + S* s = _d_newitemT!S(); - return _d_newclassT!T(); + assert(s.x == 0); + assert(s.y == 0); + } + { + // S.init + struct S { int x = 2, y = 3; } + S* s = _d_newitemT!S(); + + assert(s.x == 2); + assert(s.y == 3); + } +} + +// Test GC attributes +version (CoreUnittest) +{ + struct S1 + { + int x = 5; + } + struct S2 + { + int x; + this(int x) { this.x = x; } + } + struct S3 + { + int[4] x; + this(int x) { this.x[] = x; } + } + struct S4 + { + int *x; + } + +} +@system unittest +{ + import core.memory : GC; + + auto s1 = new S1; + assert(s1.x == 5); + assert(GC.getAttr(s1) == GC.BlkAttr.NO_SCAN); + + auto s2 = new S2(3); + assert(s2.x == 3); + assert(GC.getAttr(s2) == GC.BlkAttr.NO_SCAN); + + auto s3 = new S3(1); + assert(s3.x == [1, 1, 1, 1]); + assert(GC.getAttr(s3) == GC.BlkAttr.NO_SCAN); + debug(SENTINEL) {} else + assert(GC.sizeOf(s3) == 16); + + auto s4 = new S4; + assert(s4.x == null); + assert(GC.getAttr(s4) == 0); +} + +// Test struct finalizers exception handling +debug(SENTINEL) {} else +@system unittest +{ + import core.memory : GC; + + bool test(E)() + { + import core.exception; + static struct S1 + { + E exc; + ~this() { throw exc; } + } + + bool caught = false; + S1* s = new S1(new E("test onFinalizeError")); + try + { + GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0 .. 1]); + } + catch (FinalizeError err) + { + caught = true; + } + catch (E) + { + } + GC.free(s); + return caught; + } + + assert(test!Exception); + import core.exception : InvalidMemoryOperationError; + assert(!test!InvalidMemoryOperationError); +} + +version (D_ProfileGC) +{ + /** + * TraceGC wrapper around $(REF _d_newitemT, core,lifetime). + */ + T* _d_newitemTTrace(T)(string file, int line, string funcname) @trusted + { + version (D_TypeInfo) + { + import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure; + mixin(TraceHook!(T.stringof, "_d_newitemT")); + + return _d_newitemT!T(); + } + else + assert(0, "Cannot create new `struct` if compiling without support for runtime type information!"); } - else - assert(0, "Cannot create new class if compiling without support for runtime type information!"); } diff --git a/libphobos/libdruntime/core/stdc/assert_.d b/libphobos/libdruntime/core/stdc/assert_.d index fc9402f..a8909e2 100644 --- a/libphobos/libdruntime/core/stdc/assert_.d +++ b/libphobos/libdruntime/core/stdc/assert_.d @@ -12,7 +12,6 @@ /**************************** * These are the various functions called by the assert() macro. - * They are all noreturn functions, although D doesn't have a specific attribute for that. */ module core.stdc.assert_; @@ -36,7 +35,7 @@ version (CRuntime_DigitalMars) /*** * Assert failure function in the Digital Mars C library. */ - void _assert(const(void)* exp, const(void)* file, uint line); + noreturn _assert(const(void)* exp, const(void)* file, uint line); } else version (CRuntime_Microsoft) { @@ -44,37 +43,37 @@ else version (CRuntime_Microsoft) * Assert failure function in the Microsoft C library. * `_assert` is not in assert.h, but it is in the library. */ - void _wassert(const(wchar)* exp, const(wchar)* file, uint line); + noreturn _wassert(const(wchar)* exp, const(wchar)* file, uint line); /// - void _assert(const(char)* exp, const(char)* file, uint line); + noreturn _assert(const(char)* exp, const(char)* file, uint line); } else version (Darwin) { /*** * Assert failure function in the Darwin C library. */ - void __assert_rtn(const(char)* func, const(char)* file, uint line, const(char)* exp); + noreturn __assert_rtn(const(char)* func, const(char)* file, uint line, const(char)* exp); } else version (FreeBSD) { /*** * Assert failure function in the FreeBSD C library. */ - void __assert(const(char)* exp, const(char)* file, uint line); + noreturn __assert(const(char)* exp, const(char)* file, uint line, const(char)* exp); } else version (NetBSD) { /*** * Assert failure function in the NetBSD C library. */ - void __assert(const(char)* file, int line, const(char)* exp); + noreturn __assert(const(char)* file, int line, const(char)* exp); } else version (OpenBSD) { /*** * Assert failure function in the OpenBSD C library. */ - void __assert(const(char)* file, int line, const(char)* exp); + noreturn __assert(const(char)* file, int line, const(char)* exp); /// void __assert2(const(char)* file, int line, const(char)* func, const(char)* exp); } @@ -83,37 +82,37 @@ else version (DragonFlyBSD) /*** * Assert failure function in the DragonFlyBSD C library. */ - void __assert(const(char)* exp, const(char)* file, uint line); + noreturn __assert(const(char)* exp, const(char)* file, uint line, const(char)* exp); } else version (CRuntime_Glibc) { /*** * Assert failure functions in the GLIBC library. */ - void __assert(const(char)* exp, const(char)* file, uint line); + noreturn __assert(const(char)* exp, const(char)* file, uint line); /// - void __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func); + noreturn __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func); /// - void __assert_perror_fail(int errnum, const(char)* file, uint line, const(char)* func); + noreturn __assert_perror_fail(int errnum, const(char)* file, uint line, const(char)* func); } else version (CRuntime_Bionic) { - void __assert(const(char)* __file, int __line, const(char)* __msg); + noreturn __assert(const(char)* __file, int __line, const(char)* __msg); } else version (CRuntime_Musl) { /*** * Assert failure function in the Musl C library. */ - void __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func); + noreturn __assert_fail(const(char)* exp, const(char)* file, uint line, const(char)* func); } else version (CRuntime_UClibc) { - void __assert(const(char)* exp, const(char)* file, uint line, const(char)* func); + noreturn __assert(const(char)* exp, const(char)* file, uint line, const(char)* func); } else version (Solaris) { - void __assert_c99(const(char)* exp, const(char)* file, uint line, const(char)* func); + noreturn __assert_c99(const(char)* exp, const(char)* file, uint line, const(char)* func); } else { diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index 610cb7a..337eabf 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -527,7 +527,8 @@ private extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) void setSameMutex(shared Object ownee, shared Object owner) { - _d_setSameMutex(ownee, owner); + import core.atomic : atomicLoad; + _d_setSameMutex(atomicLoad(ownee), atomicLoad(owner)); } @system unittest @@ -4532,6 +4533,7 @@ version (D_ProfileGC) { public import core.internal.array.appending : _d_arrayappendTTrace; public import core.internal.array.concatenation : _d_arraycatnTXTrace; + public import core.lifetime : _d_newitemTTrace; } public import core.internal.array.appending : _d_arrayappendcTXImpl; public import core.internal.array.comparison : __cmp; @@ -4560,6 +4562,7 @@ public import core.lifetime : _d_delstructImpl; public import core.lifetime : _d_newThrowable; public import core.lifetime : _d_newclassT; public import core.lifetime : _d_newclassTTrace; +public import core.lifetime : _d_newitemT; public @trusted @nogc nothrow pure extern (C) void _d_delThrowable(scope Throwable); diff --git a/libphobos/libdruntime/rt/cast_.d b/libphobos/libdruntime/rt/cast_.d index 1604510..925599e 100644 --- a/libphobos/libdruntime/rt/cast_.d +++ b/libphobos/libdruntime/rt/cast_.d @@ -117,22 +117,6 @@ int _d_isbaseof2(scope ClassInfo oc, scope const ClassInfo c, scope ref size_t o int _d_isbaseof(scope ClassInfo oc, scope const ClassInfo c) @safe { - if (areClassInfosEqual(oc, c)) - return true; - - do - { - if (oc.base && areClassInfosEqual(oc.base, c)) - return true; - - foreach (iface; oc.interfaces) - { - if (areClassInfosEqual(iface.classinfo, c) || _d_isbaseof(iface.classinfo, c)) - return true; - } - - oc = oc.base; - } while (oc); - - return false; + size_t offset = 0; + return _d_isbaseof2(oc, c, offset); } diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d index a37541b..40fa3e0 100644 --- a/libphobos/libdruntime/rt/lifetime.d +++ b/libphobos/libdruntime/rt/lifetime.d @@ -676,7 +676,7 @@ Params: ti = `TypeInfo` of array type arr = array to shrink. Its `.length` is element length, not byte length, despite `void` type */ -extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) /+nothrow+/ +extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow { // note, we do not care about shared. We are setting the length no matter // what, so no lock is required. @@ -701,7 +701,17 @@ extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) /+nothrow+/ { auto oldsize = __arrayAllocLength(info, tinext); if (oldsize > cursize) - finalize_array(arr.ptr + cursize, oldsize - cursize, sti); + { + try + { + finalize_array(arr.ptr + cursize, oldsize - cursize, sti); + } + catch (Exception e) + { + import core.exception : onFinalizeError; + onFinalizeError(sti, e); + } + } } } // Note: Since we "assume" the append is safe, it means it is not shared. @@ -1148,25 +1158,8 @@ extern (C) void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims) @weak } /** -Allocate an uninitialized non-array item. - -This is an optimization to avoid things needed for arrays like the __arrayPad(size). - -- `_d_newitemU` leaves the item uninitialized -- `_d_newitemT` zero initializes the item -- `_d_newitemiT` uses a non-zero initializer from `TypeInfo` - -Used to allocate struct instances on the heap. ---- -struct Sz {int x = 0;} -struct Si {int x = 3;} - -void main() -{ - new Sz(); // _d_newitemT(typeid(Sz)) - new Si(); // _d_newitemiT(typeid(Si)) -} ---- +Non-template version of $(REF _d_newitemT, core,lifetime) that does not perform +initialization. Needed for $(REF allocEntry, rt,aaA). Params: _ti = `TypeInfo` of item to allocate @@ -1196,26 +1189,6 @@ extern (C) void* _d_newitemU(scope const TypeInfo _ti) pure nothrow @weak return p; } -/// ditto -extern (C) void* _d_newitemT(const TypeInfo _ti) pure nothrow @weak -{ - import core.stdc.string; - auto p = _d_newitemU(_ti); - memset(p, 0, _ti.tsize); - return p; -} - -/// Same as above, for item with non-zero initializer. -extern (C) void* _d_newitemiT(const TypeInfo _ti) pure nothrow @weak -{ - import core.stdc.string; - auto p = _d_newitemU(_ti); - auto init = _ti.initializer(); - assert(init.length <= _ti.tsize); - memcpy(p, init.ptr, init.length); - return p; -} - debug(PRINTF) { extern(C) void printArrayCache() @@ -2361,52 +2334,6 @@ unittest testPostBlit!(const(S))(); } -// cannot define structs inside unit test block, or they become nested structs. -version (CoreUnittest) -{ - struct S1 - { - int x = 5; - } - struct S2 - { - int x; - this(int x) {this.x = x;} - } - struct S3 - { - int[4] x; - this(int x) - {this.x[] = x;} - } - struct S4 - { - int *x; - } - -} - -unittest -{ - auto s1 = new S1; - assert(s1.x == 5); - assert(GC.getAttr(s1) == BlkAttr.NO_SCAN); - - auto s2 = new S2(3); - assert(s2.x == 3); - assert(GC.getAttr(s2) == BlkAttr.NO_SCAN); - - auto s3 = new S3(1); - assert(s3.x == [1,1,1,1]); - assert(GC.getAttr(s3) == BlkAttr.NO_SCAN); - debug(SENTINEL) {} else - assert(GC.sizeOf(s3) == 16); - - auto s4 = new S4; - assert(s4.x == null); - assert(GC.getAttr(s4) == 0); -} - unittest { // Bugzilla 3454 - Inconsistent flag setting in GC.realloc() @@ -2731,41 +2658,6 @@ unittest assert(!test!InvalidMemoryOperationError); } -// test struct finalizers exception handling -debug(SENTINEL) {} else -unittest -{ - bool test(E)() - { - import core.exception; - static struct S1 - { - E exc; - ~this() { throw exc; } - } - - bool caught = false; - S1* s = new S1(new E("test onFinalizeError")); - try - { - GC.runFinalizers((cast(char*)(typeid(S1).xdtor))[0..1]); - } - catch (FinalizeError err) - { - caught = true; - } - catch (E) - { - } - GC.free(s); - return caught; - } - - assert( test!Exception); - import core.exception : InvalidMemoryOperationError; - assert(!test!InvalidMemoryOperationError); -} - // test bug 14126 unittest { diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index c6e61f7..d3ebf74 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -8ab95ded5265379e74d507fdc252ff3d2305fc26 +8d3800bee23db56f71ef4066f74bce057fcce256 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d index 9f5a6ac..55ccb51 100644 --- a/libphobos/src/std/algorithm/iteration.d +++ b/libphobos/src/std/algorithm/iteration.d @@ -7939,15 +7939,23 @@ See_Also: $(REF nextPermutation, std,algorithm,sorting). */ Permutations!Range permutations(Range)(Range r) -if (isRandomAccessRange!Range && hasLength!Range) { + static assert(isRandomAccessRange!Range, Range.stringof, + " must be a RandomAccessRange"); + static assert(hasLength!Range, Range.stringof + , " must have a length"); + return typeof(return)(r); } /// ditto struct Permutations(Range) -if (isRandomAccessRange!Range && hasLength!Range) { + static assert(isRandomAccessRange!Range, Range.stringof, + " must be a RandomAccessRange"); + static assert(hasLength!Range, Range.stringof + , " must have a length"); + private size_t[] _indices, _state; private Range _r; private bool _empty; diff --git a/libphobos/src/std/bigint.d b/libphobos/src/std/bigint.d index 33d0eae..50f88da 100644 --- a/libphobos/src/std/bigint.d +++ b/libphobos/src/std/bigint.d @@ -254,11 +254,11 @@ public: static if (op=="+") { - data = BigUint.addOrSubInt(data, u, sign != (y<0), sign); + data = BigUint.addOrSubInt!ulong(data, u, wantSub: sign != (y<0), sign); } else static if (op=="-") { - data = BigUint.addOrSubInt(data, u, sign == (y<0), sign); + data = BigUint.addOrSubInt!ulong(data, u, wantSub: sign == (y<0), sign); } else static if (op=="*") { @@ -613,7 +613,7 @@ public: static if (op == "-") { r.sign = sign; - r.data = BigUint.addOrSubInt(data, u, sign == (y<0), r.sign); + r.data = BigUint.addOrSubInt!ulong(data, u, wantSub: sign == (y<0), r.sign); r.negate(); } return r; @@ -670,12 +670,12 @@ public: { static if (op=="++") { - data = BigUint.addOrSubInt(data, 1UL, sign, sign); + data = BigUint.addOrSubInt!ulong(data, 1UL, wantSub: sign, sign); return this; } else static if (op=="--") { - data = BigUint.addOrSubInt(data, 1UL, !sign, sign); + data = BigUint.addOrSubInt!ulong(data, 1UL, wantSub: !sign, sign); return this; } } diff --git a/libphobos/src/std/checkedint.d b/libphobos/src/std/checkedint.d index 79597e8..cec1dc1 100644 --- a/libphobos/src/std/checkedint.d +++ b/libphobos/src/std/checkedint.d @@ -2129,16 +2129,16 @@ static: { // Not value convertible, only viable option is rhs fits within the // bounds of Lhs - static if (ProperCompare.hookOpCmp(Rhs.min, Lhs.min) < 0) + static if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: Rhs.min, rhs: Lhs.min) < 0) { // Example: hookOpCast!short(int(42)), hookOpCast!uint(int(42)) - if (ProperCompare.hookOpCmp(rhs, Lhs.min) < 0) + if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: rhs, rhs: Lhs.min) < 0) return defaultValue!Lhs; } - static if (ProperCompare.hookOpCmp(Rhs.max, Lhs.max) > 0) + static if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: Rhs.max, rhs: Lhs.max) > 0) { // Example: hookOpCast!int(uint(42)) - if (ProperCompare.hookOpCmp(rhs, Lhs.max) > 0) + if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: rhs, rhs: Lhs.max) > 0) return defaultValue!Lhs; } return cast(Lhs) rhs; diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d index aef2365..89d4e5e 100644 --- a/libphobos/src/std/conv.d +++ b/libphobos/src/std/conv.d @@ -102,21 +102,6 @@ private auto convError(S, T)(S source, string fn = __FILE__, size_t ln = __LINE_ return new ConvException(msg, fn, ln); } -private auto convError(S, T)(S source, int radix, string fn = __FILE__, size_t ln = __LINE__) -{ - string msg; - - if (source.empty) - msg = text("Unexpected end of input when converting from type " ~ S.stringof ~ " base ", radix, - " to type " ~ T.stringof); - else - msg = text("Unexpected '", source.front, - "' when converting from type " ~ S.stringof ~ " base ", radix, - " to type " ~ T.stringof); - - return new ConvException(msg, fn, ln); -} - @safe pure/* nothrow*/ // lazy parameter bug private auto parseError(lazy string msg, string fn = __FILE__, size_t ln = __LINE__) { @@ -1023,7 +1008,15 @@ if (!(is(S : T) && else static if (isIntegral!S && !is(S == enum)) { // other integral-to-string conversions with default radix - return toImpl!(T, S)(value, 10); + + import core.internal.string : signedToTempString, unsignedToTempString; + + alias EEType = Unqual!(ElementEncodingType!T); + EEType[long.sizeof * 3 + 1] buf = void; + EEType[] t = isSigned!S + ? signedToTempString!(10, false, EEType)(value, buf) + : unsignedToTempString!(10, false, EEType)(value, buf); + return t.dup; } else static if (is(S == void[]) || is(S == const(void)[]) || is(S == immutable(void)[])) { @@ -5726,33 +5719,13 @@ if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) && { void initialize(UT value) { - bool neg = false; - if (value < 10) - { - if (value >= 0) - { - lwr = 0; - upr = 1; - buf[0] = cast(char)(cast(uint) value + '0'); - return; - } - value = -value; - neg = true; - } - auto i = cast(uint) buf.length - 1; - while (cast(Unsigned!UT) value >= 10) - { - buf[i] = cast(ubyte)('0' + cast(Unsigned!UT) value % 10); - value = unsigned(value) / 10; - --i; - } - buf[i] = cast(char)(cast(uint) value + '0'); - if (neg) - { - buf[i - 1] = '-'; - --i; - } - lwr = i; + import core.internal.string : signedToTempString, unsignedToTempString; + + char[] t = value < 0 + ? signedToTempString!(10, false, char)(value, buf) + : unsignedToTempString!(10, false, char)(value, buf); + + lwr = cast(uint) (buf.length - t.length); upr = cast(uint) buf.length; } diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d index de9afbb..02d5cf8 100644 --- a/libphobos/src/std/experimental/allocator/mallocator.d +++ b/libphobos/src/std/experimental/allocator/mallocator.d @@ -376,17 +376,17 @@ version (Posix) { // https://issues.dlang.org/show_bug.cgi?id=16398 // test the "pseudo" alignedReallocate for Posix - void[] s = AlignedMallocator.instance.alignedAllocate(16, 32); - (cast(ubyte[]) s)[] = ubyte(1); - AlignedMallocator.instance.alignedReallocate(s, 32, 32); + void[] b = AlignedMallocator.instance.alignedAllocate(16, 32); + (cast(ubyte[]) b)[] = ubyte(1); + AlignedMallocator.instance.alignedReallocate(b, 32, 32); ubyte[16] o; o[] = 1; - assert((cast(ubyte[]) s)[0 .. 16] == o); - AlignedMallocator.instance.alignedReallocate(s, 4, 32); - assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]); - AlignedMallocator.instance.alignedReallocate(s, 128, 32); - assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]); - AlignedMallocator.instance.deallocate(s); + assert((cast(ubyte[]) b)[0 .. 16] == o); + AlignedMallocator.instance.alignedReallocate(b, 4, 32); + assert((cast(ubyte[]) b)[0 .. 3] == o[0 .. 3]); + AlignedMallocator.instance.alignedReallocate(b, 128, 32); + assert((cast(ubyte[]) b)[0 .. 3] == o[0 .. 3]); + AlignedMallocator.instance.deallocate(b); void[] c; AlignedMallocator.instance.alignedReallocate(c, 32, 32); diff --git a/libphobos/src/std/getopt.d b/libphobos/src/std/getopt.d index 42aeb40..cb97eeb 100644 --- a/libphobos/src/std/getopt.d +++ b/libphobos/src/std/getopt.d @@ -685,6 +685,7 @@ private void getoptImpl(T...)(ref string[] args, ref configuration cfg, import std.algorithm.mutation : remove; import std.conv : to; + import std.uni : toLower; static if (opts.length) { static if (is(typeof(opts[0]) : config)) @@ -708,7 +709,10 @@ private void getoptImpl(T...)(ref string[] args, ref configuration cfg, if (optionHelp.optLong.length) { - assert(optionHelp.optLong !in visitedLongOpts, + auto name = optionHelp.optLong; + if (!cfg.caseSensitive) + name = name.toLower(); + assert(name !in visitedLongOpts, "Long option " ~ optionHelp.optLong ~ " is multiply defined"); visitedLongOpts[optionHelp.optLong] = []; @@ -716,7 +720,10 @@ private void getoptImpl(T...)(ref string[] args, ref configuration cfg, if (optionHelp.optShort.length) { - assert(optionHelp.optShort !in visitedShortOpts, + auto name = optionHelp.optShort; + if (!cfg.caseSensitive) + name = name.toLower(); + assert(name !in visitedShortOpts, "Short option " ~ optionHelp.optShort ~ " is multiply defined"); @@ -1779,6 +1786,14 @@ void defaultGetoptFormatter(Output)(Output output, string text, Option[] opt, st assertThrown!AssertError(getopt(args, "abc", &abc, "abc", &abc)); assertThrown!AssertError(getopt(args, "abc|a", &abc, "def|a", &def)); assertNotThrown!AssertError(getopt(args, "abc", &abc, "def", &def)); + + // https://issues.dlang.org/show_bug.cgi?id=23940 + assertThrown!AssertError(getopt(args, + "abc", &abc, "ABC", &def)); + assertThrown!AssertError(getopt(args, config.caseInsensitive, + "abc", &abc, "ABC", &def)); + assertNotThrown!AssertError(getopt(args, config.caseSensitive, + "abc", &abc, "ABC", &def)); } // https://issues.dlang.org/show_bug.cgi?id=17327 repeated option use diff --git a/libphobos/src/std/path.d b/libphobos/src/std/path.d index 63d60d1..e81f2b6 100644 --- a/libphobos/src/std/path.d +++ b/libphobos/src/std/path.d @@ -3955,7 +3955,7 @@ if (isConvertibleToString!Range) } ----- */ -string expandTilde(string inputPath) @safe nothrow +string expandTilde(return scope const string inputPath) @safe nothrow { version (Posix) { @@ -4138,7 +4138,7 @@ string expandTilde(string inputPath) @safe nothrow } /// -@system unittest +@safe unittest { version (Posix) { @@ -4153,7 +4153,7 @@ string expandTilde(string inputPath) @safe nothrow } } -@system unittest +@safe unittest { version (Posix) { @@ -4205,6 +4205,26 @@ string expandTilde(string inputPath) @safe nothrow } } +@safe unittest +{ + version (Posix) + { + import std.process : environment; + + string testPath(scope const string source_path) { + return source_path.expandTilde; + } + + auto oldHome = environment["HOME"]; + scope(exit) environment["HOME"] = oldHome; + + environment["HOME"] = "dmd/test"; + assert(testPath("~/") == "dmd/test/"); + assert(testPath("~") == "dmd/test"); + } +} + + version (StdUnittest) { private: diff --git a/libphobos/src/std/range/package.d b/libphobos/src/std/range/package.d index 7a724b0..d37c641 100644 --- a/libphobos/src/std/range/package.d +++ b/libphobos/src/std/range/package.d @@ -232,7 +232,7 @@ module std.range; public import std.array; public import std.range.interfaces; public import std.range.primitives; -public import std.typecons : Flag, Yes, No; +public import std.typecons : Flag, Yes, No, Rebindable, rebindable; import std.internal.attributes : betterC; import std.meta : aliasSeqOf, allSatisfy, anySatisfy, staticMap; @@ -978,6 +978,11 @@ if (Ranges.length > 0 && static if (bidirectional) size_t backIndex; else enum backIndex = source.length; + this(typeof(Result.tupleof) fields) + { + this.tupleof = fields; + } + public: this(R input) { @@ -1376,25 +1381,34 @@ if (Ranges.length > 0 && static if (allSatisfy!(hasLength, R) && allSatisfy!(hasSlicing, R)) auto opSlice(size_t begin, size_t end) return scope { - auto result = this; + // force staticMap type conversion to Rebindable + static struct ResultRanges + { + staticMap!(Rebindable, Ranges) fields; + } + auto sourceI(size_t i)() => rebindable(this.source[i]); + auto resultRanges = ResultRanges(staticMap!(sourceI, aliasSeqOf!(R.length.iota))).fields; + size_t resultFrontIndex = this.frontIndex; + static if (bidirectional) + size_t resultBackIndex = this.backIndex; sw: switch (frontIndex) { static foreach (i; 0 .. R.length) { case i: - immutable len = result.source[i].length; + immutable len = resultRanges[i].length; if (len <= begin) { - result.source[i] = result.source[i] + resultRanges[i] = resultRanges[i] [len .. len]; begin -= len; - result.frontIndex++; + resultFrontIndex++; goto case; } else { - result.source[i] = result.source[i] + resultRanges[i] = resultRanges[i] [begin .. len]; break sw; } @@ -1418,18 +1432,18 @@ if (Ranges.length > 0 && static foreach_reverse (i; 1 .. R.length + 1) { case i: - immutable len = result.source[i-1].length; + immutable len = resultRanges[i-1].length; if (len <= cut) { - result.source[i-1] = result.source[i-1] + resultRanges[i-1] = resultRanges[i-1] [0 .. 0]; cut -= len; - result.backIndex--; + resultBackIndex--; goto case; } else { - result.source[i-1] = result.source[i-1] + resultRanges[i-1] = resultRanges[i-1] [0 .. len - cut]; break sw2; } @@ -1445,7 +1459,10 @@ if (Ranges.length > 0 && assert(0, "Internal library error. Please report it."); } - return result; + static if (bidirectional) + return Result(resultRanges, resultFrontIndex, resultBackIndex); + else + return Result(resultRanges, resultFrontIndex); } } return Result(rs); @@ -1643,6 +1660,18 @@ pure @safe unittest assert(equal(r, "foobar")); } +// https://issues.dlang.org/show_bug.cgi?id=23844 +pure @safe unittest +{ + struct S + { + immutable int value; + } + + auto range = chain(only(S(5)), only(S(6))); + assert(range.array == [S(5), S(6)]); +} + pure @safe nothrow @nogc unittest { // support non-copyable items diff --git a/libphobos/src/std/system.d b/libphobos/src/std/system.d index 55fcfd7..aa672a5 100644 --- a/libphobos/src/std/system.d +++ b/libphobos/src/std/system.d @@ -82,5 +82,77 @@ immutable /// The endianness that the program was compiled for. version (LittleEndian) Endian endian = Endian.littleEndian; else Endian endian = Endian.bigEndian; + /++ + Instruction Set Architecture. + + Note: + This is intended for cases where you need a value representing the + instruction set architecture at runtime. If you're doing something + which should compile differently depending on instruction set + architecture, then please use `version (X86_64)`, `version (ARM)`, + etc. + + See_Also: + $(DDSUBLINK spec/version,PredefinedVersions, Predefined Versions) + +/ + enum ISA + { + x86, /// Intel and AMD 32-bit processors + x86_64, /// Intel and AMD 64-bit processors + arm, /// The ARM architecture (32-bit) (AArch32 et al) + aarch64, /// The Advanced RISC Machine architecture (64-bit) + asmJS, /// The asm.js intermediate programming language + avr, /// 8-bit Atmel AVR Microcontrollers + epiphany, /// The Epiphany architecture + ppc, /// The PowerPC architecture, 32-bit + ppc64, /// The PowerPC architecture, 64-bit + ia64, /// The Itanium architecture (64-bit) + mips32, /// The MIPS architecture, 32-bit + mips64, /// The MIPS architecture, 64-bit + msp430, /// The MSP430 architecture + nvptx, /// The Nvidia Parallel Thread Execution (PTX) architecture, 32-bit + nvptx64, /// The Nvidia Parallel Thread Execution (PTX) architecture, 64-bit + riscv32, /// The RISC-V architecture, 32-bit + riscv64, /// The RISC-V architecture, 64-bit + sparc, /// The SPARC architecture, 32-bit + sparc64, /// The SPARC architecture, 64-bit + s390, /// The System/390 architecture, 32-bit + systemZ, /// The System Z architecture, 64-bit + hppa, /// The HP PA-RISC architecture, 32-bit + hppa64, /// The HP PA-RISC architecture, 64-bit + sh, /// The SuperH architecture, 32-bit + webAssembly, /// The WebAssembly virtual ISA (instruction set architecture), 32-bit + alpha, /// The Alpha architecture + unknown, /// Unknown + } + + /// The instruction set architecture that the program was compiled for. + version (X86) ISA instructionSetArchitecture = ISA.x86; + else version (X86_64) ISA instructionSetArchitecture = ISA.x86_64; + else version (ARM) ISA instructionSetArchitecture = ISA.arm; + else version (AArch64) ISA instructionSetArchitecture = ISA.aarch64; + else version (AsmJS) ISA instructionSetArchitecture = ISA.asmJS; + else version (AVR) ISA instructionSetArchitecture = ISA.avr; + else version (Epiphany) ISA instructionSetArchitecture = ISA.epiphany; + else version (PPC) ISA instructionSetArchitecture = ISA.ppc; + else version (PPC64) ISA instructionSetArchitecture = ISA.ppc64; + else version (IA64) ISA instructionSetArchitecture = ISA.ia64; + else version (MIPS32) ISA instructionSetArchitecture = ISA.mips32; + else version (MIPS64) ISA instructionSetArchitecture = ISA.mips64; + else version (MSP430) ISA instructionSetArchitecture = ISA.msp430; + else version (NVPTX) ISA instructionSetArchitecture = ISA.nvptx; + else version (NVPTX64) ISA instructionSetArchitecture = ISA.nvptx64; + else version (RISCV32) ISA instructionSetArchitecture = ISA.riscv32; + else version (RISCV64) ISA instructionSetArchitecture = ISA.riscv64; + else version (SPARC) ISA instructionSetArchitecture = ISA.sparc; + else version (SPARC64) ISA instructionSetArchitecture = ISA.sparc64; + else version (S390) ISA instructionSetArchitecture = ISA.s390; + else version (SystemZ) ISA instructionSetArchitecture = ISA.systemZ; + else version (HPPA) ISA instructionSetArchitecture = ISA.hppa; + else version (HPPA64) ISA instructionSetArchitecture = ISA.hppa64; + else version (SH) ISA instructionSetArchitecture = ISA.sh; + else version (WebAssembly) ISA instructionSetArchitecture = ISA.webAssembly; + else version (Alpha) ISA instructionSetArchitecture = ISA.alpha; + else ISA instructionSetArchitecture = ISA.unknown; } diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index d267e71..0748d52 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -7406,11 +7406,11 @@ pure @system unittest foreach (MyRefCounted; AliasSeq!(SafeRefCounted, RefCounted)) { MyRefCounted!int* p; + auto rc1 = MyRefCounted!int(5); + p = &rc1; + assert(rc1 == 5); + assert(rc1._refCounted._store._count == 1); { - auto rc1 = MyRefCounted!int(5); - p = &rc1; - assert(rc1 == 5); - assert(rc1._refCounted._store._count == 1); auto rc2 = rc1; assert(rc1._refCounted._store._count == 2); // Reference semantics @@ -7421,6 +7421,8 @@ pure @system unittest rc1 = rc2; assert(rc1._refCounted._store._count == 2); } + // Artificially end scope of rc1 by calling ~this() explicitly + rc1.__xdtor(); assert(p._refCounted._store == null); // [Safe]RefCounted as a member |