diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-01-29 21:06:59 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-02-21 15:33:38 +0100 |
commit | f99303eb4aafef70075951731b3ad99266fe6225 (patch) | |
tree | 582ebb6e3e8fd966732bc3b92da1a63caad1aca7 | |
parent | 7e9dd9de169034810b92d47bf78284db731fa5da (diff) | |
download | gcc-f99303eb4aafef70075951731b3ad99266fe6225.zip gcc-f99303eb4aafef70075951731b3ad99266fe6225.tar.gz gcc-f99303eb4aafef70075951731b3ad99266fe6225.tar.bz2 |
d: Merge upstream dmd, druntime 09faa4eacd, phobos 13ef27a56.
D front-end changes:
- Import dmd v2.102.0-beta.1
- `static assert' now supports multiple message arguments.
D runtime changes:
- Import druntime v2.102.0-beta.1
- The default `Throwable.TraceInfo' generation now is `@nogc'.
- `Object.factory' method has now been deprecated.
Phobos changes:
- Import phobos v2.102.0-beta.1
- Added float- and double-precision implementations for log
function families in std.math.
- `std.typecons.Unique' now calls `destroy` on struct types
gcc/d/ChangeLog:
* Make-lang.in (D_FRONTEND_OBJS): Add d/location.o.
* d-lang.cc (d_init_options): Update for new front-end interface.
(d_post_options): Call Loc::set after handling options.
* dmd/MERGE: Merge upstream dmd 09faa4eacd.
* dmd/VERSION: Bump version to v2.102.0-beta.1.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 09faa4eacd.
* src/MERGE: Merge upstream phobos 13ef27a56.
* testsuite/libphobos.exceptions/refcounted.d: Add test for chained
reference counted exceptions.
* testsuite/libphobos.shared/finalize.d: Add dg-warning for deprecated
factory interfaces.
* testsuite/libphobos.gc/issue22843.d: New test.
gcc/testsuite/ChangeLog:
* gdc.dg/simd2a.d: Update.
* gdc.dg/simd2b.d: Update.
* gdc.dg/simd2c.d: Update.
* gdc.dg/simd2d.d: Update.
* gdc.dg/simd2e.d: Update.
* gdc.dg/simd2f.d: Update.
* gdc.dg/simd2g.d: Update.
* gdc.dg/simd2h.d: Update.
* gdc.dg/simd2i.d: Update.
* gdc.dg/simd2j.d: Update.
253 files changed, 2627 insertions, 999 deletions
diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in index bf295a9..4feebac 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -147,6 +147,7 @@ D_FRONTEND_OBJS = \ d/json.o \ d/lambdacomp.o \ d/lexer.o \ + d/location.o \ d/mtype.o \ d/mustuse.o \ d/nogc.o \ diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index d9b4946..449c692 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -303,7 +303,7 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options) /* Warnings and deprecations are disabled by default. */ global.params.useDeprecated = DIAGNOSTICinform; global.params.warnings = DIAGNOSTICoff; - global.params.messageStyle = MESSAGESTYLEgnu; + global.params.messageStyle = MessageStyle::gnu; global.params.imppath = d_gc_malloc<Strings> (); global.params.fileImppath = d_gc_malloc<Strings> (); @@ -940,6 +940,9 @@ d_post_options (const char ** fn) global.params.showColumns = flag_show_column; global.params.printErrorContext = flag_diagnostics_show_caret; + /* Keep the front-end location type in sync with params. */ + Loc::set (global.params.showColumns, global.params.messageStyle); + if (global.params.useInline) global.params.dihdr.fullOutput = true; diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 5ee6f62..ac3dd12 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -c8ae4adb2eda515b09b326948e3a4aa9f489af45 +09faa4eacd4fb147107e94eeebf56b3a73fdcc05 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 1c7e1dd..43eb187 100644 --- a/gcc/d/dmd/README.md +++ b/gcc/d/dmd/README.md @@ -47,6 +47,7 @@ Note that these groups have no strict meaning, the category assignments are a bi | File | Purpose | |-----------------------------------------------------------------------|----------------------------------------------------------------------| | [lexer.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/lexer.d) | Convert source code into tokens for the D and ImportC parsers | +| [location.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/location.d)| Encapsulate file/line/column info for error messages, etc. | | [entity.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/entity.d) | Define "\\&Entity;" escape sequence for strings / character literals | | [tokens.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/tokens.d) | Define lexical tokens. | | [parse.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/parse.d) | D parser, converting tokens into an Abstract Syntax Tree (AST) | diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 50adf9c..177c41d 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.101.0-beta.1 +v2.102.0-beta.1 diff --git a/gcc/d/dmd/access.d b/gcc/d/dmd/access.d index 59c77adf..f2d68d5 100644 --- a/gcc/d/dmd/access.d +++ b/gcc/d/dmd/access.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/attribute.html#visibility_attributes, Visibility Attributes) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/access.d, _access.d) @@ -25,6 +25,7 @@ import dmd.errors; import dmd.expression; import dmd.func; import dmd.globals; +import dmd.location; import dmd.mtype; import dmd.tokens; diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d index 50fdc3b..1306a10 100644 --- a/gcc/d/dmd/aggregate.d +++ b/gcc/d/dmd/aggregate.d @@ -4,7 +4,7 @@ * Specification: $(LINK2 https://dlang.org/spec/struct.html, Structs, Unions), * $(LINK2 https://dlang.org/spec/class.html, Class). * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.d, _aggregate.d) @@ -34,6 +34,7 @@ import dmd.func; import dmd.globals; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.tokens; import dmd.typesem : defaultInit; @@ -206,7 +207,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol //printf("AggregateDeclaration::determineSize() %s, sizeok = %d\n", toChars(), sizeok); // The previous instance size finalizing had: - if (type.ty == Terror) + if (type.ty == Terror || errors) return false; // failed already if (sizeok == Sizeok.done) return true; // succeeded diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h index d4432b5..9f9098f 100644 --- a/gcc/d/dmd/aggregate.h +++ b/gcc/d/dmd/aggregate.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. @@ -41,13 +41,6 @@ enum class Baseok : uint8_t semanticdone // all base classes semantic done }; -enum class ThreeState : uint8_t -{ - none, // value not yet computed - no, // value is false - yes, // value is true -}; - FuncDeclaration *search_toString(StructDeclaration *sd); enum class ClassKind : uint8_t diff --git a/gcc/d/dmd/aliasthis.d b/gcc/d/dmd/aliasthis.d index 2771071b..ef839fa 100644 --- a/gcc/d/dmd/aliasthis.d +++ b/gcc/d/dmd/aliasthis.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/class.html#alias-this, Alias This) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/aliasthis.d, _aliasthis.d) @@ -21,6 +21,7 @@ import dmd.expression; import dmd.expressionsem; import dmd.globals; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.opover; import dmd.tokens; @@ -94,7 +95,7 @@ Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false, bool find Type tthis = (e.op == EXP.type ? e.type : null); const flags = DotExpFlag.noAliasThis | (gag ? DotExpFlag.gag : 0); uint olderrors = gag ? global.startGagging() : 0; - e = dotExp(e.type, sc, e, ad.aliasthis.ident, flags); + e = dotExp(ad.type, sc, e, ad.aliasthis.ident, flags); if (!e || findOnly) return gag && global.endGagging(olderrors) ? null : e; diff --git a/gcc/d/dmd/aliasthis.h b/gcc/d/dmd/aliasthis.h index c63d717..389cff4 100644 --- a/gcc/d/dmd/aliasthis.h +++ b/gcc/d/dmd/aliasthis.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 2009-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 2009-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/apply.d b/gcc/d/dmd/apply.d index 3b73771..f5855c4 100644 --- a/gcc/d/dmd/apply.d +++ b/gcc/d/dmd/apply.d @@ -1,7 +1,7 @@ /** * A depth-first visitor for expressions. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/apply.d, _apply.d) diff --git a/gcc/d/dmd/arrayop.d b/gcc/d/dmd/arrayop.d index f07a6f4..da2f800 100644 --- a/gcc/d/dmd/arrayop.d +++ b/gcc/d/dmd/arrayop.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/arrays.html#array-operations, Array Operations) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/arrayop.d, _arrayop.d) @@ -26,6 +26,7 @@ import dmd.globals; import dmd.hdrgen; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.common.outbuffer; import dmd.statement; diff --git a/gcc/d/dmd/arraytypes.d b/gcc/d/dmd/arraytypes.d index 29b3a3d..34ffa6e 100644 --- a/gcc/d/dmd/arraytypes.d +++ b/gcc/d/dmd/arraytypes.d @@ -1,7 +1,7 @@ /** * Provide aliases for arrays of certain declarations or statements. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/arraytypes.d, _arraytypes.d) diff --git a/gcc/d/dmd/arraytypes.h b/gcc/d/dmd/arraytypes.h index ca2051c..05126a5 100644 --- a/gcc/d/dmd/arraytypes.h +++ b/gcc/d/dmd/arraytypes.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 2006-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 2006-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/ast_node.d b/gcc/d/dmd/ast_node.d index 843cc02..c0dd186 100644 --- a/gcc/d/dmd/ast_node.d +++ b/gcc/d/dmd/ast_node.d @@ -1,7 +1,7 @@ /** * Defines the base class for all nodes which are part of the AST. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ast_node.d, _ast_node.d) diff --git a/gcc/d/dmd/ast_node.h b/gcc/d/dmd/ast_node.h index 0e04e38..6154c6d 100644 --- a/gcc/d/dmd/ast_node.h +++ b/gcc/d/dmd/ast_node.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/astenums.d b/gcc/d/dmd/astenums.d index 091e96a..6e88208 100644 --- a/gcc/d/dmd/astenums.d +++ b/gcc/d/dmd/astenums.d @@ -1,7 +1,7 @@ /** * Defines enums common to dmd and dmd as parse library. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/astenums.d, _astenums.d) * Documentation: https://dlang.org/phobos/dmd_astenums.html diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d index 55d69b5..712099e 100644 --- a/gcc/d/dmd/attrib.d +++ b/gcc/d/dmd/attrib.d @@ -14,7 +14,7 @@ * - Protection (`private`, `public`) * - Deprecated declarations (`@deprecated`) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/attrib.d, _attrib.d) @@ -40,6 +40,7 @@ import dmd.globals; import dmd.hdrgen : visibilityToBuffer; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.objc; // for objc.addSymbols import dmd.common.outbuffer; diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h index b153229..96c46e8 100644 --- a/gcc/d/dmd/attrib.h +++ b/gcc/d/dmd/attrib.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d index 6456876..6369b5a 100644 --- a/gcc/d/dmd/blockexit.d +++ b/gcc/d/dmd/blockexit.d @@ -1,7 +1,7 @@ /** * Find out in what ways control flow can exit a statement block. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/blockexit.d, _blockexit.d) @@ -23,6 +23,7 @@ import dmd.func; import dmd.globals; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.statement; import dmd.tokens; diff --git a/gcc/d/dmd/builtin.d b/gcc/d/dmd/builtin.d index 06db97b..27ba1e0 100644 --- a/gcc/d/dmd/builtin.d +++ b/gcc/d/dmd/builtin.d @@ -3,7 +3,7 @@ * * Currently includes functions from `std.math`, `core.math` and `core.bitop`. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/builtin.d, _builtin.d) @@ -16,7 +16,7 @@ module dmd.builtin; import dmd.arraytypes; import dmd.expression; import dmd.func; -import dmd.globals; +import dmd.location; /********************************** * Determine if function is a builtin one that we can diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d index cb9289fd..7c18040 100644 --- a/gcc/d/dmd/canthrow.d +++ b/gcc/d/dmd/canthrow.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/function.html#nothrow-functions, Nothrow Functions) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/canthrow.d, _canthrow.d) diff --git a/gcc/d/dmd/chkformat.d b/gcc/d/dmd/chkformat.d index 8204961..21a1b5e 100644 --- a/gcc/d/dmd/chkformat.d +++ b/gcc/d/dmd/chkformat.d @@ -1,7 +1,7 @@ /** * Check the arguments to `printf` and `scanf` against the `format` string. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/chkformat.d, _chkformat.d) @@ -19,6 +19,7 @@ import dmd.errors; import dmd.expression; import dmd.globals; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.target; diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index c030d35..ef5464d 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -2,7 +2,7 @@ * Builds struct member functions if needed and not defined by the user. * Includes `opEquals`, `opAssign`, post blit, copy constructor and destructor. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/clone.d, _clone.d) @@ -31,6 +31,7 @@ import dmd.globals; import dmd.id; import dmd.identifier; import dmd.init; +import dmd.location; import dmd.mtype; import dmd.opover; import dmd.semantic2; diff --git a/gcc/d/dmd/common/bitfields.d b/gcc/d/dmd/common/bitfields.d index bba61ad..b9fcb09 100644 --- a/gcc/d/dmd/common/bitfields.d +++ b/gcc/d/dmd/common/bitfields.d @@ -1,7 +1,7 @@ /** * A library bitfields utility * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Dennis Korpel * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/bitfields.d, common/bitfields.d) diff --git a/gcc/d/dmd/common/file.d b/gcc/d/dmd/common/file.d index 89e7027..ae13c41 100644 --- a/gcc/d/dmd/common/file.d +++ b/gcc/d/dmd/common/file.d @@ -4,7 +4,7 @@ * Functions and objects dedicated to file I/O and management. TODO: Move here artifacts * from places such as root/ so both the frontend and the backend have access to them. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/file.d, common/_file.d) diff --git a/gcc/d/dmd/common/outbuffer.d b/gcc/d/dmd/common/outbuffer.d index 9d544a4..276928a 100644 --- a/gcc/d/dmd/common/outbuffer.d +++ b/gcc/d/dmd/common/outbuffer.d @@ -1,7 +1,7 @@ /** * An expandable buffer in which you can write text or binary data. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/outbuffer.d, root/_outbuffer.d) diff --git a/gcc/d/dmd/common/outbuffer.h b/gcc/d/dmd/common/outbuffer.h index fed25c0..b672842 100644 --- a/gcc/d/dmd/common/outbuffer.h +++ b/gcc/d/dmd/common/outbuffer.h @@ -1,5 +1,5 @@ -/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved +/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/common/string.d b/gcc/d/dmd/common/string.d index 48bf9bb..1111cec 100644 --- a/gcc/d/dmd/common/string.d +++ b/gcc/d/dmd/common/string.d @@ -1,7 +1,7 @@ /** * Common string functions including filename manipulation. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/string.d, common/_string.d) diff --git a/gcc/d/dmd/compiler.d b/gcc/d/dmd/compiler.d index dd26d40..68ec1d3 100644 --- a/gcc/d/dmd/compiler.d +++ b/gcc/d/dmd/compiler.d @@ -1,7 +1,7 @@ /** * Describes a back-end compiler and implements compiler-specific actions. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/compiler.d, _compiler.d) diff --git a/gcc/d/dmd/compiler.h b/gcc/d/dmd/compiler.h index e8b7704..c7cbce3 100644 --- a/gcc/d/dmd/compiler.h +++ b/gcc/d/dmd/compiler.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d index c1e1e4d..c0c4cf1 100644 --- a/gcc/d/dmd/cond.d +++ b/gcc/d/dmd/cond.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/version.html, Conditional Compilation) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cond.d, _cond.d) @@ -26,6 +26,7 @@ import dmd.expression; import dmd.expressionsem; import dmd.globals; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.typesem; import dmd.common.outbuffer; @@ -80,6 +81,11 @@ extern (C++) abstract class Condition : ASTNode return null; } + inout(StaticIfCondition) isStaticIfCondition() inout + { + return null; + } + override void accept(Visitor v) { v.visit(this); @@ -218,12 +224,12 @@ extern (C++) final class StaticForeach : RootObject { if (aggrfe) { - return new ForeachStatement(loc, aggrfe.op, parameters, aggrfe.aggr.syntaxCopy(), s, loc); + return new ForeachStatement(loc, aggrfe.op, parameters, aggrfe.aggr, s, loc); } else { assert(rangefe && parameters.length == 1); - return new ForeachRangeStatement(loc, rangefe.op, (*parameters)[0], rangefe.lwr.syntaxCopy(), rangefe.upr.syntaxCopy(), s, loc); + return new ForeachRangeStatement(loc, rangefe.op, (*parameters)[0], rangefe.lwr, rangefe.upr, s, loc); } } @@ -953,6 +959,11 @@ extern (C++) final class StaticIfCondition : Condition v.visit(this); } + override inout(StaticIfCondition) isStaticIfCondition() inout + { + return this; + } + override const(char)* toChars() const { return exp ? exp.toChars() : "static if".ptr; diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h index b33f288..422a715 100644 --- a/gcc/d/dmd/cond.h +++ b/gcc/d/dmd/cond.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d index ef684ba..79bbd5d 100644 --- a/gcc/d/dmd/constfold.d +++ b/gcc/d/dmd/constfold.d @@ -5,7 +5,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/float.html#fp_const_folding, Floating Point Constant Folding) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/constfold.d, _constfold.d) @@ -25,6 +25,7 @@ import dmd.dstruct; import dmd.errors; import dmd.expression; import dmd.globals; +import dmd.location; import dmd.mtype; import dmd.root.complex; import dmd.root.ctfloat; @@ -1249,7 +1250,14 @@ UnionExp Slice(Type type, Expression e1, Expression lwr, Expression upr) } } - if (e1.op == EXP.string_ && lwr.op == EXP.int64 && upr.op == EXP.int64) + if (!lwr) + { + if (e1.op == EXP.string_) + emplaceExp(&ue, e1); + else + cantExp(ue); + } + else if (e1.op == EXP.string_ && lwr.op == EXP.int64 && upr.op == EXP.int64) { StringExp es1 = e1.isStringExp(); const uinteger_t ilwr = lwr.toInteger(); diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index d4416ab..a6bc42b 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -3,7 +3,7 @@ * * Specification: C11 * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cparse.d, _cparse.d) @@ -20,6 +20,7 @@ import dmd.globals; import dmd.id; import dmd.identifier; import dmd.lexer; +import dmd.location; import dmd.parse; import dmd.errors; import dmd.root.array; diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d index fbe9f01..d3effa99 100644 --- a/gcc/d/dmd/cppmangle.d +++ b/gcc/d/dmd/cppmangle.d @@ -4,7 +4,7 @@ * This is the POSIX side of the implementation. * It exports two functions to C++, `toCppMangleItanium` and `cppTypeInfoMangleItanium`. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cppmangle.d, _cppmangle.d) @@ -38,6 +38,7 @@ import dmd.func; import dmd.globals; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.nspace; import dmd.root.array; diff --git a/gcc/d/dmd/ctfe.h b/gcc/d/dmd/ctfe.h index ab022ff..1071edf 100644 --- a/gcc/d/dmd/ctfe.h +++ b/gcc/d/dmd/ctfe.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d index 1dc1f7d..c902149 100644 --- a/gcc/d/dmd/ctfeexpr.d +++ b/gcc/d/dmd/ctfeexpr.d @@ -1,7 +1,7 @@ /** * CTFE for expressions involving pointers, slices, array concatenation etc. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ctfeexpr.d, _ctfeexpr.d) @@ -27,6 +27,7 @@ import dmd.errors; import dmd.expression; import dmd.func; import dmd.globals; +import dmd.location; import dmd.mtype; import dmd.root.complex; import dmd.root.ctfloat; diff --git a/gcc/d/dmd/ctorflow.d b/gcc/d/dmd/ctorflow.d index c04793d..a3953af 100644 --- a/gcc/d/dmd/ctorflow.d +++ b/gcc/d/dmd/ctorflow.d @@ -1,7 +1,7 @@ /** * Manage flow analysis for constructors. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ctorflow.d, _ctorflow.d) @@ -14,7 +14,7 @@ module dmd.ctorflow; import core.stdc.stdio; import dmd.root.rmem; -import dmd.globals : Loc; +import dmd.location; enum CSX : ushort { diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 02bf6cf..b305360 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -1,7 +1,7 @@ /** * Semantic analysis for cast-expressions. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dcast.d, _dcast.d) @@ -30,6 +30,7 @@ import dmd.expressionsem; import dmd.func; import dmd.globals; import dmd.hdrgen; +import dmd.location; import dmd.impcnvtab; import dmd.id; import dmd.importc; @@ -66,10 +67,14 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t) { Expression visit(Expression e) { - //printf("Expression.implicitCastTo(%s of type %s) => %s\n", e.toChars(), e.type.toChars(), t.toChars()); + // printf("Expression.implicitCastTo(%s of type %s) => %s\n", e.toChars(), e.type.toChars(), t.toChars()); if (const match = (sc && sc.flags & SCOPE.Cfile) ? e.cimplicitConvTo(t) : e.implicitConvTo(t)) { + if (match == MATCH.convert && e.type.isTypeNoreturn()) + { + return specialNoreturnCast(e, t); + } if (match == MATCH.constant && (e.type.constConv(t) || !e.isLvalue() && e.type.equivalent(t))) { /* Do not emit CastExp for const conversions and @@ -1526,6 +1531,10 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) { return e; } + if (e.type.isTypeNoreturn()) + { + return specialNoreturnCast(e, t); + } if (auto ve = e.isVarExp()) { VarDeclaration v = ve.var.isVarDeclaration(); @@ -2539,7 +2548,12 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) // Handle the cast from Tarray to Tsarray with CT-known slicing - TypeSArray tsa = toStaticArrayType(e).isTypeSArray(); + TypeSArray tsa; + { + Type t = toStaticArrayType(e); + tsa = t ? t.isTypeSArray() : null; + } + if (tsa && tsa.size(e.loc) == tb.size(e.loc)) { /* Match if the sarray sizes are equal: @@ -3858,3 +3872,21 @@ IntRange getIntRange(Expression e) case EXP.negate : return visitNeg(e.isNegExp()); } } +/** + * A helper function to "cast" from expressions of type noreturn to + * any other type - noreturn is implicitly convertible to any other type. + * However, the dmd backend does not like a naive cast from a noreturn expression + * (particularly an `assert(0)`) so this function generates: + * + * `(assert(0), value)` instead of `cast(to)(assert(0))`. + * + * `value` is currently `to.init` however it cannot be read so could be made simpler. + * Params: + * toBeCasted = Expression of type noreturn to cast + * to = Type to cast the expression to. + * Returns: A CommaExp, upon any failure ErrorExp will be returned. + */ +Expression specialNoreturnCast(Expression toBeCasted, Type to) +{ + return Expression.combine(toBeCasted, to.defaultInitLiteral(toBeCasted.loc)); +} diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d index fc49b21..1fdd073 100644 --- a/gcc/d/dmd/dclass.d +++ b/gcc/d/dmd/dclass.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/class.html, Classes) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dclass.d, _dclass.d) @@ -30,6 +30,7 @@ import dmd.func; import dmd.globals; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.objc; import dmd.root.rmem; @@ -468,7 +469,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration { //printf("%s.ClassDeclaration.search('%s', flags=x%x)\n", toChars(), ident.toChars(), flags); //if (_scope) printf("%s baseok = %d\n", toChars(), baseok); - if (_scope && baseok < Baseok.done) + if (_scope && baseok < Baseok.semanticdone) { if (!inuse) { diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index 3d0752c..51737ce 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -2,7 +2,7 @@ * Miscellaneous declarations, including typedef, alias, variable declarations including the * implicit this declaration, type tuples, ClassInfo, ModuleInfo and various TypeInfos. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/declaration.d, _declaration.d) @@ -35,6 +35,7 @@ import dmd.identifier; import dmd.init; import dmd.initsem; import dmd.intrange; +import dmd.location; import dmd.mtype; import dmd.common.outbuffer; import dmd.root.rootobject; @@ -81,6 +82,9 @@ bool checkFrameAccess(Loc loc, Scope* sc, AggregateDeclaration ad, size_t iStart /*********************************************** * Mark variable v as modified if it is inside a constructor that var * is a field in. + * Also used to allow immutable globals to be initialized inside a static constructor. + * Returns: + * true if it's an initialization of v */ bool modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e1) { @@ -93,7 +97,7 @@ bool modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e1) fd = s.isFuncDeclaration(); if (fd && ((fd.isCtorDeclaration() && var.isField()) || - (fd.isStaticCtorDeclaration() && !var.isField())) && + ((fd.isStaticCtorDeclaration() || fd.isCrtCtor) && !var.isField())) && fd.toParentDecl() == var.toParent2() && (!e1 || e1.op == EXP.this_)) { diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index 2668b6e..5d5c423 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d index 461f441..3f982b3 100644 --- a/gcc/d/dmd/delegatize.d +++ b/gcc/d/dmd/delegatize.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/function.html#lazy-params, Lazy Parameters) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/delegatize.d, _delegatize.d) @@ -25,6 +25,7 @@ import dmd.func; import dmd.globals; import dmd.init; import dmd.initsem; +import dmd.location; import dmd.mtype; import dmd.statement; import dmd.tokens; diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d index 926186b..221250b 100644 --- a/gcc/d/dmd/denum.d +++ b/gcc/d/dmd/denum.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/enum.html, Enums) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/denum.d, _denum.d) @@ -28,6 +28,7 @@ import dmd.globals; import dmd.id; import dmd.identifier; import dmd.init; +import dmd.location; import dmd.mtype; import dmd.tokens; import dmd.typesem; diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d index 1104005..b653d9b 100644 --- a/gcc/d/dmd/dimport.d +++ b/gcc/d/dmd/dimport.d @@ -1,7 +1,7 @@ /** * A `Dsymbol` representing a renamed import. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dimport.d, _dimport.d) @@ -22,6 +22,7 @@ import dmd.errors; import dmd.expression; import dmd.globals; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.visitor; diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index e504cb4..7920df7 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -3,7 +3,7 @@ * * Specification: ($LINK2 https://dlang.org/spec/function.html#interpretation, Compile Time Function Execution (CTFE)) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dinterpret.d, _dinterpret.d) @@ -39,6 +39,7 @@ import dmd.id; import dmd.identifier; import dmd.init; import dmd.initsem; +import dmd.location; import dmd.mtype; import dmd.printast; import dmd.root.rmem; @@ -165,7 +166,7 @@ public Expression ctfeInterpretForPragmaMsg(Expression e) return e; } -public extern (C++) Expression getValue(VarDeclaration vd) +public Expression getValue(VarDeclaration vd) { return ctfeGlobals.stack.getValue(vd); } @@ -280,25 +281,25 @@ private: Expression localThis; // value of 'this', or NULL if none public: - extern (C++) size_t stackPointer() + size_t stackPointer() { return values.length; } // The current value of 'this', or NULL if none - extern (C++) Expression getThis() + Expression getThis() { return localThis; } // Largest number of stack positions we've used - extern (C++) size_t maxStackUsage() + size_t maxStackUsage() { return maxStackPointer; } // Start a new stack frame, using the provided 'this'. - extern (C++) void startFrame(Expression thisexp) + void startFrame(Expression thisexp) { frames.push(cast(void*)cast(size_t)framepointer); savedThis.push(localThis); @@ -306,7 +307,7 @@ public: localThis = thisexp; } - extern (C++) void endFrame() + void endFrame() { size_t oldframe = cast(size_t)frames[frames.length - 1]; localThis = savedThis[savedThis.length - 1]; @@ -316,14 +317,14 @@ public: savedThis.setDim(savedThis.length - 1); } - extern (C++) bool isInCurrentFrame(VarDeclaration v) + bool isInCurrentFrame(VarDeclaration v) { if (v.isDataseg() && !v.isCTFE()) return false; // It's a global return v.ctfeAdrOnStack >= framepointer; } - extern (C++) Expression getValue(VarDeclaration v) + Expression getValue(VarDeclaration v) { //printf("getValue() %s\n", v.toChars()); if ((v.isDataseg() || v.storage_class & STC.manifest) && !v.isCTFE()) @@ -335,7 +336,7 @@ public: return values[v.ctfeAdrOnStack]; } - extern (C++) void setValue(VarDeclaration v, Expression e) + void setValue(VarDeclaration v, Expression e) { //printf("setValue() %s : %s\n", v.toChars(), e.toChars()); assert(!v.isDataseg() || v.isCTFE()); @@ -343,7 +344,7 @@ public: values[v.ctfeAdrOnStack] = e; } - extern (C++) void push(VarDeclaration v) + void push(VarDeclaration v) { //printf("push() %s\n", v.toChars()); assert(!v.isDataseg() || v.isCTFE()); @@ -359,7 +360,7 @@ public: values.push(null); } - extern (C++) void pop(VarDeclaration v) + void pop(VarDeclaration v) { assert(!v.isDataseg() || v.isCTFE()); assert(!v.isReference()); @@ -373,7 +374,7 @@ public: } } - extern (C++) void popAll(size_t stackpointer) + void popAll(size_t stackpointer) { if (stackPointer() > maxStackPointer) maxStackPointer = stackPointer(); @@ -388,7 +389,7 @@ public: savedId.setDim(stackpointer); } - extern (C++) void saveGlobalConstant(VarDeclaration v, Expression e) + void saveGlobalConstant(VarDeclaration v, Expression e) { assert(v._init && (v.isConst() || v.isImmutable() || v.storage_class & STC.manifest) && !v.isCTFE()); v.ctfeAdrOnStack = cast(uint)globalValues.length; @@ -1529,7 +1530,7 @@ public: } // Little sanity check to make sure it's really a Throwable ClassReferenceExp boss = oldest.thrown; - const next = 4; // index of Throwable.next + const next = 5; // index of Throwable.next assert((*boss.value.elements)[next].type.ty == Tclass); // Throwable.next ClassReferenceExp collateral = newest.thrown; if (collateral.originalClass().isErrorException() && !boss.originalClass().isErrorException()) @@ -1849,10 +1850,27 @@ public: { printf("%s StringExp::interpret() %s\n", e.loc.toChars(), e.toChars()); } - /* Attempts to modify string literals are prevented - * in BinExp::interpretAssignCommon. - */ - result = e; + if (e.ownedByCtfe >= OwnedBy.ctfe) // We've already interpreted the string + { + result = e; + return; + } + + if (e.type.ty != Tsarray || + (cast(TypeNext)e.type).next.mod & (MODFlags.const_ | MODFlags.immutable_)) + { + // If it's immutable, we don't need to dup it. Attempts to modify + // string literals are prevented in BinExp::interpretAssignCommon. + result = e; + } + else + { + // https://issues.dlang.org/show_bug.cgi?id=20811 + // Create a copy of mutable string literals, so that any change in + // value via an index or slice will not survive CTFE. + *pue = copyLiteral(e); + result = pue.exp(); + } } override void visit(FuncExp e) @@ -4287,12 +4305,12 @@ public: bool needsPostblit; bool needsDtor; - extern (C++) Expression assignTo(ArrayLiteralExp ae) + Expression assignTo(ArrayLiteralExp ae) { return assignTo(ae, 0, ae.elements.length); } - extern (C++) Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr) + Expression assignTo(ArrayLiteralExp ae, size_t lwr, size_t upr) { Expressions* w = ae.elements; assert(ae.type.ty == Tsarray || ae.type.ty == Tarray); @@ -6178,7 +6196,7 @@ public: { debug (LOG) { - printf("%s ThrowExpression::interpret()\n", e.loc.toChars()); + printf("%s ThrowExpression::interpret()\n", te.loc.toChars()); } interpretThrow(te.e1, te.loc); } diff --git a/gcc/d/dmd/dmacro.d b/gcc/d/dmd/dmacro.d index 358712b..6fc23e9 100644 --- a/gcc/d/dmd/dmacro.d +++ b/gcc/d/dmd/dmacro.d @@ -1,7 +1,7 @@ /** * Text macro processor for Ddoc. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmacro.d, _dmacro.d) diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d index 6ecaa52..867d3ca 100644 --- a/gcc/d/dmd/dmangle.d +++ b/gcc/d/dmd/dmangle.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/abi.html#name_mangling, Name Mangling) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmangle.d, _dmangle.d) diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index 6160805..e1234e5 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/module.html, Modules) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmodule.d, _dmodule.d) @@ -35,6 +35,7 @@ import dmd.file_manager; import dmd.globals; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.parse; import dmd.cparse; import dmd.root.array; @@ -359,7 +360,8 @@ extern (C++) final class Module : Package Package pkg; // if isPackageFile is true, the Package that contains this package.d Strings contentImportedFiles; // array of files whose content was imported int needmoduleinfo; - int selfimports; // 0: don't know, 1: does not, 2: does + private ThreeState selfimports; + private ThreeState rootimports; Dsymbol[void*] tagSymTab; /// ImportC: tag symbols that conflict with other symbols used as the index private OutBuffer defines; // collect all the #define lines here @@ -371,48 +373,46 @@ extern (C++) final class Module : Package bool selfImports() { //printf("Module::selfImports() %s\n", toChars()); - if (selfimports == 0) + if (selfimports == ThreeState.none) { foreach (Module m; amodules) - m.insearch = 0; - selfimports = imports(this) + 1; + m.insearch = false; + selfimports = imports(this) ? ThreeState.yes : ThreeState.no; foreach (Module m; amodules) - m.insearch = 0; + m.insearch = false; } - return selfimports == 2; + return selfimports == ThreeState.yes; } - int rootimports; // 0: don't know, 1: does not, 2: does - /************************************* * Return true if module imports root module. */ bool rootImports() { //printf("Module::rootImports() %s\n", toChars()); - if (rootimports == 0) + if (rootimports == ThreeState.none) { foreach (Module m; amodules) - m.insearch = 0; - rootimports = 1; + m.insearch = false; + rootimports = ThreeState.no; foreach (Module m; amodules) { if (m.isRoot() && imports(m)) { - rootimports = 2; + rootimports = ThreeState.yes; break; } } foreach (Module m; amodules) - m.insearch = 0; + m.insearch = false; } - return rootimports == 2; + return rootimports == ThreeState.yes; } - int insearch; - Identifier searchCacheIdent; - Dsymbol searchCacheSymbol; // cached value of search - int searchCacheFlags; // cached flags + private Identifier searchCacheIdent; + private Dsymbol searchCacheSymbol; // cached value of search + private int searchCacheFlags; // cached flags + private bool insearch; /** * A root module is one that will be compiled all the way to @@ -1041,9 +1041,9 @@ extern (C++) final class Module : Package uint errors = global.errors; - insearch = 1; + insearch = true; Dsymbol s = ScopeDsymbol.search(loc, ident, flags); - insearch = 0; + insearch = false; if (errors == global.errors) { @@ -1214,7 +1214,7 @@ extern (C++) final class Module : Package return true; if (!mi.insearch) { - mi.insearch = 1; + mi.insearch = true; int r = mi.imports(m); if (r) return r; @@ -1284,6 +1284,59 @@ extern (C++) final class Module : Package _escapetable = new Escape(); return _escapetable; } + + /**************************** + * A Singleton that loads core.atomic + * Returns: + * Module of core.atomic, null if couldn't find it + */ + extern (D) static Module loadCoreAtomic() + { + __gshared Module core_atomic; + return loadModuleFromLibrary(core_atomic, Id.core, Id.atomic); + } + + /**************************** + * A Singleton that loads std.math + * Returns: + * Module of std.math, null if couldn't find it + */ + extern (D) static Module loadStdMath() + { + __gshared Module std_math; + return loadModuleFromLibrary(std_math, Id.std, Id.math); + } + + /********************************** + * Load a Module from the library. + * Params: + * mod = cached return value of this call + * pkgid = package id + * modid = module id + * Returns: + * Module loaded, null if cannot load it + */ + private static Module loadModuleFromLibrary(ref Module mod, Identifier pkgid, Identifier modid) + { + if (mod) + return mod; + + auto ids = new Identifier[1]; + ids[0] = pkgid; + auto imp = new Import(Loc.initial, ids[], modid, null, true); + // Module.load will call fatal() if there's no module available. + // Gag the error here, pushing the error handling to the caller. + const errors = global.startGagging(); + imp.load(null); + if (imp.mod) + { + imp.mod.importAll(null); + imp.mod.dsymbolSemantic(null); + } + global.endGagging(errors); + mod = imp.mod; + return mod; + } } /*********************************************************** diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d index c04409c4..732a737 100644 --- a/gcc/d/dmd/doc.d +++ b/gcc/d/dmd/doc.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/ddoc.html, Documentation Generator) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/doc.d, _doc.d) @@ -41,6 +41,7 @@ import dmd.hdrgen; import dmd.id; import dmd.identifier; import dmd.lexer; +import dmd.location; import dmd.mtype; import dmd.root.array; import dmd.root.file; @@ -5181,7 +5182,8 @@ private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t of { uint errorsave = global.startGagging(); - scope Lexer lex = new Lexer(null, cast(char*)buf[].ptr, 0, buf.length - 1, 0, 1); + scope Lexer lex = new Lexer(null, cast(char*)buf[].ptr, 0, buf.length - 1, 0, 1, + global.vendor, global.versionNumber()); OutBuffer res; const(char)* lastp = cast(char*)buf[].ptr; //printf("highlightCode2('%.*s')\n", cast(int)(buf.length - 1), buf[].ptr); diff --git a/gcc/d/dmd/doc.h b/gcc/d/dmd/doc.h index 8dc2d9f..d16806b 100644 --- a/gcc/d/dmd/doc.h +++ b/gcc/d/dmd/doc.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d index 362e7f2..8f19626 100644 --- a/gcc/d/dmd/dscope.d +++ b/gcc/d/dmd/dscope.d @@ -3,7 +3,7 @@ * * Not to be confused with the `scope` storage class. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dscope.d, _dscope.d) @@ -33,6 +33,7 @@ import dmd.func; import dmd.globals; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.common.outbuffer; import dmd.root.rmem; import dmd.root.speller; diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d index 2115fda..6ab93d4 100644 --- a/gcc/d/dmd/dstruct.d +++ b/gcc/d/dmd/dstruct.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/struct.html, Structs, Unions) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dstruct.d, _dstruct.d) @@ -29,6 +29,7 @@ import dmd.func; import dmd.globals; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.opover; import dmd.target; diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index 2cf5500..3611e09 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -1,7 +1,7 @@ /** * The base class for a D symbol, which can be a module, variable, function, enum, etc. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dsymbol.d, _dsymbol.d) @@ -42,6 +42,7 @@ import dmd.id; import dmd.identifier; import dmd.init; import dmd.lexer; +import dmd.location; import dmd.mtype; import dmd.nspace; import dmd.opover; diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h index 3e9b634..88110e1 100644 --- a/gcc/d/dmd/dsymbol.h +++ b/gcc/d/dmd/dsymbol.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. @@ -87,6 +87,13 @@ struct Ungag ~Ungag() { global.gag = oldgag; } }; +enum class ThreeState : uint8_t +{ + none, // value not yet computed + no, // value is false + yes, // value is true +}; + void dsymbolSemantic(Dsymbol *dsym, Scope *sc); void semantic2(Dsymbol *dsym, Scope *sc); void semantic3(Dsymbol *dsym, Scope* sc); diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index b842dc8..49e1c59 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -2,7 +2,7 @@ * Does the semantic 1 pass on the AST, which looks at symbol declarations but not initializers * or function bodies. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dsymbolsem.d, _dsymbolsem.d) @@ -51,6 +51,7 @@ import dmd.init; import dmd.initsem; import dmd.intrange; import dmd.hdrgen; +import dmd.location; import dmd.mtype; import dmd.mustuse; import dmd.nogc; @@ -1594,6 +1595,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (pd.ident == Id.printf || pd.ident == Id.scanf) { s.setPragmaPrintf(pd.ident == Id.printf); + s.dsymbolSemantic(sc2); continue; } @@ -2310,6 +2312,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor auto inneruda = em.userAttribDecl.userAttribDecl; em.userAttribDecl.setScope(sc); em.userAttribDecl.userAttribDecl = inneruda; + em.userAttribDecl.dsymbolSemantic(sc); } // The first enum member is special @@ -2464,8 +2467,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor e = e.ctfeInterpret(); if (e.toInteger()) { + auto mt = em.ed.memtype; + if (!mt) + mt = eprev.type; em.error("initialization with `%s.%s+1` causes overflow for type `%s`", - emprev.ed.toChars(), emprev.toChars(), em.ed.memtype.toChars()); + emprev.ed.toChars(), emprev.toChars(), mt.toChars()); return errorReturn(); } @@ -5165,6 +5171,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } // Copy vtbl[] from base class + assert(cldec.vtbl.length == 0); cldec.vtbl.setDim(cldec.baseClass.vtbl.length); memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.length); @@ -5205,7 +5212,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor cldec.baseClass.toChars(), cldec.baseClass.toParentLocal().toChars()); } - cldec.enclosing = null; } if (cldec.vthis2) { @@ -5378,10 +5384,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor cldec.error("already exists at %s. Perhaps in another function with the same name?", cd.loc.toChars()); } - if (global.errors != errors) + if (global.errors != errors || (cldec.baseClass && cldec.baseClass.errors)) { - // The type is no good. - cldec.type = Type.terror; + // The type is no good, but we should keep the + // the type so that we have more accurate error messages + // See: https://issues.dlang.org/show_bug.cgi?id=23552 cldec.errors = true; if (cldec.deferred) cldec.deferred.errors = true; @@ -7073,33 +7080,13 @@ bool determineFields(AggregateDeclaration ad) /// Do an atomic operation (currently tailored to [shared] static ctors|dtors) needs private CallExp doAtomicOp (string op, Identifier var, Expression arg) { - __gshared Import imp = null; - __gshared Identifier[1] id; - assert(op == "-=" || op == "+="); - const loc = Loc.initial; + Module mod = Module.loadCoreAtomic(); + if (!mod) + return null; // core.atomic couldn't be loaded - // Below code is similar to `loadStdMath` (used for `^^` operator) - if (!imp) - { - id[0] = Id.core; - auto s = new Import(Loc.initial, id[], Id.atomic, null, true); - // Module.load will call fatal() if there's no std.math available. - // Gag the error here, pushing the error handling to the caller. - uint errors = global.startGagging(); - s.load(null); - if (s.mod) - { - s.mod.importAll(null); - s.mod.dsymbolSemantic(null); - } - global.endGagging(errors); - imp = s; - } - // Module couldn't be loaded - if (imp.mod is null) - return null; + const loc = Loc.initial; Objects* tiargs = new Objects(1); (*tiargs)[0] = new StringExp(loc, op); @@ -7108,7 +7095,7 @@ private CallExp doAtomicOp (string op, Identifier var, Expression arg) (*args)[0] = new IdentifierExp(loc, var); (*args)[1] = arg; - auto sc = new ScopeExp(loc, imp.mod); + auto sc = new ScopeExp(loc, mod); auto dti = new DotTemplateInstanceExp( loc, sc, Id.atomicOp, tiargs); diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index 6095dcc..32799aa 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -28,7 +28,7 @@ * arguments, and uses it if found. * - Otherwise, the rest of semantic is run on the `TemplateInstance`. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dtemplate.d, _dtemplate.d) @@ -64,6 +64,7 @@ import dmd.identifier; import dmd.impcnvtab; import dmd.init; import dmd.initsem; +import dmd.location; import dmd.mtype; import dmd.opover; import dmd.root.array; @@ -567,7 +568,6 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol bool isTrivialAlias; /// matches pattern `template Alias(T) { alias Alias = qualifiers(T); }` bool deprecated_; /// this template declaration is deprecated Visibility visibility; - int inuse; /// for recursive expansion detection // threaded list of previous instantiation attempts on stack TemplatePrevious* previous; @@ -1117,9 +1117,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol printf("\tparameter[%d] is %s : %s\n", i, tp.ident.toChars(), ttp.specType ? ttp.specType.toChars() : ""); } - inuse++; m2 = tp.matchArg(ti.loc, paramscope, ti.tiargs, i, parameters, dedtypes, &sparam); - inuse--; //printf("\tm2 = %d\n", m2); if (m2 == MATCH.nomatch) { @@ -1783,9 +1781,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol } else { - inuse++; oded = tparam.defaultArg(instLoc, paramscope); - inuse--; if (oded) (*dedargs)[i] = declareParameter(paramscope, tparam, oded); } @@ -2166,9 +2162,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol } else { - inuse++; oded = tparam.defaultArg(instLoc, paramscope); - inuse--; if (!oded) { // if tuple parameter and @@ -2813,11 +2807,6 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, int applyTemplate(TemplateDeclaration td) { //printf("applyTemplate()\n"); - if (td.inuse) - { - td.error(loc, "recursive template expansion"); - return 1; - } if (td == td_best) // skip duplicates return 0; @@ -3613,8 +3602,29 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param } // Found the corresponding parameter tp + /+ + https://issues.dlang.org/show_bug.cgi?id=23578 + To pattern match: + static if (is(S!int == S!av, alias av)) + + We eventually need to deduce `int` (Tint32 [0]) and `av` (Tident). + Previously this would not get pattern matched at all, but now we check if the + template parameter `av` came from. + + This note has been left to serve as a hint for further explorers into + how IsExp matching works. + +/ + if (auto ta = tp.isTemplateAliasParameter()) + { + (*dedtypes)[i] = t; + goto Lexact; + } + // (23578) - ensure previous behaviour for non-alias template params if (!tp.isTemplateTypeParameter()) + { goto Lnomatch; + } + Type at = cast(Type)(*dedtypes)[i]; Type tt; if (ubyte wx = wm ? deduceWildHelper(t, &tt, tparam) : 0) @@ -4100,6 +4110,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param } goto Lnomatch; } + TemplateParameter tpx = (*parameters)[i]; if (!tpx.matchArg(sc, tempdecl, i, parameters, dedtypes, null)) goto Lnomatch; @@ -4110,7 +4121,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param L2: for (size_t i = 0; 1; i++) { - //printf("\ttest: tempinst.tiargs[%d]\n", i); + //printf("\ttest: tempinst.tiargs[%zu]\n", i); RootObject o1 = null; if (i < t.tempinst.tiargs.length) o1 = (*t.tempinst.tiargs)[i]; @@ -4121,7 +4132,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param } 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); @@ -4136,7 +4147,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param 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 && @@ -5571,15 +5582,25 @@ extern (C++) final class TemplateValueParameter : TemplateParameter if (e) { e = e.syntaxCopy(); - uint olderrs = global.errors; if ((e = e.expressionSemantic(sc)) is null) return null; + if (auto te = e.isTemplateExp()) + { + assert(sc && sc.tinst); + if (te.td == sc.tinst.tempdecl) + { + // defaultValue is a reference to its template declaration + // i.e: `template T(int arg = T)` + // Raise error now before calling resolveProperties otherwise we'll + // start looping on the expansion of the template instance. + sc.tinst.tempdecl.error("recursive template expansion"); + return ErrorExp.get(); + } + } if ((e = resolveProperties(sc, e)) is null) return null; e = e.resolveLoc(instLoc, sc); // use the instantiated loc e = e.optimize(WANTvalue); - if (global.errors != olderrs) - e = ErrorExp.get(); } return e; } @@ -6910,11 +6931,6 @@ extern (C++) class TemplateInstance : ScopeDsymbol auto td = s.isTemplateDeclaration(); if (!td) return 0; - if (td.inuse) - { - td.error(loc, "recursive template expansion"); - return 1; - } if (td == td_best) // skip duplicates return 0; @@ -7133,11 +7149,6 @@ extern (C++) class TemplateInstance : ScopeDsymbol auto td = s.isTemplateDeclaration(); if (!td) return 0; - if (td.inuse) - { - td.error(loc, "recursive template expansion"); - return 1; - } /* If any of the overloaded template declarations need inference, * then return true diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d index 432e88d..30ca3d1 100644 --- a/gcc/d/dmd/dtoh.d +++ b/gcc/d/dmd/dtoh.d @@ -2,7 +2,7 @@ * This module contains the implementation of the C++ header generation available through * the command line switch -Hc. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dtohd, _dtoh.d) @@ -24,6 +24,7 @@ import dmd.errors; import dmd.globals; import dmd.hdrgen; import dmd.identifier; +import dmd.location; import dmd.root.filename; import dmd.visitor; import dmd.tokens; diff --git a/gcc/d/dmd/dversion.d b/gcc/d/dmd/dversion.d index 94753bb..259f85c5 100644 --- a/gcc/d/dmd/dversion.d +++ b/gcc/d/dmd/dversion.d @@ -4,7 +4,7 @@ * Specification: $(LINK2 https://dlang.org/spec/version.html#version-specification, Version Specification), * $(LINK2 https://dlang.org/spec/version.html#debug_specification, Debug Specification). * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dversion.d, _dversion.d) @@ -22,6 +22,7 @@ import dmd.dsymbol; import dmd.dsymbolsem; import dmd.globals; import dmd.identifier; +import dmd.location; import dmd.common.outbuffer; import dmd.visitor; diff --git a/gcc/d/dmd/entity.d b/gcc/d/dmd/entity.d index 2b499c1..c31883f 100644 --- a/gcc/d/dmd/entity.d +++ b/gcc/d/dmd/entity.d @@ -3,7 +3,7 @@ * * Specification $(LINK2 https://dlang.org/spec/entity.html, Named Character Entities) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/entity.d, _entity.d) diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h index 723cebc..be12c65 100644 --- a/gcc/d/dmd/enum.h +++ b/gcc/d/dmd/enum.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/errors.d b/gcc/d/dmd/errors.d index 62e86a1..03c78a5 100644 --- a/gcc/d/dmd/errors.d +++ b/gcc/d/dmd/errors.d @@ -1,7 +1,7 @@ /** * Functions for raising errors. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/errors.d, _errors.d) @@ -13,6 +13,7 @@ module dmd.errors; import core.stdc.stdarg; import dmd.globals; +import dmd.location; nothrow: diff --git a/gcc/d/dmd/errors.h b/gcc/d/dmd/errors.h index 000242c..cc72811 100644 --- a/gcc/d/dmd/errors.h +++ b/gcc/d/dmd/errors.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index 24a428b..7bc018e 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -1,7 +1,7 @@ /** * Most of the logic to implement scoped pointers and scoped references is here. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/escape.d, _escape.d) @@ -29,6 +29,7 @@ import dmd.globals; import dmd.id; import dmd.identifier; import dmd.init; +import dmd.location; import dmd.mtype; import dmd.printast; import dmd.root.rootobject; @@ -1788,7 +1789,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re if (tf.isreturn) stc |= STC.return_; if (tf.isreturnscope) - stc |= STC.returnScope; + stc |= STC.returnScope | STC.scope_; auto ad = fd.isThis(); if (ad.isClassDeclaration() || tf.isScopeQual) stc |= STC.scope_; diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 4f14d66..e0f258c 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -3,7 +3,7 @@ * * Specification: ($LINK2 https://dlang.org/spec/expression.html, Expressions) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/expression.d, _expression.d) @@ -50,6 +50,7 @@ import dmd.id; import dmd.identifier; import dmd.init; import dmd.inline; +import dmd.location; import dmd.mtype; import dmd.nspace; import dmd.objc; @@ -1291,12 +1292,16 @@ extern (C++) abstract class Expression : ASTNode return false; // ...or manifest constants // accessing empty structs is pure + // https://issues.dlang.org/show_bug.cgi?id=18694 + // https://issues.dlang.org/show_bug.cgi?id=21464 + // https://issues.dlang.org/show_bug.cgi?id=23589 if (v.type.ty == Tstruct) { StructDeclaration sd = (cast(TypeStruct)v.type).sym; if (sd.members) // not opaque { - sd.determineSize(v.loc); + if (sd.semanticRun >= PASS.semanticdone) + sd.determineSize(v.loc); if (sd.hasNoFields) return false; } diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index 79bc528..7202960 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 60b51cb..63236cd 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -3,7 +3,7 @@ * * Specification: ($LINK2 https://dlang.org/spec/expression.html, Expressions) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/expressionsem.d, _expressionsem.d) @@ -55,6 +55,7 @@ import dmd.init; import dmd.initsem; import dmd.inline; import dmd.intrange; +import dmd.location; import dmd.mtype; import dmd.mustuse; import dmd.nspace; @@ -512,7 +513,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce) { Identifier ident = die.ident; - Expression ex = die.semanticX(sc); + Expression ex = die.dotIdSemanticPropX(sc); if (ex != die) { ce.e1 = ex; @@ -561,7 +562,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce) } else { - if (Expression ey = die.semanticY(sc, 1)) + if (Expression ey = die.dotIdSemanticProp(sc, 1)) { if (ey.op == EXP.error) return ey; @@ -632,7 +633,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce) } else if (auto dti = ce.e1.isDotTemplateInstanceExp()) { - if (Expression ey = dti.semanticY(sc, 1)) + if (Expression ey = dti.dotTemplateSemanticProp(sc, 1)) { ce.e1 = ey; return null; @@ -2536,28 +2537,6 @@ Package resolveIsPackage(Dsymbol sym) return pkg; } -private Module loadStdMath() -{ - __gshared Import impStdMath = null; - __gshared Identifier[1] stdID; - if (!impStdMath) - { - stdID[0] = Id.std; - auto s = new Import(Loc.initial, stdID[], Id.math, null, false); - // Module.load will call fatal() if there's no std.math available. - // Gag the error here, pushing the error handling to the caller. - uint errors = global.startGagging(); - s.load(null); - if (s.mod) - { - s.mod.importAll(null); - s.mod.dsymbolSemantic(null); - } - global.endGagging(errors); - impStdMath = s; - } - return impStdMath.mod; -} private extern (C++) final class ExpressionSemanticVisitor : Visitor { @@ -3585,6 +3564,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (auto tc = tb.isTypeClass()) { auto cd = tc.sym; + if (cd.errors) + return setError(); cd.size(exp.loc); if (cd.sizeok != Sizeok.done) return setError(); @@ -3630,21 +3611,25 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { if (!cdthis) { - if (!sc.hasThis) + void noReferenceToOuterClass() { - string msg = "cannot construct " ~ - (cd.isAnonymous ? "anonymous nested class" : "nested class `%s`") ~ - " because no implicit `this` reference to outer class" ~ - (cdn.isAnonymous ? "" : " `%s`") ~ " is available\0"; - - exp.error(msg.ptr, cd.toChars, cdn.toChars); + if (cd.isAnonymous) + exp.error("cannot construct anonymous nested class because no implicit `this` reference to outer class is available"); + else + exp.error("cannot construct nested class `%s` because no implicit `this` reference to outer class `%s` is available", + cd.toChars(), cdn.toChars()); return setError(); } + if (!sc.hasThis) + return noReferenceToOuterClass(); + // Supply an implicit 'this' and try again exp.thisexp = new ThisExp(exp.loc); for (Dsymbol sp = sc.parent; 1; sp = sp.toParentLocal()) { + if (!sp) + return noReferenceToOuterClass(); ClassDeclaration cdp = sp.isClassDeclaration(); if (!cdp) continue; @@ -4671,8 +4656,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor else if (exp.arguments.length == 1) { e = (*exp.arguments)[0]; - if (!e.type.isTypeNoreturn()) - e = e.implicitCastTo(sc, t1); + e = e.implicitCastTo(sc, t1); + e = new CastExp(exp.loc, e, t1); } else { @@ -5851,8 +5836,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor dedtypes.zero(); MATCH m = deduceType(e.targ, sc, e.tspec, e.parameters, &dedtypes, null, 0, e.tok == TOK.equal); - //printf("targ: %s\n", targ.toChars()); - //printf("tspec: %s\n", tspec.toChars()); + if (m == MATCH.nomatch || (m != MATCH.exact && e.tok == TOK.equal)) { return no(); @@ -6557,7 +6541,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } } - Expression e = exp.semanticY(sc, 1); + Expression e = exp.dotIdSemanticProp(sc, 1); if (e && isDotOpDispatch(e)) { @@ -6786,7 +6770,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } // Indicate we need to resolve by UFCS. - Expression e = exp.semanticY(sc, 1); + Expression e = exp.dotTemplateSemanticProp(sc, 1); if (!e) e = resolveUFCSProperties(sc, exp); if (e is exp) @@ -7528,11 +7512,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } - if (exp.e1.type.isTypeNoreturn() && (!exp.to || !exp.to.isTypeNoreturn())) - { - result = exp.e1; - return; - } if (exp.to && !exp.to.isTypeSArray() && !exp.to.isTypeFunction()) exp.e1 = exp.e1.arrayFuncConv(sc); @@ -8069,22 +8048,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Expression el = new ArrayLengthExp(exp.loc, exp.e1); el = el.expressionSemantic(sc); el = el.optimize(WANTvalue); - if (el.op == EXP.int64 && t1b.ty == Tsarray) + if (el.op == EXP.int64) { // Array length is known at compile-time. Upper is in bounds if it fits length. dinteger_t length = el.toInteger(); auto bounds = IntRange(SignExtendedNumber(0), SignExtendedNumber(length)); exp.upperIsInBounds = bounds.contains(uprRange); - if (exp.lwr.op == EXP.int64 && exp.upr.op == EXP.int64 && exp.lwr.toInteger() > exp.upr.toInteger()) - { - exp.error("in slice `%s[%llu .. %llu]`, lower bound is greater than upper bound", exp.e1.toChars, exp.lwr.toInteger(), exp.upr.toInteger()); - return setError(); - } - if (exp.upr.op == EXP.int64 && exp.upr.toInteger() > length) - { - exp.error("in slice `%s[%llu .. %llu]`, upper bound is greater than array length `%llu`", exp.e1.toChars, exp.lwr.toInteger(), exp.upr.toInteger(), length); - return setError(); - } } else if (exp.upr.op == EXP.int64 && exp.upr.toInteger() == 0) { @@ -8884,7 +8853,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor */ if (auto dti = e1x.isDotTemplateInstanceExp()) { - Expression e = dti.semanticY(sc, 1); + Expression e = dti.dotTemplateSemanticProp(sc, 1); if (!e) { return setResult(resolveUFCSProperties(sc, e1x, exp.e2)); @@ -8899,7 +8868,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else if (auto die = e1x.isDotIdExp()) { - Expression e = die.semanticY(sc, 1); + Expression e = die.dotIdSemanticProp(sc, 1); if (e && isDotOpDispatch(e)) { /* https://issues.dlang.org/show_bug.cgi?id=19687 @@ -11275,7 +11244,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } - Module mmath = loadStdMath(); + Module mmath = Module.loadStdMath(); if (!mmath) { e.error("`%s` requires `std.math` for `^^` operators", e.toChars()); @@ -11823,8 +11792,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } - if (t1.isTypeVector()) - exp.type = t1; + if (auto tv = t1.isTypeVector()) + exp.type = tv.toBooleanVector(); result = exp; return; @@ -12105,8 +12074,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } - if (t1.isTypeVector()) - exp.type = t1; + if (auto tv = t1.isTypeVector()) + exp.type = tv.toBooleanVector(); result = exp; } @@ -12244,10 +12213,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (t1.ty == Tnoreturn) { exp.type = t2; + exp.e1 = specialNoreturnCast(exp.e1, exp.type); } else if (t2.ty == Tnoreturn) { exp.type = t1; + exp.e2 = specialNoreturnCast(exp.e2, exp.type); } // If either operand is void the result is void, we have to cast both // the expression to void so that we explicitly discard the expression @@ -12541,7 +12512,7 @@ extern (C++) Expression expressionSemantic(Expression e, Scope* sc) return v.result; } -Expression semanticX(DotIdExp exp, Scope* sc) +private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc) { //printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars()); if (Expression ex = unaSemantic(exp, sc)) @@ -12649,7 +12620,7 @@ Expression semanticX(DotIdExp exp, Scope* sc) * Returns: * resolved expression, null if error */ -Expression semanticY(DotIdExp exp, Scope* sc, int flag) +Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, int flag) { //printf("DotIdExp::semanticY(this = %p, '%s')\n", exp, exp.toChars()); @@ -12681,7 +12652,7 @@ Expression semanticY(DotIdExp exp, Scope* sc, int flag) } { - Expression e = semanticX(exp, sc); + Expression e = dotIdSemanticPropX(exp, sc); if (e != exp) return e; } @@ -12983,7 +12954,7 @@ Expression semanticY(DotIdExp exp, Scope* sc, int flag) // Resolve e1.ident!tiargs without seeing UFCS. // If flag == 1, stop "not a property" error and return NULL. -Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag) +Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, int flag) { static if (LOGSEMANTIC) { @@ -13007,7 +12978,7 @@ Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag) auto die = new DotIdExp(exp.loc, e1, exp.ti.name); - Expression e = die.semanticX(sc); + Expression e = die.dotIdSemanticPropX(sc); if (e == die) { exp.e1 = die.e1; // take back @@ -13020,7 +12991,7 @@ Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag) if (flag) return null; } - e = die.semanticY(sc, flag); + e = die.dotIdSemanticProp(sc, flag); if (flag) { if (!e || @@ -13169,6 +13140,7 @@ Lerr: bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false) { if (global.params.noSharedAccess != FeatureState.enabled || + !sc || sc.intypeof || sc.flags & SCOPE.ctfe) { diff --git a/gcc/d/dmd/file_manager.d b/gcc/d/dmd/file_manager.d index a941115..a0e5d05 100644 --- a/gcc/d/dmd/file_manager.d +++ b/gcc/d/dmd/file_manager.d @@ -1,7 +1,7 @@ /** * Read a file from disk and store it in memory. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/file_manager.d, _file_manager.d) * Documentation: https://dlang.org/phobos/dmd_file_manager.html @@ -16,6 +16,7 @@ import dmd.root.filename : FileName, isDirSeparator; import dmd.root.string : toDString; import dmd.globals; import dmd.identifier; +import dmd.location; enum package_d = "package." ~ mars_ext; enum package_di = "package." ~ hdr_ext; @@ -123,7 +124,7 @@ nothrow: const(char)[] lookForSourceFile(const char[] filename, const char*[] path) { //printf("lookForSourceFile(`%.*s`)\n", cast(int)filename.length, filename.ptr); - /* Search along path[] for .di file, then .d file, then .i file, then .c file. + /* Search along path[] for .di file, then .d file. */ // see if we should check for the module locally. bool checkLocal = packageExists(filename); @@ -140,16 +141,6 @@ nothrow: return sd; scope(exit) FileName.free(sd.ptr); - const si = FileName.forceExt(filename, i_ext); - if (checkLocal && FileName.exists(si) == 1) - return si; - scope(exit) FileName.free(si.ptr); - - const sc = FileName.forceExt(filename, c_ext); - if (checkLocal && FileName.exists(sc) == 1) - return sc; - scope(exit) FileName.free(sc.ptr); - if (checkLocal) { auto cached = packageStatus.lookup(filename); @@ -198,18 +189,6 @@ nothrow: } FileName.free(n.ptr); - n = FileName.combine(p, si); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - - n = FileName.combine(p, sc); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - const b = FileName.removeExt(filename); n = FileName.combine(p, b); FileName.free(b.ptr); @@ -235,6 +214,34 @@ nothrow: FileName.free(n2.ptr); } } + + /* ImportC: No D modules found, now search along path[] for .i file, then .c file. + */ + const si = FileName.forceExt(filename, i_ext); + if (FileName.exists(si) == 1) + return si; + scope(exit) FileName.free(si.ptr); + + const sc = FileName.forceExt(filename, c_ext); + if (FileName.exists(sc) == 1) + return sc; + scope(exit) FileName.free(sc.ptr); + foreach (entry; path) + { + const p = entry.toDString(); + + const(char)[] n = FileName.combine(p, si); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + + n = FileName.combine(p, sc); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + } return null; } diff --git a/gcc/d/dmd/foreachvar.d b/gcc/d/dmd/foreachvar.d index 63281b5..7c4df0de 100644 --- a/gcc/d/dmd/foreachvar.d +++ b/gcc/d/dmd/foreachvar.d @@ -1,7 +1,7 @@ /** * Utility to visit every variable in an expression. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/foreachvar.d, _foreachvar.d) diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index 93e3634..3a85679 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -8,7 +8,7 @@ * - `invariant` * - `unittest` * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/func.d, _func.d) @@ -43,6 +43,7 @@ import dmd.hdrgen; import dmd.id; import dmd.identifier; import dmd.init; +import dmd.location; import dmd.mtype; import dmd.objc; import dmd.root.aav; @@ -2924,89 +2925,100 @@ Expression addInvariant(AggregateDeclaration ad, VarDeclaration vthis) */ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc = null) { - Dsymbol next; - for (auto d = fstart; d; d = next) + Dsymbols visited; + + int overloadApplyRecurse(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc) { - import dmd.access : checkSymbolAccess; - if (auto od = d.isOverDeclaration()) + // Detect cyclic calls. + if (visited.contains(fstart)) + return 0; + visited.push(fstart); + + Dsymbol next; + for (auto d = fstart; d; d = next) { - /* The scope is needed here to check whether a function in - an overload set was added by means of a private alias (or a - selective import). If the scope where the alias is created - is imported somewhere, the overload set is visible, but the private - alias is not. - */ - if (sc) + import dmd.access : checkSymbolAccess; + if (auto od = d.isOverDeclaration()) { - if (checkSymbolAccess(sc, od)) + /* The scope is needed here to check whether a function in + an overload set was added by means of a private alias (or a + selective import). If the scope where the alias is created + is imported somewhere, the overload set is visible, but the private + alias is not. + */ + if (sc) { - if (int r = overloadApply(od.aliassym, dg, sc)) + if (checkSymbolAccess(sc, od)) + { + if (int r = overloadApplyRecurse(od.aliassym, dg, sc)) + return r; + } + } + else if (int r = overloadApplyRecurse(od.aliassym, dg, sc)) + return r; + next = od.overnext; + } + else if (auto fa = d.isFuncAliasDeclaration()) + { + if (fa.hasOverloads) + { + if (int r = overloadApplyRecurse(fa.funcalias, dg, sc)) return r; } + else if (auto fd = fa.toAliasFunc()) + { + if (int r = dg(fd)) + return r; + } + else + { + d.error("is aliased to a function"); + break; + } + next = fa.overnext; } - else if (int r = overloadApply(od.aliassym, dg, sc)) - return r; - next = od.overnext; - } - else if (auto fa = d.isFuncAliasDeclaration()) - { - if (fa.hasOverloads) + else if (auto ad = d.isAliasDeclaration()) { - if (int r = overloadApply(fa.funcalias, dg, sc)) + if (sc) + { + if (checkSymbolAccess(sc, ad)) + next = ad.toAlias(); + } + else + next = ad.toAlias(); + if (next == ad) + break; + if (next == fstart) + break; + } + else if (auto td = d.isTemplateDeclaration()) + { + if (int r = dg(td)) return r; + next = td.overnext; } - else if (auto fd = fa.toAliasFunc()) + else if (auto fd = d.isFuncDeclaration()) { if (int r = dg(fd)) return r; + next = fd.overnext; + } + else if (auto os = d.isOverloadSet()) + { + foreach (ds; os.a) + if (int r = dg(ds)) + return r; } else { d.error("is aliased to a function"); break; + // BUG: should print error message? } - next = fa.overnext; - } - else if (auto ad = d.isAliasDeclaration()) - { - if (sc) - { - if (checkSymbolAccess(sc, ad)) - next = ad.toAlias(); - } - else - next = ad.toAlias(); - if (next == ad) - break; - if (next == fstart) - break; - } - else if (auto td = d.isTemplateDeclaration()) - { - if (int r = dg(td)) - return r; - next = td.overnext; - } - else if (auto fd = d.isFuncDeclaration()) - { - if (int r = dg(fd)) - return r; - next = fd.overnext; - } - else if (auto os = d.isOverloadSet()) - { - foreach (ds; os.a) - if (int r = dg(ds)) - return r; - } - else - { - d.error("is aliased to a function"); - break; - // BUG: should print error message? } + return 0; } - return 0; + return overloadApplyRecurse(fstart, dg, sc); } /** diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 2770f5a..80c183e 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -1,7 +1,7 @@ /** * Stores command line options and contains other miscellaneous declarations. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/globals.d, _globals.d) @@ -17,6 +17,7 @@ import dmd.root.filename; import dmd.common.outbuffer; import dmd.file_manager; import dmd.identifier; +import dmd.location; /// Defines a setting for how compiler warnings and deprecations are handled enum DiagnosticReporting : ubyte @@ -26,13 +27,6 @@ enum DiagnosticReporting : ubyte off, /// disable diagnostic } -/// How code locations are formatted for diagnostic reporting -enum MessageStyle : ubyte -{ - digitalmars, /// filename.d(line): message - gnu, /// filename.d:line: message, see https://www.gnu.org/prep/standards/html_node/Errors.html -} - /// In which context checks for assertions, contracts, bounds checks etc. are enabled enum CHECKENABLE : ubyte { @@ -266,7 +260,7 @@ extern (C++) struct Global { const(char)[] inifilename; /// filename of configuration file as given by `-conf=`, or default value - string copyright = "Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved"; + string copyright = "Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved"; string written = "written by Walter Bright"; Array!(const(char)*)* path; /// Array of char*'s which form the import lookup path @@ -446,125 +440,5 @@ alias dinteger_t = ulong; alias sinteger_t = long; alias uinteger_t = ulong; -version (DMDLIB) -{ - version = LocOffset; -} - -/** -A source code location - -Used for error messages, `__FILE__` and `__LINE__` tokens, `__traits(getLocation, XXX)`, -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 - version (LocOffset) - uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0 - - static immutable Loc initial; /// use for default initialization of const ref Loc's - -nothrow: - extern (D) this(const(char)* filename, uint linnum, uint charnum) pure - { - this.linnum = linnum; - this.charnum = charnum; - this.filename = filename; - } - - extern (C++) const(char)* toChars( - bool showColumns = global.params.showColumns, - ubyte messageStyle = global.params.messageStyle) const pure nothrow - { - OutBuffer buf; - if (filename) - { - buf.writestring(filename); - } - if (linnum) - { - final switch (messageStyle) - { - case MessageStyle.digitalmars: - buf.writeByte('('); - buf.print(linnum); - if (showColumns && charnum) - { - buf.writeByte(','); - buf.print(charnum); - } - buf.writeByte(')'); - break; - case MessageStyle.gnu: // https://www.gnu.org/prep/standards/html_node/Errors.html - buf.writeByte(':'); - buf.print(linnum); - if (showColumns && charnum) - { - buf.writeByte(':'); - buf.print(charnum); - } - break; - } - } - return buf.extractChars(); - } - - /** - * Checks for equivalence by comparing the filename contents (not the pointer) and character location. - * - * Note: - * - Uses case-insensitive comparison on Windows - * - Ignores `charnum` if `global.params.showColumns` is false. - */ - extern (C++) bool equals(ref const(Loc) loc) const - { - return (!global.params.showColumns || charnum == loc.charnum) && - linnum == loc.linnum && - FileName.equals(filename, loc.filename); - } - - /** - * `opEquals()` / `toHash()` for AA key usage - * - * Compare filename contents (case-sensitively on Windows too), not - * the pointer - a static foreach loop repeatedly mixing in a mixin - * 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 - { - import core.stdc.string : strcmp; - - return charnum == loc.charnum && - linnum == loc.linnum && - (filename == loc.filename || - (filename && loc.filename && strcmp(filename, loc.filename) == 0)); - } - - /// ditto - extern (D) size_t toHash() const @trusted pure nothrow - { - import dmd.root.string : toDString; - - auto hash = hashOf(linnum); - hash = hashOf(charnum, hash); - hash = hashOf(filename.toDString, hash); - return hash; - } - - /****************** - * Returns: - * true if Loc has been set to other than the default initialization - */ - bool isValid() const pure - { - return filename !is null; - } -} - /// Collection of global state extern (C++) __gshared Global global; diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index d9cb76c..45c5624 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. @@ -30,11 +30,10 @@ enum DIAGNOSTICoff // disable diagnostic }; -typedef unsigned char MessageStyle; -enum +enum class MessageStyle : unsigned char { - MESSAGESTYLEdigitalmars, // file(line,column): message - MESSAGESTYLEgnu // file:line:column: message + digitalmars, // file(line,column): message + gnu // file:line:column: message }; // The state of array bounds checking @@ -342,6 +341,11 @@ struct Loc unsigned linnum; unsigned charnum; + static void set(bool showColumns, MessageStyle messageStyle); + + static bool showColumns; + static MessageStyle messageStyle; + Loc() { linnum = 0; @@ -357,8 +361,8 @@ struct Loc } const char *toChars( - bool showColumns = global.params.showColumns, - MessageStyle messageStyle = global.params.messageStyle) const; + bool showColumns = Loc::showColumns, + MessageStyle messageStyle = Loc::messageStyle) const; bool equals(const Loc& loc) const; }; diff --git a/gcc/d/dmd/gluelayer.d b/gcc/d/dmd/gluelayer.d index 73a1f00..7b52eff 100644 --- a/gcc/d/dmd/gluelayer.d +++ b/gcc/d/dmd/gluelayer.d @@ -3,7 +3,7 @@ * * This 'glues' either the DMC or GCC back-end to the front-end. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/gluelayer.d, _gluelayer.d) diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index 6b51a81..68670d9 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -3,7 +3,7 @@ * * Also used to convert AST nodes to D code in general, e.g. for error messages or `printf` debugging. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/hdrgen.d, _hdrgen.d) @@ -823,10 +823,13 @@ public: buf.writestring(s.kind()); buf.writeByte('('); s.exp.expressionToBuffer(buf, hgs); - if (s.msg) + if (s.msgs) { - buf.writestring(", "); - s.msg.expressionToBuffer(buf, hgs); + foreach (m; (*s.msgs)[]) + { + buf.writestring(", "); + m.expressionToBuffer(buf, hgs); + } } buf.writestring(");"); buf.writenl(); diff --git a/gcc/d/dmd/hdrgen.h b/gcc/d/dmd/hdrgen.h index 0488c51..43fea34 100644 --- a/gcc/d/dmd/hdrgen.h +++ b/gcc/d/dmd/hdrgen.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Dave Fladebo * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/iasm.d b/gcc/d/dmd/iasm.d index 29aca3e..4d780b3 100644 --- a/gcc/d/dmd/iasm.d +++ b/gcc/d/dmd/iasm.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/iasm.html, Inline Assembler) * - * Copyright (C) 2018-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 2018-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/iasm.d, _iasm.d) diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d index f85e1ab..baf6b14 100644 --- a/gcc/d/dmd/iasmgcc.d +++ b/gcc/d/dmd/iasmgcc.d @@ -1,7 +1,7 @@ /** * Inline assembler for the GCC D compiler. * - * Copyright (C) 2018-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 2018-2023 by The D Language Foundation, All Rights Reserved * Authors: Iain Buclaw * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/iasmgcc.d, _iasmgcc.d) @@ -21,6 +21,7 @@ import dmd.expression; import dmd.expressionsem; import dmd.identifier; import dmd.globals; +import dmd.location; import dmd.parse; import dmd.tokens; import dmd.statement; diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d index 48ca766..40a5c6e 100644 --- a/gcc/d/dmd/id.d +++ b/gcc/d/dmd/id.d @@ -1,7 +1,7 @@ /** * Contains the `Id` struct with a list of predefined symbols the compiler knows about. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/id.d, _id.d) diff --git a/gcc/d/dmd/id.h b/gcc/d/dmd/id.h index 984c203..f6cf6e5 100644 --- a/gcc/d/dmd/id.h +++ b/gcc/d/dmd/id.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 2017-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 2017-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/identifier.d b/gcc/d/dmd/identifier.d index 7f92298..2233d77 100644 --- a/gcc/d/dmd/identifier.d +++ b/gcc/d/dmd/identifier.d @@ -1,7 +1,7 @@ /** * Defines an identifier, which is the name of a `Dsymbol`. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/identifier.d, _identifier.d) @@ -14,8 +14,8 @@ module dmd.identifier; import core.stdc.ctype; import core.stdc.stdio; import core.stdc.string; -import dmd.globals; import dmd.id; +import dmd.location; import dmd.common.outbuffer; import dmd.root.rootobject; import dmd.root.string; diff --git a/gcc/d/dmd/identifier.h b/gcc/d/dmd/identifier.h index fa7a25a..c12c355 100644 --- a/gcc/d/dmd/identifier.h +++ b/gcc/d/dmd/identifier.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/impcnvtab.d b/gcc/d/dmd/impcnvtab.d index 832c331..b45880a 100644 --- a/gcc/d/dmd/impcnvtab.d +++ b/gcc/d/dmd/impcnvtab.d @@ -6,7 +6,7 @@ * Specification: $(LINK2 https://dlang.org/spec/type.html#integer-promotions, Integer Promotions), * $(LINK2 https://dlang.org/spec/type.html#usual-arithmetic-conversions, Usual Arithmetic Conversions). * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/impcnvtab.d, _impcnvtab.d) diff --git a/gcc/d/dmd/imphint.d b/gcc/d/dmd/imphint.d index f03113d..913de9f 100644 --- a/gcc/d/dmd/imphint.d +++ b/gcc/d/dmd/imphint.d @@ -3,7 +3,7 @@ * * For example, prompt to `import std.stdio` when using `writeln`. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/imphint.d, _imphint.d) diff --git a/gcc/d/dmd/import.h b/gcc/d/dmd/import.h index f749ef5..ff25ba2 100644 --- a/gcc/d/dmd/import.h +++ b/gcc/d/dmd/import.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d index afec5ef..97710b8 100644 --- a/gcc/d/dmd/importc.d +++ b/gcc/d/dmd/importc.d @@ -3,7 +3,7 @@ * * Specification: C11 * - * Copyright: Copyright (C) 2021-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 2021-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/importc.d, _importc.d) diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d index f57b4e6..f646d03 100644 --- a/gcc/d/dmd/init.d +++ b/gcc/d/dmd/init.d @@ -1,7 +1,7 @@ /** * Defines initializers of variables, e.g. the array literal in `int[3] x = [0, 1, 2]`. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/init.d, _init.d) @@ -22,6 +22,7 @@ import dmd.expression; import dmd.globals; import dmd.hdrgen; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.common.outbuffer; import dmd.root.rootobject; diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h index 977157f..66b874c 100644 --- a/gcc/d/dmd/init.h +++ b/gcc/d/dmd/init.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index ecaa5e8..572753b 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -1,7 +1,7 @@ /** * Semantic analysis of initializers. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/initsem.d, _initsem.d) @@ -33,6 +33,7 @@ import dmd.id; import dmd.identifier; import dmd.importc; import dmd.init; +import dmd.location; import dmd.mtype; import dmd.opover; import dmd.statement; diff --git a/gcc/d/dmd/inline.d b/gcc/d/dmd/inline.d index 25982a6..8e63122 100644 --- a/gcc/d/dmd/inline.d +++ b/gcc/d/dmd/inline.d @@ -4,7 +4,7 @@ * The AST is traversed, and every function call is considered for inlining using `inlinecost.d`. * The function call is then inlined if this cost is below a threshold. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/inline.d, _inline.d) diff --git a/gcc/d/dmd/intrange.d b/gcc/d/dmd/intrange.d index d0206b6..d67e0f5 100644 --- a/gcc/d/dmd/intrange.d +++ b/gcc/d/dmd/intrange.d @@ -1,7 +1,7 @@ /** * Implement $(LINK2 https://digitalmars.com/articles/b62.html, Value Range Propagation). * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/intrange.d, _intrange.d) diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d index b7719d8..38e03e7 100644 --- a/gcc/d/dmd/json.d +++ b/gcc/d/dmd/json.d @@ -1,7 +1,7 @@ /** * Code for generating .json descriptions of the module when passing the `-X` flag to dmd. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/json.d, _json.d) @@ -32,6 +32,7 @@ import dmd.globals; import dmd.hdrgen; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.common.outbuffer; import dmd.root.rootobject; diff --git a/gcc/d/dmd/json.h b/gcc/d/dmd/json.h index 979440c..7a23897 100644 --- a/gcc/d/dmd/json.h +++ b/gcc/d/dmd/json.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/lambdacomp.d b/gcc/d/dmd/lambdacomp.d index e1ed717..c800273 100644 --- a/gcc/d/dmd/lambdacomp.d +++ b/gcc/d/dmd/lambdacomp.d @@ -5,7 +5,7 @@ * The serialization is a string which contains the type of the parameters and the string * represantation of the lambda expression. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/lamdbacomp.d, _lambdacomp.d) diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index 200d74f..bd53433 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/lex.html, Lexical) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/lexer.d, _lexer.d) @@ -26,6 +26,7 @@ import dmd.errors; import dmd.globals; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.root.array; import dmd.root.ctfloat; import dmd.common.outbuffer; @@ -79,15 +80,14 @@ class Lexer bool commentToken; // comments are TOK.comment's bool tokenizeNewlines; // newlines are turned into TOK.endOfLine's - version (DMDLIB) - { - bool whitespaceToken; // tokenize whitespaces - } + bool whitespaceToken; // tokenize whitespaces (only for DMDLIB) int inTokenStringConstant; // can be larger than 1 when in nested q{} strings int lastDocLine; // last line of previous doc comment Token* tokenFreelist; + uint versionNumber; + const(char)[] vendor; } nothrow: @@ -103,9 +103,12 @@ class Lexer * endoffset = the last offset to read into base[] * doDocComment = handle documentation comments * commentToken = comments become TOK.comment's + * vendor = name of the vendor + * versionNumber = version of the caller */ this(const(char)* filename, const(char)* base, size_t begoffset, - size_t endoffset, bool doDocComment, bool commentToken) pure + size_t endoffset, bool doDocComment, bool commentToken, + const(char)[] vendor = "DLF", uint versionNumber = 1) pure { scanloc = Loc(filename, 1, 1); // debug printf("Lexer::Lexer(%p)\n", base); @@ -120,6 +123,8 @@ class Lexer this.tokenizeNewlines = false; this.inTokenStringConstant = 0; this.lastDocLine = 0; + this.versionNumber = versionNumber; + this.vendor = vendor; //initKeywords(); /* If first line starts with '#!', ignore the line */ @@ -154,6 +159,16 @@ class Lexer } } + /*********************** + * Alternative entry point for DMDLIB, adds `whitespaceToken` + */ + this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset, + bool doDocComment, bool commentToken, bool whitespaceToken) + { + this(filename, base, begoffset, endoffset, doDocComment, commentToken); + this.whitespaceToken = whitespaceToken; + } + /****************** * Used for unittests for a mock Lexer */ @@ -184,29 +199,23 @@ class Lexer tokenizeNewlines = true; } - version (DMDLIB) - { - this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset, - bool doDocComment, bool commentToken, bool whitespaceToken) - { - this(filename, base, begoffset, endoffset, doDocComment, commentToken); - this.whitespaceToken = whitespaceToken; - } + /*************** + * Range interface + */ - bool empty() const pure @property @nogc @safe - { - return front() == TOK.endOfFile; - } + final bool empty() const pure @property @nogc @safe + { + return front() == TOK.endOfFile; + } - TOK front() const pure @property @nogc @safe - { - return token.value; - } + final TOK front() const pure @property @nogc @safe + { + return token.value; + } - void popFront() - { - nextToken(); - } + final void popFront() + { + nextToken(); } /// Returns: a newly allocated `Token`. @@ -570,7 +579,7 @@ class Lexer } else if (id == Id.VENDOR) { - t.ustring = global.vendor.xarraydup.ptr; + t.ustring = vendor.xarraydup.ptr; goto Lstr; } else if (id == Id.TIMESTAMP) @@ -584,7 +593,7 @@ class Lexer else if (id == Id.VERSIONX) { t.value = TOK.int64Literal; - t.unsvalue = global.versionNumber(); + t.unsvalue = versionNumber; } else if (id == Id.EOFX) { @@ -1965,7 +1974,7 @@ class Lexer { int base = 10; const start = p; - uinteger_t n = 0; // unsigned >=64 bit integer type + ulong n = 0; // unsigned >=64 bit integer type int d; bool err = false; bool overflow = false; @@ -2274,7 +2283,7 @@ class Lexer * Returns: * token value */ - private TOK cnumber(int base, uinteger_t n) + private TOK cnumber(int base, ulong n) { /* C11 6.4.4.1 * Parse trailing suffixes: diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d new file mode 100644 index 0000000..020d297 --- /dev/null +++ b/gcc/d/dmd/location.d @@ -0,0 +1,158 @@ +/** + * Encapsulates file/line/column locations. + * + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved + * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) + * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/location.d, _location.d) + * Documentation: https://dlang.org/phobos/dmd_location.html + * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/location.d + */ + +module dmd.location; + +import dmd.common.outbuffer; +import dmd.root.filename; + +version (DMDLIB) +{ + version = LocOffset; +} + +/// How code locations are formatted for diagnostic reporting +enum MessageStyle : ubyte +{ + digitalmars, /// filename.d(line): message + gnu, /// filename.d:line: message, see https://www.gnu.org/prep/standards/html_node/Errors.html +} + +/** +A source code location + +Used for error messages, `__FILE__` and `__LINE__` tokens, `__traits(getLocation, XXX)`, +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 + version (LocOffset) + uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0 + + static immutable Loc initial; /// use for default initialization of const ref Loc's + + extern (C++) __gshared bool showColumns; + extern (C++) __gshared MessageStyle messageStyle; + +nothrow: + + /******************************* + * Configure how display is done + * Params: + * showColumns = when to display columns + * messageStyle = digitalmars or gnu style messages + */ + extern (C++) static void set(bool showColumns, MessageStyle messageStyle) + { + this.showColumns = showColumns; + this.messageStyle = messageStyle; + } + + extern (D) this(const(char)* filename, uint linnum, uint charnum) pure + { + this.linnum = linnum; + this.charnum = charnum; + this.filename = filename; + } + + extern (C++) const(char)* toChars( + bool showColumns = Loc.showColumns, + MessageStyle messageStyle = Loc.messageStyle) const pure nothrow + { + OutBuffer buf; + if (filename) + { + buf.writestring(filename); + } + if (linnum) + { + final switch (messageStyle) + { + case MessageStyle.digitalmars: + buf.writeByte('('); + buf.print(linnum); + if (showColumns && charnum) + { + buf.writeByte(','); + buf.print(charnum); + } + buf.writeByte(')'); + break; + case MessageStyle.gnu: // https://www.gnu.org/prep/standards/html_node/Errors.html + buf.writeByte(':'); + buf.print(linnum); + if (showColumns && charnum) + { + buf.writeByte(':'); + buf.print(charnum); + } + break; + } + } + return buf.extractChars(); + } + + /** + * Checks for equivalence by comparing the filename contents (not the pointer) and character location. + * + * Note: + * - Uses case-insensitive comparison on Windows + * - Ignores `charnum` if `Columns` is false. + */ + extern (C++) bool equals(ref const(Loc) loc) const + { + return (!showColumns || charnum == loc.charnum) && + linnum == loc.linnum && + FileName.equals(filename, loc.filename); + } + + /** + * `opEquals()` / `toHash()` for AA key usage + * + * Compare filename contents (case-sensitively on Windows too), not + * the pointer - a static foreach loop repeatedly mixing in a mixin + * 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 + { + import core.stdc.string : strcmp; + + return charnum == loc.charnum && + linnum == loc.linnum && + (filename == loc.filename || + (filename && loc.filename && strcmp(filename, loc.filename) == 0)); + } + + /// ditto + extern (D) size_t toHash() const @trusted pure nothrow + { + import dmd.root.string : toDString; + + auto hash = hashOf(linnum); + hash = hashOf(charnum, hash); + hash = hashOf(filename.toDString, hash); + return hash; + } + + /****************** + * Returns: + * true if Loc has been set to other than the default initialization + */ + bool isValid() const pure + { + return filename !is null; + } +} diff --git a/gcc/d/dmd/mangle.h b/gcc/d/dmd/mangle.h index 512184a..37953c2 100644 --- a/gcc/d/dmd/mangle.h +++ b/gcc/d/dmd/mangle.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h index 48046de..bc89ac4 100644 --- a/gcc/d/dmd/module.h +++ b/gcc/d/dmd/module.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. @@ -79,18 +79,18 @@ public: Package *pkg; // if isPackageFile is true, the Package that contains this package.d Strings contentImportedFiles; // array of files whose content was imported int needmoduleinfo; - int selfimports; // 0: don't know, 1: does not, 2: does + ThreeState selfimports; + ThreeState rootimports; void* tagSymTab; // ImportC: tag symbols that conflict with other symbols used as the index OutBuffer defines; // collect all the #define lines here bool selfImports(); // returns true if module imports itself - int rootimports; // 0: don't know, 1: does not, 2: does bool rootImports(); // returns true if module imports root module - int insearch; Identifier *searchCacheIdent; Dsymbol *searchCacheSymbol; // cached value of search int searchCacheFlags; // cached flags + bool insearch; // module from command line we're imported from, // i.e. a module that will be taken all the diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 2c0a571..232042d 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -1,7 +1,7 @@ /** * Defines a D type. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/mtype.d, _mtype.d) @@ -41,6 +41,7 @@ import dmd.hdrgen; import dmd.id; import dmd.identifier; import dmd.init; +import dmd.location; import dmd.opover; import dmd.root.ctfloat; import dmd.common.outbuffer; @@ -7384,3 +7385,51 @@ private extern(D) MATCH matchTypeSafeVarArgs(TypeFunction tf, Parameter p, return MATCH.nomatch; } } + +/** + * Creates an appropriate vector type for `tv` that will hold one boolean + * result for each element of the vector type. The result of vector comparisons + * is a single or doubleword mask of all 1s (comparison true) or all 0s + * (comparison false). This SIMD mask type does not have an equivalent D type, + * however its closest equivalent would be an integer vector of the same unit + * size and length. + * + * Params: + * tv = The `TypeVector` to build a vector from. + * Returns: + * A vector type suitable for the result of a vector comparison operation. + */ +TypeVector toBooleanVector(TypeVector tv) +{ + Type telem = tv.elementType(); + switch (telem.ty) + { + case Tvoid: + case Tint8: + case Tuns8: + case Tint16: + case Tuns16: + case Tint32: + case Tuns32: + case Tint64: + case Tuns64: + // No need to build an equivalent mask type. + return tv; + + case Tfloat32: + telem = Type.tuns32; + break; + + case Tfloat64: + telem = Type.tuns64; + break; + + default: + assert(0); + } + + TypeSArray tsa = tv.basetype.isTypeSArray(); + assert(tsa !is null); + + return new TypeVector(new TypeSArray(telem, tsa.dim)); +} diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h index c81c25a..d0775f2 100644 --- a/gcc/d/dmd/mtype.h +++ b/gcc/d/dmd/mtype.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/mustuse.d b/gcc/d/dmd/mustuse.d index 369d60e..11cc3b8d 100644 --- a/gcc/d/dmd/mustuse.d +++ b/gcc/d/dmd/mustuse.d @@ -1,7 +1,7 @@ /** * Compile-time checks associated with the @mustuse attribute. * - * Copyright: Copyright (C) 2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 2022-2023 by The D Language Foundation, All Rights Reserved * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/mustuse.d, _mustuse.d) * Documentation: https://dlang.org/phobos/dmd_mustuse.html @@ -15,6 +15,7 @@ import dmd.dsymbol; import dmd.expression; import dmd.globals; import dmd.identifier; +import dmd.location; // Used in isIncrementOrDecrement private static const StringExp plusPlus, minusMinus; @@ -147,7 +148,7 @@ private bool isAssignmentOpId(Identifier id) private bool isIncrementOrDecrement(Expression e) { import dmd.dtemplate : isExpression; - import dmd.globals : Loc; + import dmd.location; import dmd.id : Id; import dmd.tokens : EXP; diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index 3329c14..370e3b8 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/function.html#nogc-functions, No-GC Functions) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/nogc.d, _nogc.d) diff --git a/gcc/d/dmd/nspace.d b/gcc/d/dmd/nspace.d index 40f2676..551db5b 100644 --- a/gcc/d/dmd/nspace.d +++ b/gcc/d/dmd/nspace.d @@ -36,7 +36,7 @@ * are valid D identifier. * * See_Also: https://github.com/dlang/dmd/pull/10031 - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/nspace.d, _nspace.d) @@ -55,6 +55,7 @@ import dmd.dsymbolsem; import dmd.expression; import dmd.globals; import dmd.identifier; +import dmd.location; import dmd.visitor; import core.stdc.stdio; diff --git a/gcc/d/dmd/nspace.h b/gcc/d/dmd/nspace.h index 9dbbdf2..e9fb7bd 100644 --- a/gcc/d/dmd/nspace.h +++ b/gcc/d/dmd/nspace.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d index 59f34e1..31e93a7 100644 --- a/gcc/d/dmd/ob.d +++ b/gcc/d/dmd/ob.d @@ -1,7 +1,7 @@ /** * Flow analysis for Ownership/Borrowing * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ob.d, _ob.d) @@ -35,6 +35,7 @@ import dmd.func; import dmd.globals; import dmd.identifier; import dmd.init; +import dmd.location; import dmd.mtype; import dmd.printast; import dmd.statement; diff --git a/gcc/d/dmd/objc.d b/gcc/d/dmd/objc.d index 2bb5eab..c493323 100644 --- a/gcc/d/dmd/objc.d +++ b/gcc/d/dmd/objc.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/objc_interface.html, Interfacing to Objective-C) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/objc.d, _objc.d) @@ -36,6 +36,7 @@ import dmd.gluelayer; import dmd.hdrgen; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.root.array; import dmd.common.outbuffer; diff --git a/gcc/d/dmd/objc.h b/gcc/d/dmd/objc.h index a030154..305ce81 100644 --- a/gcc/d/dmd/objc.h +++ b/gcc/d/dmd/objc.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 2015-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 2015-2023 by The D Language Foundation, All Rights Reserved * written by Michel Fortin * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d index de41727..4d7fe9f 100644 --- a/gcc/d/dmd/opover.d +++ b/gcc/d/dmd/opover.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/operatoroverloading.html, Operator Overloading) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/opover.d, _opover.d) @@ -32,6 +32,7 @@ import dmd.globals; import dmd.hdrgen; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.statement; import dmd.tokens; @@ -931,6 +932,12 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) /* Rewrite as: * .object.opEquals(e1, e2) */ + if (!ClassDeclaration.object) + { + e.error("cannot compare classes for equality because `object.Object` was not declared"); + return null; + } + Expression e1x = e.e1; Expression e2x = e.e2; diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index a9c5425..b5d32b2 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -1,7 +1,7 @@ /** * Perform constant folding. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/optimize.d, _optimize.d) @@ -25,6 +25,7 @@ import dmd.expression; import dmd.expressionsem; import dmd.globals; import dmd.init; +import dmd.location; import dmd.mtype; import dmd.printast; import dmd.root.ctfloat; @@ -586,7 +587,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) Expression ex = new AddrExp(ae1.loc, ae1); // &a[i] ex.type = ae1.type.pointerTo(); - Expression add = new AddExp(ae.loc, ex, new IntegerExp(ae.loc, offset, e.type)); + Expression add = new AddExp(ae.loc, ex, new IntegerExp(ae.e2.loc, offset, ae.e2.type)); add.type = e.type; ret = Expression_optimize(add, result, keepLvalue); return; @@ -862,7 +863,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) return returnE_e1(); // can always convert a class to Object // Need to determine correct offset before optimizing away the cast. // https://issues.dlang.org/show_bug.cgi?id=16980 - cdfrom.size(e.loc); + if (cdfrom.size(e.loc) == SIZE_INVALID) + return error(); assert(cdfrom.sizeok == Sizeok.done); assert(cdto.sizeok == Sizeok.done || !cdto.isBaseOf(cdfrom, null)); int offset; diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index 93c7ea0..6eb3021 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/grammar.html, D Grammar) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/parse.d, _parse.d) @@ -20,6 +20,7 @@ import dmd.globals; import dmd.id; import dmd.identifier; import dmd.lexer; +import dmd.location; import dmd.errors; import dmd.root.filename; import dmd.common.outbuffer; @@ -52,7 +53,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer */ extern (D) this(const ref Loc loc, AST.Module _module, const(char)[] input, bool doDocComment) { - super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false); + super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false, + global.vendor, global.versionNumber()); //printf("Parser::Parser()\n"); scanloc = loc; @@ -74,7 +76,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer extern (D) this(AST.Module _module, const(char)[] input, bool doDocComment) { - super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false); + super(_module ? _module.srcfile.toChars() : null, input.ptr, 0, input.length, doDocComment, false, + global.vendor, global.versionNumber()); //printf("Parser::Parser()\n"); mod = _module; @@ -1982,7 +1985,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { const loc = token.loc; AST.Expression exp; - AST.Expression msg = null; + AST.Expressions* msg = null; //printf("parseStaticAssert()\n"); nextToken(); @@ -1991,15 +1994,16 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer exp = parseAssignExp(); if (token.value == TOK.comma) { - nextToken(); - if (token.value != TOK.rightParenthesis) + if (peekNext() == TOK.rightParenthesis) { - msg = parseAssignExp(); - if (token.value == TOK.comma) - nextToken(); + nextToken(); // consume `,` + nextToken(); // consume `)` } + else + msg = parseArguments(); } - check(TOK.rightParenthesis); + else + check(TOK.rightParenthesis); check(TOK.semicolon, "static assert"); return new AST.StaticAssert(loc, exp, msg); } @@ -5719,6 +5723,8 @@ LagainStc: s = null; else if (token.value == TOK.leftCurly) s = parseStatement(ParseStatementFlags.curly | ParseStatementFlags.scope_); + else if (flags & ParseStatementFlags.curlyScope) + s = parseStatement(ParseStatementFlags.semiOk | ParseStatementFlags.curlyScope); else s = parseStatement(ParseStatementFlags.semiOk); s = new AST.LabelStatement(loc, ident, s); diff --git a/gcc/d/dmd/printast.d b/gcc/d/dmd/printast.d index 8c71a1a..9975c9c 100644 --- a/gcc/d/dmd/printast.d +++ b/gcc/d/dmd/printast.d @@ -1,7 +1,7 @@ /** * Provides an AST printer for debugging. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/printast.d, _printast.d) diff --git a/gcc/d/dmd/root/aav.d b/gcc/d/dmd/root/aav.d index beceb0f0..42d1399 100644 --- a/gcc/d/dmd/root/aav.d +++ b/gcc/d/dmd/root/aav.d @@ -1,7 +1,7 @@ /** * Associative array implementation. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/aav.d, root/_aav.d) diff --git a/gcc/d/dmd/root/array.d b/gcc/d/dmd/root/array.d index 5c01940..e352c61 100644 --- a/gcc/d/dmd/root/array.d +++ b/gcc/d/dmd/root/array.d @@ -2,7 +2,7 @@ /** * Dynamic array implementation. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/array.d, root/_array.d) diff --git a/gcc/d/dmd/root/array.h b/gcc/d/dmd/root/array.h index 52bed5e..ebe2c47 100644 --- a/gcc/d/dmd/root/array.h +++ b/gcc/d/dmd/root/array.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2022 by The D Language Foundation, All Rights Reserved +/* Copyright (C) 2011-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/root/bitarray.d b/gcc/d/dmd/root/bitarray.d index 90cbaed..66adab6 100644 --- a/gcc/d/dmd/root/bitarray.d +++ b/gcc/d/dmd/root/bitarray.d @@ -1,7 +1,7 @@ /** * Implementation of a bit array. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/bitarray.d, root/_bitarray.d) diff --git a/gcc/d/dmd/root/bitarray.h b/gcc/d/dmd/root/bitarray.h index c5c5d3a..617cc9e 100644 --- a/gcc/d/dmd/root/bitarray.h +++ b/gcc/d/dmd/root/bitarray.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2022 by The D Language Foundation, All Rights Reserved +/* Copyright (C) 2011-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/root/complex.d b/gcc/d/dmd/root/complex.d index a7a7438..fc93bd7 100644 --- a/gcc/d/dmd/root/complex.d +++ b/gcc/d/dmd/root/complex.d @@ -1,7 +1,7 @@ /** * Implements a complex number type. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/complex.d, _complex.d) diff --git a/gcc/d/dmd/root/complex_t.h b/gcc/d/dmd/root/complex_t.h index c384848..de2040b 100644 --- a/gcc/d/dmd/root/complex_t.h +++ b/gcc/d/dmd/root/complex_t.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/root/ctfloat.d b/gcc/d/dmd/root/ctfloat.d index 8c2fe46..cd336e6 100644 --- a/gcc/d/dmd/root/ctfloat.d +++ b/gcc/d/dmd/root/ctfloat.d @@ -1,7 +1,7 @@ /** * Collects functions for compile-time floating-point calculations. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/ctfloat.d, root/_ctfloat.d) diff --git a/gcc/d/dmd/root/ctfloat.h b/gcc/d/dmd/root/ctfloat.h index 5a6cf25..44bd959e 100644 --- a/gcc/d/dmd/root/ctfloat.h +++ b/gcc/d/dmd/root/ctfloat.h @@ -1,5 +1,5 @@ -/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved +/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/root/dcompat.h b/gcc/d/dmd/root/dcompat.h index 5823e7c..0bc23b7 100644 --- a/gcc/d/dmd/root/dcompat.h +++ b/gcc/d/dmd/root/dcompat.h @@ -1,5 +1,5 @@ -/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved +/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/root/file.d b/gcc/d/dmd/root/file.d index b40413c..1fb1056 100644 --- a/gcc/d/dmd/root/file.d +++ b/gcc/d/dmd/root/file.d @@ -1,7 +1,7 @@ /** * Read a file from disk and store it in memory. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/file.d, root/_file.d) diff --git a/gcc/d/dmd/root/filename.d b/gcc/d/dmd/root/filename.d index f6a4515..33f4a7a 100644 --- a/gcc/d/dmd/root/filename.d +++ b/gcc/d/dmd/root/filename.d @@ -1,7 +1,7 @@ /** * Encapsulate path and file names. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/filename.d, root/_filename.d) diff --git a/gcc/d/dmd/root/filename.h b/gcc/d/dmd/root/filename.h index 419a4c9..8977411 100644 --- a/gcc/d/dmd/root/filename.h +++ b/gcc/d/dmd/root/filename.h @@ -1,5 +1,5 @@ -/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved +/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/root/hash.d b/gcc/d/dmd/root/hash.d index fe97c42..2acee35 100644 --- a/gcc/d/dmd/root/hash.d +++ b/gcc/d/dmd/root/hash.d @@ -1,7 +1,7 @@ /** * Hash functions for arbitrary binary data. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Martin Nowak, Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/hash.d, root/_hash.d) diff --git a/gcc/d/dmd/root/object.h b/gcc/d/dmd/root/object.h index b735dd9..8e505f0 100644 --- a/gcc/d/dmd/root/object.h +++ b/gcc/d/dmd/root/object.h @@ -1,5 +1,5 @@ -/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved +/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/root/optional.d b/gcc/d/dmd/root/optional.d index 266846b..bc1016b 100644 --- a/gcc/d/dmd/root/optional.d +++ b/gcc/d/dmd/root/optional.d @@ -1,7 +1,7 @@ /** * Implementation of an 'Optional' type * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/optional.d, root/_optional.d) diff --git a/gcc/d/dmd/root/optional.h b/gcc/d/dmd/root/optional.h index e4a41a0..cc2ee79 100644 --- a/gcc/d/dmd/root/optional.h +++ b/gcc/d/dmd/root/optional.h @@ -3,7 +3,7 @@ /** * Optional implementation. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/optional.h, root/_optional.h) diff --git a/gcc/d/dmd/root/port.d b/gcc/d/dmd/root/port.d index 0c8088c..290280f 100644 --- a/gcc/d/dmd/root/port.d +++ b/gcc/d/dmd/root/port.d @@ -1,7 +1,7 @@ /** * Portable routines for functions that have different implementations on different platforms. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/port.d, root/_port.d) diff --git a/gcc/d/dmd/root/port.h b/gcc/d/dmd/root/port.h index 66a6760..6fa3c00 100644 --- a/gcc/d/dmd/root/port.h +++ b/gcc/d/dmd/root/port.h @@ -1,5 +1,5 @@ -/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved +/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/root/region.d b/gcc/d/dmd/root/region.d index 1e86f32..9fc57f1 100644 --- a/gcc/d/dmd/root/region.d +++ b/gcc/d/dmd/root/region.d @@ -1,7 +1,7 @@ /** * Region storage allocator implementation. * - * Copyright: Copyright (C) 2019-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 2019-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/region.d, root/_region.d) diff --git a/gcc/d/dmd/root/rmem.d b/gcc/d/dmd/root/rmem.d index ffe5ee1..9b1d9fb 100644 --- a/gcc/d/dmd/root/rmem.d +++ b/gcc/d/dmd/root/rmem.d @@ -1,7 +1,7 @@ /** * Allocate memory using `malloc` or the GC depending on the configuration. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/rmem.d, root/_rmem.d) diff --git a/gcc/d/dmd/root/rmem.h b/gcc/d/dmd/root/rmem.h index 1338d7c..36aa264 100644 --- a/gcc/d/dmd/root/rmem.h +++ b/gcc/d/dmd/root/rmem.h @@ -1,5 +1,5 @@ -/* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved +/* Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/root/rootobject.d b/gcc/d/dmd/root/rootobject.d index 7390d07..4437d16 100644 --- a/gcc/d/dmd/root/rootobject.d +++ b/gcc/d/dmd/root/rootobject.d @@ -1,7 +1,7 @@ /** * Provide the root object that classes in dmd inherit from. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/rootobject.d, root/_rootobject.d) diff --git a/gcc/d/dmd/root/speller.d b/gcc/d/dmd/root/speller.d index 9b9460d..b646bdd 100644 --- a/gcc/d/dmd/root/speller.d +++ b/gcc/d/dmd/root/speller.d @@ -3,7 +3,7 @@ * * Does not have any dependencies on the rest of DMD. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/speller.d, root/_speller.d) diff --git a/gcc/d/dmd/root/string.d b/gcc/d/dmd/root/string.d index 93c596f..8b204ab 100644 --- a/gcc/d/dmd/root/string.d +++ b/gcc/d/dmd/root/string.d @@ -1,7 +1,7 @@ /** * Contains various string related functions. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/string.d, root/_string.d) diff --git a/gcc/d/dmd/root/stringtable.d b/gcc/d/dmd/root/stringtable.d index 20316fa..de293eb 100644 --- a/gcc/d/dmd/root/stringtable.d +++ b/gcc/d/dmd/root/stringtable.d @@ -1,7 +1,7 @@ /** * A specialized associative array with string keys stored in a variable length structure. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: Walter Bright, https://www.digitalmars.com * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/stringtable.d, root/_stringtable.d) diff --git a/gcc/d/dmd/root/utf.d b/gcc/d/dmd/root/utf.d index 0d230e7..c9781a4 100644 --- a/gcc/d/dmd/root/utf.d +++ b/gcc/d/dmd/root/utf.d @@ -1,7 +1,7 @@ /** * Functions related to UTF encoding. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/utf.d, _utf.d) diff --git a/gcc/d/dmd/safe.d b/gcc/d/dmd/safe.d index 397fd2ef..c3fa90d 100644 --- a/gcc/d/dmd/safe.d +++ b/gcc/d/dmd/safe.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/function.html#function-safety, Function Safety) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/safe.d, _safe.d) diff --git a/gcc/d/dmd/sapply.d b/gcc/d/dmd/sapply.d index adfae32..8486028 100644 --- a/gcc/d/dmd/sapply.d +++ b/gcc/d/dmd/sapply.d @@ -1,7 +1,7 @@ /** * Provides a depth-first statement visitor. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/sparse.d, _sparse.d) diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h index 8b9e59e..b25c26a 100644 --- a/gcc/d/dmd/scope.h +++ b/gcc/d/dmd/scope.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d index 4795bcf..c103f60 100644 --- a/gcc/d/dmd/semantic2.d +++ b/gcc/d/dmd/semantic2.d @@ -1,7 +1,7 @@ /** * Performs the semantic2 stage, which deals with initializer expressions. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/semantic2.d, _semantic2.d) @@ -110,21 +110,36 @@ private extern(C++) final class Semantic2Visitor : Visitor else if (result) return; - if (sa.msg) + if (sa.msgs) { - sc = sc.startCTFE(); - sa.msg = sa.msg.expressionSemantic(sc); - sa.msg = resolveProperties(sc, sa.msg); - sc = sc.endCTFE(); - sa.msg = sa.msg.ctfeInterpret(); - if (StringExp se = sa.msg.toStringExp()) + OutBuffer msgbuf; + for (size_t i = 0; i < sa.msgs.length; i++) { - // same with pragma(msg) - const slice = se.toUTF8(sc).peekString(); - error(sa.loc, "static assert: \"%.*s\"", cast(int)slice.length, slice.ptr); + Expression e = (*sa.msgs)[i]; + sc = sc.startCTFE(); + e = e.expressionSemantic(sc); + e = resolveProperties(sc, e); + sc = sc.endCTFE(); + e = ctfeInterpretForPragmaMsg(e); + if (e.op == EXP.error) + { + errorSupplemental(sa.loc, "while evaluating `static assert` argument `%s`", (*sa.msgs)[i].toChars()); + return; + } + StringExp se = e.toStringExp(); + if (se) + { + const slice = se.toUTF8(sc).peekString(); + // Hack to keep old formatting to avoid changing error messages everywhere + if (sa.msgs.length == 1) + msgbuf.printf("\"%.*s\"", cast(int)slice.length, slice.ptr); + else + msgbuf.printf("%.*s", cast(int)slice.length, slice.ptr); + } + else + msgbuf.printf("%s", e.toChars()); } - else - error(sa.loc, "static assert: %s", sa.msg.toChars()); + error(sa.loc, "static assert: %s", msgbuf.extractChars()); } else error(sa.loc, "static assert: `%s` is false", sa.exp.toChars()); diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index cc75aa5..78da4a1 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -1,7 +1,7 @@ /** * Performs the semantic3 stage, which deals with function bodies. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/semantic3.d, _semantic3.d) @@ -47,6 +47,7 @@ import dmd.identifier; import dmd.init; import dmd.initsem; import dmd.hdrgen; +import dmd.location; import dmd.mtype; import dmd.nogc; import dmd.nspace; diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d index f7a3836..ed93876 100644 --- a/gcc/d/dmd/sideeffect.d +++ b/gcc/d/dmd/sideeffect.d @@ -1,7 +1,7 @@ /** * Find side-effects of expressions. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/sideeffect.d, _sideeffect.d) diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d index 91a802e..96c59ba 100644 --- a/gcc/d/dmd/statement.d +++ b/gcc/d/dmd/statement.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/statement.html, Statements) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statement.d, _statement.d) @@ -36,6 +36,7 @@ import dmd.globals; import dmd.hdrgen; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.dinterpret; import dmd.mtype; import dmd.common.outbuffer; @@ -323,6 +324,10 @@ extern (C++) abstract class Statement : ASTNode override void visit(DefaultStatement s) { } + + override void visit(LabelStatement s) + { + } } scope HasCode hc = new HasCode(); diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h index 681b481..76a3991 100644 --- a/gcc/d/dmd/statement.h +++ b/gcc/d/dmd/statement.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/statement_rewrite_walker.d b/gcc/d/dmd/statement_rewrite_walker.d index 7b3a13b..dcdd963 100644 --- a/gcc/d/dmd/statement_rewrite_walker.d +++ b/gcc/d/dmd/statement_rewrite_walker.d @@ -1,7 +1,7 @@ /** * Provides a visitor for statements that allows rewriting the currently visited node. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statement_rewrite_walker.d, _statement_rewrite_walker.d) diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index b372fc2..5764efd 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/statement.html, Statements) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statementsem.d, _statementsem.d) @@ -50,6 +50,7 @@ import dmd.identifier; import dmd.importc; import dmd.init; import dmd.intrange; +import dmd.location; import dmd.mtype; import dmd.mustuse; import dmd.nogc; diff --git a/gcc/d/dmd/staticassert.d b/gcc/d/dmd/staticassert.d index c7d3148..15c46b3 100644 --- a/gcc/d/dmd/staticassert.d +++ b/gcc/d/dmd/staticassert.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/version.html#static-assert, Static Assert) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/staticassert.d, _staticassert.d) @@ -13,10 +13,12 @@ module dmd.staticassert; +import dmd.arraytypes; import dmd.dscope; import dmd.dsymbol; import dmd.expression; import dmd.globals; +import dmd.location; import dmd.id; import dmd.identifier; import dmd.mtype; @@ -27,19 +29,27 @@ import dmd.visitor; extern (C++) final class StaticAssert : Dsymbol { Expression exp; - Expression msg; + Expressions* msgs; extern (D) this(const ref Loc loc, Expression exp, Expression msg) { super(loc, Id.empty); this.exp = exp; - this.msg = msg; + this.msgs = new Expressions(1); + (*this.msgs)[0] = msg; + } + + extern (D) this(const ref Loc loc, Expression exp, Expressions* msgs) + { + super(loc, Id.empty); + this.exp = exp; + this.msgs = msgs; } override StaticAssert syntaxCopy(Dsymbol s) { assert(!s); - return new StaticAssert(loc, exp.syntaxCopy(), msg ? msg.syntaxCopy() : null); + return new StaticAssert(loc, exp.syntaxCopy(), msgs ? Expression.arraySyntaxCopy(msgs) : null); } override void addMember(Scope* sc, ScopeDsymbol sds) diff --git a/gcc/d/dmd/staticassert.h b/gcc/d/dmd/staticassert.h index d938990..2b7d300 100644 --- a/gcc/d/dmd/staticassert.h +++ b/gcc/d/dmd/staticassert.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. @@ -18,7 +18,7 @@ class StaticAssert : public Dsymbol { public: Expression *exp; - Expression *msg; + Expressions *msg; StaticAssert *syntaxCopy(Dsymbol *s) override; void addMember(Scope *sc, ScopeDsymbol *sds) override; diff --git a/gcc/d/dmd/staticcond.d b/gcc/d/dmd/staticcond.d index 0cbdd96..aa6f37c 100644 --- a/gcc/d/dmd/staticcond.d +++ b/gcc/d/dmd/staticcond.d @@ -1,7 +1,7 @@ /** * Lazily evaluate static conditions for `static if`, `static assert` and template constraints. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/staticcond.d, _staticcond.d) diff --git a/gcc/d/dmd/stmtstate.d b/gcc/d/dmd/stmtstate.d index 3e26b8f..7b2ea97 100644 --- a/gcc/d/dmd/stmtstate.d +++ b/gcc/d/dmd/stmtstate.d @@ -1,7 +1,7 @@ /** * Used to help transform statement AST into flow graph. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/stmtstate.d, _stmtstate.d) diff --git a/gcc/d/dmd/target.d b/gcc/d/dmd/target.d index eb85c67..fddfd54 100644 --- a/gcc/d/dmd/target.d +++ b/gcc/d/dmd/target.d @@ -15,7 +15,7 @@ * - $(LINK2 https://github.com/ldc-developers/ldc, LDC repository) * - $(LINK2 https://github.com/D-Programming-GDC/gcc, GDC repository) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/target.d, _target.d) @@ -61,7 +61,7 @@ extern (C++) struct Target import dmd.dscope : Scope; import dmd.expression : Expression; import dmd.func : FuncDeclaration; - import dmd.globals : Loc; + import dmd.location; import dmd.astenums : LINK, TY; import dmd.mtype : Type, TypeFunction, TypeTuple; import dmd.root.ctfloat : real_t; diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h index 096c16f..ef2c09d 100644 --- a/gcc/d/dmd/target.h +++ b/gcc/d/dmd/target.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 2013-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 2013-2023 by The D Language Foundation, All Rights Reserved * written by Iain Buclaw * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h index 9ad027a..8e8ba16 100644 --- a/gcc/d/dmd/template.h +++ b/gcc/d/dmd/template.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. @@ -70,7 +70,6 @@ public: bool isTrivialAlias; // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }` bool deprecated_; // this template declaration is deprecated Visibility visibility; - int inuse; // for recursive expansion detection TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack diff --git a/gcc/d/dmd/templateparamsem.d b/gcc/d/dmd/templateparamsem.d index e79a9ec..432daee 100644 --- a/gcc/d/dmd/templateparamsem.d +++ b/gcc/d/dmd/templateparamsem.d @@ -1,7 +1,7 @@ /** * Semantic analysis of template parameters. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/templateparamsem.d, _templateparamsem.d) @@ -16,6 +16,7 @@ import dmd.dsymbol; import dmd.dscope; import dmd.dtemplate; import dmd.globals; +import dmd.location; import dmd.expression; import dmd.expressionsem; import dmd.root.rootobject; diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d index 86abedf..b3cd2d3 100644 --- a/gcc/d/dmd/tokens.d +++ b/gcc/d/dmd/tokens.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/lex.html#tokens, Tokens) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/tokens.d, _tokens.d) @@ -16,8 +16,8 @@ module dmd.tokens; import core.stdc.ctype; import core.stdc.stdio; import core.stdc.string; -import dmd.globals; import dmd.identifier; +import dmd.location; import dmd.root.ctfloat; import dmd.common.outbuffer; import dmd.root.rmem; @@ -636,8 +636,8 @@ extern (C++) struct Token union { // Integers - sinteger_t intvalue; - uinteger_t unsvalue; + long intvalue; + ulong unsvalue; // Floats real_t floatvalue; diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h index 35fd68b..32ae5f4 100644 --- a/gcc/d/dmd/tokens.h +++ b/gcc/d/dmd/tokens.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index a6d2304..048c24f 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -3,7 +3,7 @@ * * Specification: $(LINK2 https://dlang.org/spec/traits.html, Traits) * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/traits.d, _traits.d) @@ -38,6 +38,7 @@ import dmd.globals; import dmd.hdrgen; import dmd.id; import dmd.identifier; +import dmd.location; import dmd.mtype; import dmd.nogc; import dmd.parse; @@ -88,82 +89,6 @@ private Dsymbol getDsymbolWithoutExpCtx(RootObject oarg) return getDsymbol(oarg); } -private const StringTable!bool traitsStringTable; - -shared static this() -{ - static immutable string[] names = - [ - "isAbstractClass", - "isArithmetic", - "isAssociativeArray", - "isDisabled", - "isDeprecated", - "isFuture", - "isFinalClass", - "isPOD", - "isNested", - "isFloating", - "isIntegral", - "isScalar", - "isStaticArray", - "isUnsigned", - "isVirtualFunction", - "isVirtualMethod", - "isAbstractFunction", - "isFinalFunction", - "isOverrideFunction", - "isStaticFunction", - "isModule", - "isPackage", - "isRef", - "isOut", - "isLazy", - "isReturnOnStack", - "hasMember", - "identifier", - "getProtection", - "getVisibility", - "parent", - "child", - "getLinkage", - "getMember", - "getOverloads", - "getVirtualFunctions", - "getVirtualMethods", - "classInstanceSize", - "classInstanceAlignment", - "allMembers", - "derivedMembers", - "isSame", - "compiles", - "getAliasThis", - "getAttributes", - "getFunctionAttributes", - "getFunctionVariadicStyle", - "getParameterStorageClasses", - "getUnitTests", - "getVirtualIndex", - "getPointerBitmap", - "isZeroInit", - "getTargetInfo", - "getLocation", - "hasPostblit", - "hasCopyConstructor", - "isCopyable", - "parameters" - ]; - - StringTable!(bool)* stringTable = cast(StringTable!(bool)*) &traitsStringTable; - stringTable._init(names.length); - - foreach (s; names) - { - auto sv = stringTable.insert(s, true); - assert(sv); - } -} - /** * get an array of size_t values that indicate possible pointer words in memory * if interpreted as the type given as argument @@ -2122,20 +2047,11 @@ Expression semanticTraits(TraitsExp e, Scope* sc) auto tup = new TupleExp(e.loc, exps); return tup.expressionSemantic(sc); } - static const(char)[] trait_search_fp(const(char)[] seed, out int cost) - { - //printf("trait_search_fp('%s')\n", seed); - if (!seed.length) - return null; - cost = 0; // all the same cost - const sv = traitsStringTable.lookup(seed); - return sv ? sv.toString() : null; - } - if (auto sub = speller!trait_search_fp(e.ident.toString())) - e.error("unrecognized trait `%s`, did you mean `%.*s`?", e.ident.toChars(), cast(int) sub.length, sub.ptr); - else - e.error("unrecognized trait `%s`", e.ident.toChars()); + /* Can't find the identifier. Try a spell check for a better error message + */ + traitNotFound(e); + return ErrorExp.get(); } @@ -2263,3 +2179,108 @@ Lnext: } return true; } + + +/*********************************** + * A trait was not found. Give a decent error message + * by trying a spell check. + * Params: + * e = the offending trait + */ +private void traitNotFound(TraitsExp e) +{ + __gshared const StringTable!bool traitsStringTable; + __gshared bool initialized; + + if (!initialized) + { + initialized = true; // lazy initialization + + // All possible traits + __gshared Identifier*[58] idents = + [ + &Id.isAbstractClass, + &Id.isArithmetic, + &Id.isAssociativeArray, + &Id.isDisabled, + &Id.isDeprecated, + &Id.isFuture, + &Id.isFinalClass, + &Id.isPOD, + &Id.isNested, + &Id.isFloating, + &Id.isIntegral, + &Id.isScalar, + &Id.isStaticArray, + &Id.isUnsigned, + &Id.isVirtualFunction, + &Id.isVirtualMethod, + &Id.isAbstractFunction, + &Id.isFinalFunction, + &Id.isOverrideFunction, + &Id.isStaticFunction, + &Id.isModule, + &Id.isPackage, + &Id.isRef, + &Id.isOut, + &Id.isLazy, + &Id.isReturnOnStack, + &Id.hasMember, + &Id.identifier, + &Id.getProtection, + &Id.getVisibility, + &Id.parent, + &Id.child, + &Id.getLinkage, + &Id.getMember, + &Id.getOverloads, + &Id.getVirtualFunctions, + &Id.getVirtualMethods, + &Id.classInstanceSize, + &Id.classInstanceAlignment, + &Id.allMembers, + &Id.derivedMembers, + &Id.isSame, + &Id.compiles, + &Id.getAliasThis, + &Id.getAttributes, + &Id.getFunctionAttributes, + &Id.getFunctionVariadicStyle, + &Id.getParameterStorageClasses, + &Id.getUnitTests, + &Id.getVirtualIndex, + &Id.getPointerBitmap, + &Id.isZeroInit, + &Id.getTargetInfo, + &Id.getLocation, + &Id.hasPostblit, + &Id.hasCopyConstructor, + &Id.isCopyable, + &Id.parameters, + ]; + + StringTable!(bool)* stringTable = cast(StringTable!(bool)*) &traitsStringTable; + stringTable._init(idents.length); + + foreach (id; idents) + { + auto sv = stringTable.insert((*id).toString(), true); + assert(sv); + } + } + + static const(char)[] trait_search_fp(const(char)[] seed, out int cost) + { + //printf("trait_search_fp('%s')\n", seed); + if (!seed.length) + return null; + cost = 0; // all the same cost + const sv = traitsStringTable.lookup(seed); + return sv ? sv.toString() : null; + } + + if (auto sub = speller!trait_search_fp(e.ident.toString())) + e.error("unrecognized trait `%s`, did you mean `%.*s`?", e.ident.toChars(), cast(int) sub.length, sub.ptr); + else + e.error("unrecognized trait `%s`", e.ident.toChars()); +} diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d index 7aaf0b8..5844911 100644 --- a/gcc/d/dmd/transitivevisitor.d +++ b/gcc/d/dmd/transitivevisitor.d @@ -490,8 +490,9 @@ package mixin template ParseVisitMethods(AST) { //printf("Visiting StaticAssert\n"); s.exp.accept(this); - if (s.msg) - s.msg.accept(this); + if (s.msgs) + foreach (m; (*s.msgs)[]) + m.accept(this); } override void visit(AST.EnumMember em) diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index a75b416..0d64ba4 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -1,7 +1,7 @@ /** * Semantic analysis for D types. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/typesem.d, _typesem.d) @@ -46,6 +46,7 @@ import dmd.imphint; import dmd.importc; import dmd.init; import dmd.initsem; +import dmd.location; import dmd.visitor; import dmd.mtype; import dmd.objc; @@ -234,7 +235,7 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb .error(loc, "`%s` is not visible from module `%s`", sm.toPrettyChars(), sc._module.toChars()); sm = null; } - // Same check as in Expression.semanticY(DotIdExp) + // Same check as in dotIdSemanticProp(DotIdExp) else if (sm.isPackage() && checkAccess(sc, sm.isPackage())) { // @@@DEPRECATED_2.106@@@ @@ -3685,7 +3686,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) * template opDispatch(name) if (isValid!name) { ... } */ uint errors = gagError ? global.startGagging() : 0; - e = dti.semanticY(sc, 0); + e = dti.dotTemplateSemanticProp(sc, 0); if (gagError && global.endGagging(errors)) e = null; return returnExp(e); @@ -3703,7 +3704,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) auto die = new DotIdExp(e.loc, alias_e, ident); auto errors = gagError ? 0 : global.startGagging(); - auto exp = die.semanticY(sc, gagError); + auto exp = die.dotIdSemanticProp(sc, gagError); if (!gagError) { global.endGagging(errors); @@ -3959,7 +3960,14 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) Dsymbol s = mt.sym.search(e.loc, ident); if (!s) { - if (ident == Id.max || ident == Id.min || ident == Id._init) + if (ident == Id._init) + { + return mt.getProperty(sc, e.loc, ident, flag & 1); + } + + /* Allow special enums to not need a member list + */ + if ((ident == Id.max || ident == Id.min) && (mt.sym.members || !mt.sym.isSpecial())) { return mt.getProperty(sc, e.loc, ident, flag & 1); } @@ -4880,13 +4888,6 @@ Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identifier id) return errorReturn(); if (!ed.members) { - if (ed.isSpecial()) - { - /* Allow these special enums to not need a member list - */ - return ed.memtype.getProperty(ed._scope, loc, id, 0); - } - ed.error(loc, "is opaque and has no `.%s`", id.toChars()); return errorReturn(); } diff --git a/gcc/d/dmd/typinf.d b/gcc/d/dmd/typinf.d index b701be3..b35e03d 100644 --- a/gcc/d/dmd/typinf.d +++ b/gcc/d/dmd/typinf.d @@ -1,7 +1,7 @@ /** * Generate `TypeInfo` objects, which are needed for run-time introspection of types. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/typeinf.d, _typeinf.d) @@ -21,6 +21,7 @@ import dmd.errors; import dmd.expression; import dmd.globals; import dmd.gluelayer; +import dmd.location; import dmd.mtype; import dmd.visitor; import core.stdc.stdio; diff --git a/gcc/d/dmd/utils.d b/gcc/d/dmd/utils.d index 5be4a19..dfb4cb5 100644 --- a/gcc/d/dmd/utils.d +++ b/gcc/d/dmd/utils.d @@ -1,7 +1,7 @@ /** * This module defines some utility functions for DMD. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/utils.d, _utils.d) @@ -13,7 +13,7 @@ module dmd.utils; import core.stdc.string; import dmd.errors; -import dmd.globals; +import dmd.location; import dmd.root.file; import dmd.root.filename; import dmd.common.outbuffer; diff --git a/gcc/d/dmd/version.h b/gcc/d/dmd/version.h index b76393bc..697d46e 100644 --- a/gcc/d/dmd/version.h +++ b/gcc/d/dmd/version.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. diff --git a/gcc/d/dmd/visitor.d b/gcc/d/dmd/visitor.d index e6dfa11..e4c2a91 100644 --- a/gcc/d/dmd/visitor.d +++ b/gcc/d/dmd/visitor.d @@ -1,7 +1,7 @@ /** * Provides a visitor class visiting all AST nodes present in the compiler. * - * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved + * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/visitor.d, _visitor.d) diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h index b45ef79..f8cbdb4 100644 --- a/gcc/d/dmd/visitor.h +++ b/gcc/d/dmd/visitor.h @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 2013-2022 by The D Language Foundation, All Rights Reserved + * Copyright (C) 2013-2023 by The D Language Foundation, All Rights Reserved * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. * https://www.boost.org/LICENSE_1_0.txt diff --git a/gcc/testsuite/gdc.dg/simd2a.d b/gcc/testsuite/gdc.dg/simd2a.d index d64f704..373d5d1 100644 --- a/gcc/testsuite/gdc.dg/simd2a.d +++ b/gcc/testsuite/gdc.dg/simd2a.d @@ -18,12 +18,12 @@ void test2a() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); v1 = v2 << 1; v1 = v2 >> 1; v1 = v2 >>> 1; diff --git a/gcc/testsuite/gdc.dg/simd2b.d b/gcc/testsuite/gdc.dg/simd2b.d index 71abd78..e72da0d 100644 --- a/gcc/testsuite/gdc.dg/simd2b.d +++ b/gcc/testsuite/gdc.dg/simd2b.d @@ -18,12 +18,12 @@ void test2b() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); v1 = v2 << 1; v1 = v2 >> 1; v1 = v2 >>> 1; diff --git a/gcc/testsuite/gdc.dg/simd2c.d b/gcc/testsuite/gdc.dg/simd2c.d index 4806b48..dc4954e 100644 --- a/gcc/testsuite/gdc.dg/simd2c.d +++ b/gcc/testsuite/gdc.dg/simd2c.d @@ -18,12 +18,12 @@ void test2c() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); v1 = v2 << 1; v1 = v2 >> 1; v1 = v2 >>> 1; diff --git a/gcc/testsuite/gdc.dg/simd2d.d b/gcc/testsuite/gdc.dg/simd2d.d index ce447e1..2d782ba 100644 --- a/gcc/testsuite/gdc.dg/simd2d.d +++ b/gcc/testsuite/gdc.dg/simd2d.d @@ -18,12 +18,12 @@ void test2d() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); v1 = v2 << 1; v1 = v2 >> 1; v1 = v2 >>> 1; diff --git a/gcc/testsuite/gdc.dg/simd2e.d b/gcc/testsuite/gdc.dg/simd2e.d index 464d1a5..b6d4ed6 100644 --- a/gcc/testsuite/gdc.dg/simd2e.d +++ b/gcc/testsuite/gdc.dg/simd2e.d @@ -18,12 +18,12 @@ void test2e() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); v1 = v2 << 1; v1 = v2 >> 1; v1 = v2 >>> 1; diff --git a/gcc/testsuite/gdc.dg/simd2f.d b/gcc/testsuite/gdc.dg/simd2f.d index d7e67fc..df8f13f 100644 --- a/gcc/testsuite/gdc.dg/simd2f.d +++ b/gcc/testsuite/gdc.dg/simd2f.d @@ -18,12 +18,12 @@ void test2f() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); v1 = v2 << 1; v1 = v2 >> 1; v1 = v2 >>> 1; diff --git a/gcc/testsuite/gdc.dg/simd2g.d b/gcc/testsuite/gdc.dg/simd2g.d index 3d15869..028b25e 100644 --- a/gcc/testsuite/gdc.dg/simd2g.d +++ b/gcc/testsuite/gdc.dg/simd2g.d @@ -18,12 +18,12 @@ void test2g() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); v1 = v2 << 1; v1 = v2 >> 1; v1 = v2 >>> 1; diff --git a/gcc/testsuite/gdc.dg/simd2h.d b/gcc/testsuite/gdc.dg/simd2h.d index 849b6ad..6c3e91a 100644 --- a/gcc/testsuite/gdc.dg/simd2h.d +++ b/gcc/testsuite/gdc.dg/simd2h.d @@ -18,12 +18,12 @@ void test2h() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); v1 = v2 << 1; v1 = v2 >> 1; v1 = v2 >>> 1; diff --git a/gcc/testsuite/gdc.dg/simd2i.d b/gcc/testsuite/gdc.dg/simd2i.d index 03130b7..2fa7f3a 100644 --- a/gcc/testsuite/gdc.dg/simd2i.d +++ b/gcc/testsuite/gdc.dg/simd2i.d @@ -18,12 +18,12 @@ void test2i() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); static assert(!__traits(compiles, v1 << 1)); static assert(!__traits(compiles, v1 >> 1)); static assert(!__traits(compiles, v1 >>> 1)); diff --git a/gcc/testsuite/gdc.dg/simd2j.d b/gcc/testsuite/gdc.dg/simd2j.d index f86a448..7c2d12f 100644 --- a/gcc/testsuite/gdc.dg/simd2j.d +++ b/gcc/testsuite/gdc.dg/simd2j.d @@ -18,12 +18,12 @@ void test2j() static assert(!__traits(compiles, v1 ^^ v2)); static assert(!__traits(compiles, v1 is v2)); static assert(!__traits(compiles, v1 !is v2)); - v1 = v1 == v2; - v1 = v1 != v2; - v1 = v1 < v2; - v1 = v1 > v2; - v1 = v1 <= v2; - v1 = v1 >= v2; + static assert( __traits(compiles, v1 == v2)); + static assert( __traits(compiles, v1 != v2)); + static assert( __traits(compiles, v1 < v2)); + static assert( __traits(compiles, v1 > v2)); + static assert( __traits(compiles, v1 <= v2)); + static assert( __traits(compiles, v1 >= v2)); static assert(!__traits(compiles, v1 << 1)); static assert(!__traits(compiles, v1 >> 1)); static assert(!__traits(compiles, v1 >>> 1)); diff --git a/gcc/testsuite/gdc.test/compilable/extra-files/build23499.d b/gcc/testsuite/gdc.test/compilable/extra-files/build23499.d new file mode 100644 index 0000000..1983b4a --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/extra-files/build23499.d @@ -0,0 +1,7 @@ +import imports.file23499; + +bool do_build() +{ + string outdir ; + return (exists(outdir)); +} diff --git a/gcc/testsuite/gdc.test/compilable/imports/file23499.d b/gcc/testsuite/gdc.test/compilable/imports/file23499.d new file mode 100644 index 0000000..76e1b78 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/file23499.d @@ -0,0 +1,19 @@ + +///---- file.d +struct TempCStringBuffer(To ) +{ + ~this() + { + } + To* _ptr; +} + +auto tempCString(To, From)(From) +{ + return TempCStringBuffer!To(); +} + +bool exists(R)(R name) +{ + return name.tempCString!wchar._ptr != null; +} diff --git a/gcc/testsuite/gdc.test/compilable/imports/test23490frop.d b/gcc/testsuite/gdc.test/compilable/imports/test23490frop.d new file mode 100644 index 0000000..13fc78f --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test23490frop.d @@ -0,0 +1,7 @@ +module imports.test23490frop; +import imports.test23490pop; +class Mu23490 : Pop23490 { } +class Frop23490 : Pop23490 { + // final // does not fail if declared final + void frolick() {} +} diff --git a/gcc/testsuite/gdc.test/compilable/imports/test23490pop.d b/gcc/testsuite/gdc.test/compilable/imports/test23490pop.d new file mode 100644 index 0000000..4757bbd --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test23490pop.d @@ -0,0 +1,7 @@ +module imports.test23490pop; +import imports.test23490frop; +import imports.test23490zoo : Zoo23490; +class Pop23490 { + void frop(Frop23490) { } + void zoo(Zoo23490) { } +} diff --git a/gcc/testsuite/gdc.test/compilable/imports/test23490zoo.d b/gcc/testsuite/gdc.test/compilable/imports/test23490zoo.d new file mode 100644 index 0000000..7ae8b97 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test23490zoo.d @@ -0,0 +1,17 @@ +module imports.test23490zoo; +import imports.test23490pop; +import imports.test23490frop; +class Foo23490() : Pop23490 { + override void frop(Frop23490 f) { + f.frolick; + } +} +class Baz23490 { + Foo23490!() foo; + Frop23490 frop; +} +class Bar23490 { + static instance() { return new Baz23490; } + auto ss = __traits(getAttributes, instance.frop); +} +class Zoo23490 { } diff --git a/gcc/testsuite/gdc.test/compilable/isexpalias.d b/gcc/testsuite/gdc.test/compilable/isexpalias.d new file mode 100644 index 0000000..5cd8d8e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/isexpalias.d @@ -0,0 +1,9 @@ +// https://issues.dlang.org/show_bug.cgi?id=23578 +struct S(alias a) +{ +} + +static if (is(S!int == S!av, alias av)) + static assert(is(av == int)); +else + static assert(false); diff --git a/gcc/testsuite/gdc.test/compilable/issue20618.d b/gcc/testsuite/gdc.test/compilable/issue20618.d new file mode 100644 index 0000000..0cc90cf --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/issue20618.d @@ -0,0 +1,10 @@ +// https://issues.dlang.org/show_bug.cgi?id=22198 +// This test was in fail_compilation, however the change in the compiler has +// been reverted to make this code compilable again. +void main() +{ + int[10] a; + auto b = a[1..12]; + auto c = a[4..3]; + auto d = a[0..$ + 1]; +} diff --git a/gcc/testsuite/gdc.test/compilable/issue22646.d b/gcc/testsuite/gdc.test/compilable/issue22646.d new file mode 100644 index 0000000..88a3b60 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/issue22646.d @@ -0,0 +1,67 @@ +// https://issues.dlang.org/show_bug.cgi?id=22646 + +static template logicalOr22646(T, const T name) +{ + enum bool ok = name.length < 3 || name[0..3] != "pad"; +} +static template logicalAnd22646(T, const T name) +{ + enum bool ok = name.length >= 3 && name[0..3] == "pad"; +} + +bool runtime22646Or(T, const T name)() +{ + return name.length < 3 || name[0..3] != "pad"; +} + +// SCOPE.ctfe +static assert(logicalOr22646!(string, "x").ok == true); +static assert(logicalOr22646!(string, "foo").ok == true); +static assert(logicalOr22646!(string, "pad").ok == false); +static assert(logicalOr22646!(string, "pad123").ok == false); + +static assert(logicalOr22646!(char[1], "x").ok == true); +static assert(logicalOr22646!(char[3], "foo").ok == true); +static assert(logicalOr22646!(char[3], "pad").ok == false); +static assert(logicalOr22646!(char[6], "pad123").ok == false); + +static assert(logicalAnd22646!(string, "x").ok == false); +static assert(logicalAnd22646!(string, "foo").ok == false); +static assert(logicalAnd22646!(string, "pad").ok == true); +static assert(logicalAnd22646!(string, "pad123").ok == true); + +static assert(logicalAnd22646!(char[1], "x").ok == false); +static assert(logicalAnd22646!(char[3], "foo").ok == false); +static assert(logicalAnd22646!(char[3], "pad").ok == true); +static assert(logicalAnd22646!(char[6], "pad123").ok == true); + +// SCOPE.compile +enum char[1] x22646 = "x"; +enum char[3] pad22646 = "pad"; + +static assert(__traits(compiles, x22646.length < 3 || x22646[0..3] != "pad") == true); +static assert(__traits(compiles, x22646.length >= 3 || x22646[0..3] == "pad") == true); +static assert(__traits(compiles, pad22646.length < 3 || pad22646[0..3] != "pad") == true); +static assert(__traits(compiles, pad22646.length >= 3 || pad22646[0..3] == "pad") == true); + +// sc.intypeof +typeof(x22646.length < 3 || x22646[0..3] != "pad") typeof22646or1; +static assert(is(typeof(typeof22646or1) == bool)); +typeof(pad22646.length < 3 || pad22646[0..3] != "pad") typeof22646or2; +static assert(is(typeof(typeof22646or2) == bool)); + +typeof(x22646.length >= 3 && x22646[0..3] == "pad") typeof22646and1; +static assert(is(typeof(typeof22646and1) == bool)); +typeof(pad22646.length >= 3 && pad22646[0..3] == "pad") typeof22646and2; +static assert(is(typeof(typeof22646and2) == bool)); + +// No SCOPE flags +alias test22646a = runtime22646Or!(string, "x"); +alias test22646b = runtime22646Or!(string, "foo"); +alias test22646c = runtime22646Or!(string, "pad"); +alias test22646d = runtime22646Or!(string, "pad123"); + +alias test22646e = runtime22646Or!(char[1], "x"); +alias test22646f = runtime22646Or!(char[3], "foo"); +alias test22646g = runtime22646Or!(char[3], "pad"); +alias test22646h = runtime22646Or!(char[6], "pad123"); diff --git a/gcc/testsuite/gdc.test/compilable/issue22854.d b/gcc/testsuite/gdc.test/compilable/issue22854.d new file mode 100644 index 0000000..4d5a518 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/issue22854.d @@ -0,0 +1,20 @@ +// https://issues.dlang.org/show_bug.cgi?id=22854 +void test22854() +{ + static foreach (ch; SomeContainer().range) { } +} + +struct SomeContainer +{ + SomeRange range() { return SomeRange(); } + TypeWithDestructor data; +} + +struct TypeWithDestructor { ~this() { } } + +struct SomeRange +{ + int front() { return 0; } + bool empty() { return true; } + void popFront() { } +} diff --git a/gcc/testsuite/gdc.test/compilable/issue22975.d b/gcc/testsuite/gdc.test/compilable/issue22975.d new file mode 100644 index 0000000..02b59aa --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/issue22975.d @@ -0,0 +1,12 @@ +// https://issues.dlang.org/show_bug.cgi?id=22975 +void test22975a(int) {}; + +alias test22975b = test22975a; + +void test22975b(bool) {} + +alias test22975c = test22975b; + +alias test22975a = test22975c; + +void test22975c(float) {} diff --git a/gcc/testsuite/gdc.test/compilable/issue23391.d b/gcc/testsuite/gdc.test/compilable/issue23391.d new file mode 100644 index 0000000..d33242d --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/issue23391.d @@ -0,0 +1,31 @@ +struct MyTuple { + string s; +} + +inout(string) myfront(inout(string)[] a) +{ + return a[0]; +} + +MyTuple[] myarray(MyZip r) +{ + MyTuple[] result; + foreach (e; r) + result ~= e; + return result; +} + +struct MyZip +{ + bool empty = false; + MyTuple front() + { + return MyTuple([""].myfront); + } + void popFront() + { + empty = true; + } +} + +static foreach(t; MyZip().myarray) {} diff --git a/gcc/testsuite/gdc.test/compilable/issue23567.d b/gcc/testsuite/gdc.test/compilable/issue23567.d new file mode 100644 index 0000000..9c0406b --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/issue23567.d @@ -0,0 +1,9 @@ +// https://issues.dlang.org/show_bug.cgi?id=23567 +extern(C++) abstract class CCvar +{ +public: + pragma(printf) void func1(const(char)* pFormat, ...); + pragma(printf) void func2(const(char)* pFormat, ...); +} + +static assert(__traits(getVirtualIndex, CCvar.func2) == 1); diff --git a/gcc/testsuite/gdc.test/compilable/noreturn1.d b/gcc/testsuite/gdc.test/compilable/noreturn1.d index e648a56..daf194d 100644 --- a/gcc/testsuite/gdc.test/compilable/noreturn1.d +++ b/gcc/testsuite/gdc.test/compilable/noreturn1.d @@ -150,3 +150,14 @@ void noreturnImplicit() auto y = (throw new Exception("wow")) + value; } } + +// https://issues.dlang.org/show_bug.cgi?id=23549 +int foo(int g = assert(0)) { + return g; +} + +// https://issues.dlang.org/show_bug.cgi?id=22587 +int front(int param) +{ + return param ? 1 : assert(0); +} diff --git a/gcc/testsuite/gdc.test/compilable/noreturn3.d b/gcc/testsuite/gdc.test/compilable/noreturn3.d index 737125d..69689d2 100644 --- a/gcc/testsuite/gdc.test/compilable/noreturn3.d +++ b/gcc/testsuite/gdc.test/compilable/noreturn3.d @@ -245,13 +245,3 @@ struct S22858 static assert (S22858.arr.offsetof % size_t.sizeof == 0); static assert (S22858.arr2.offsetof == S22858.c.offsetof + 1); static assert (S22858.arr2.offsetof == S22858.c2.offsetof); - -// https://issues.dlang.org/show_bug.cgi?id=23331 - -auto fun() { return double(new noreturn[](0)[0]); } -auto gun() { return double(assert(0)); } -auto hun() { return int(assert(0)); } - -// https://issues.dlang.org/show_bug.cgi?id=23379 - -void casting_noreturn() { auto b = cast(double)(assert(0)); } diff --git a/gcc/testsuite/gdc.test/compilable/test18646.d b/gcc/testsuite/gdc.test/compilable/test18646.d new file mode 100644 index 0000000..a9d62a1 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test18646.d @@ -0,0 +1,14 @@ +// https://issues.dlang.org/show_bug.cgi?id=18646 +class SuperClass {} + +class TemplatedClass(T : SuperClass) {} + +class A18646 : SuperClass { + alias T = TemplatedClass!B18646; +} + +class B18646 : SuperClass { + alias T = TemplatedClass!C18646; +} + +class C18646 : SuperClass {} diff --git a/gcc/testsuite/gdc.test/compilable/test19585.d b/gcc/testsuite/gdc.test/compilable/test19585.d new file mode 100644 index 0000000..a84a7ee --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test19585.d @@ -0,0 +1,10 @@ +// https://issues.dlang.org/show_bug.cgi?id=19585 +struct S19585 +{ + M2 stdin; +} + +mixin template Handle(T, T invalid_value = T.init) {} + +struct M1 { mixin Handle!(size_t); } +struct M2 { mixin Handle!(M1); } diff --git a/gcc/testsuite/gdc.test/compilable/test22638.d b/gcc/testsuite/gdc.test/compilable/test22638.d new file mode 100644 index 0000000..d7b5fdf --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22638.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=22638 + +struct S +{ + this(ref const(S)); + ~this(); +} + +extern(C++) void set(const S s); + +void disp() +{ + S p; + return set(p); +} diff --git a/gcc/testsuite/gdc.test/compilable/test22813.d b/gcc/testsuite/gdc.test/compilable/test22813.d new file mode 100644 index 0000000..7cdd534 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22813.d @@ -0,0 +1,9 @@ +// https://issues.dlang.org/show_bug.cgi?id=22813 +struct Template(int i) { } +uint test22813() +{ + Template!(1) x; + return 0; +} +immutable constant = test22813(); +alias X = Template!constant; diff --git a/gcc/testsuite/gdc.test/compilable/test23481.d b/gcc/testsuite/gdc.test/compilable/test23481.d new file mode 100644 index 0000000..7c03e82 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23481.d @@ -0,0 +1,28 @@ +// https://issues.dlang.org/show_bug.cgi?id=23481 + +struct flagenum(I = ubyte) +{ + I i = 1; + alias i this; + + auto opBinary(string s)(int j) { + return typeof(this)(cast(I)(i*2)); + } + auto opEquals(I a) { + return false; + } +} + +enum alphakey +{ + a = flagenum!int(), b, c, d, e, f, g, h, i, j, k, l, + m, n, o, p, q, r, s, t, u, v, w, x, y, z +} + +flagenum!int alpha; + +void main() +{ + alpha &= alphakey.a; + alpha = alpha & alphakey.a; // also crashed in another way +} diff --git a/gcc/testsuite/gdc.test/compilable/test23490.d b/gcc/testsuite/gdc.test/compilable/test23490.d new file mode 100644 index 0000000..0d61a09 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23490.d @@ -0,0 +1,3 @@ +// https://issues.dlang.org/show_bug.cgi?id=23490 +// EXTRA_FILES: imports/test23490frop.d imports/test23490pop.d imports/test23490zoo.d +import imports.test23490pop; diff --git a/gcc/testsuite/gdc.test/compilable/test23497.d b/gcc/testsuite/gdc.test/compilable/test23497.d new file mode 100644 index 0000000..7a13c04 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23497.d @@ -0,0 +1,19 @@ +// https://issues.dlang.org/show_bug.cgi?id=23497 + +class A {} + +A getA(T t) { + return t.a; +} + +struct T { + A _a; + + void k() {} + + auto a() in { + k(); + } do { + return _a; + } +} diff --git a/gcc/testsuite/gdc.test/compilable/test23499.d b/gcc/testsuite/gdc.test/compilable/test23499.d new file mode 100644 index 0000000..12e3f25 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23499.d @@ -0,0 +1,6 @@ +// REQUIRED_ARGS: -inline +// EXTRA_SOURCES: extra-files/build23499.d +// EXTRA_FILES: imports/file23499.d +// https://issues.dlang.org/show_bug.cgi?id=23499 + +import imports.file23499; diff --git a/gcc/testsuite/gdc.test/compilable/test23529.d b/gcc/testsuite/gdc.test/compilable/test23529.d new file mode 100644 index 0000000..712c284 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23529.d @@ -0,0 +1,6 @@ +static assert(!__traits(compiles, () +{ + char[24] x; + int myNumber = 4; + return cast(char[4]) (x[myNumber .. myNumber + 4]); +} ())); diff --git a/gcc/testsuite/gdc.test/compilable/test23532.d b/gcc/testsuite/gdc.test/compilable/test23532.d new file mode 100644 index 0000000..db6bbe7 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23532.d @@ -0,0 +1,67 @@ +// https://issues.dlang.org/show_bug.cgi?id=23532 +// DISABLED: win32 win64 +struct _Complex(T) +{ + T re; + T im; + static @property epsilon()() { return _Complex(T.epsilon, T.epsilon); } + static @property infinity()() { return _Complex(T.infinity, T.infinity); } + static @property max()() { return _Complex(T.max, T.max); } + static @property min_normal()() { return _Complex(T.min_normal, T.min_normal); } + static @property nan()() { return _Complex(T.nan, T.nan); } + static @property dig()() { return T.dig; } + static @property mant_dig()() { return T.mant_dig; } + static @property max_10_exp()() { return T.max_10_exp; } + static @property max_exp()() { return T.max_exp; } + static @property min_10_exp()() { return T.min_10_exp; } + static @property min_exp()() { return T.min_exp; } +} + +enum __c_complex_float : _Complex!float; +enum __c_complex_double : _Complex!double; +enum __c_complex_real : _Complex!real; + +static assert(__c_complex_float.epsilon is _Complex!float.epsilon); +static assert(__c_complex_float.infinity is _Complex!float.infinity); +static assert(__c_complex_float.init is _Complex!float.init); +static assert(__c_complex_float.max is _Complex!float.max); +static assert(__c_complex_float.min_normal is _Complex!float.min_normal); +static assert(__c_complex_float.nan is _Complex!float.nan); +static assert(__c_complex_float.sizeof == _Complex!float.sizeof); +static assert(__c_complex_float.alignof == _Complex!float.alignof); +static assert(__c_complex_float.dig == _Complex!float.dig); +static assert(__c_complex_float.mant_dig == _Complex!float.mant_dig); +static assert(__c_complex_float.max_10_exp == _Complex!float.max_10_exp); +static assert(__c_complex_float.max_exp == _Complex!float.max_exp); +static assert(__c_complex_float.min_10_exp == _Complex!float.min_10_exp); +static assert(__c_complex_float.min_exp == _Complex!float.min_exp); + +static assert(__c_complex_double.epsilon is _Complex!double.epsilon); +static assert(__c_complex_double.infinity is _Complex!double.infinity); +static assert(__c_complex_double.init is _Complex!double.init); +static assert(__c_complex_double.max is _Complex!double.max); +static assert(__c_complex_double.min_normal is _Complex!double.min_normal); +static assert(__c_complex_double.nan is _Complex!double.nan); +static assert(__c_complex_double.sizeof == _Complex!double.sizeof); +static assert(__c_complex_double.alignof == _Complex!double.alignof); +static assert(__c_complex_double.dig == _Complex!double.dig); +static assert(__c_complex_double.mant_dig == _Complex!double.mant_dig); +static assert(__c_complex_double.max_10_exp == _Complex!double.max_10_exp); +static assert(__c_complex_double.max_exp == _Complex!double.max_exp); +static assert(__c_complex_double.min_10_exp == _Complex!double.min_10_exp); +static assert(__c_complex_double.min_exp == _Complex!double.min_exp); + +static assert(__c_complex_real.epsilon is _Complex!real.epsilon); +static assert(__c_complex_real.infinity is _Complex!real.infinity); +static assert(__c_complex_real.init is _Complex!real.init); +static assert(__c_complex_real.max is _Complex!real.max); +static assert(__c_complex_real.min_normal is _Complex!real.min_normal); +static assert(__c_complex_real.nan is _Complex!real.nan); +static assert(__c_complex_real.sizeof == _Complex!real.sizeof); +static assert(__c_complex_real.alignof == _Complex!real.alignof); +static assert(__c_complex_real.dig == _Complex!real.dig); +static assert(__c_complex_real.mant_dig == _Complex!real.mant_dig); +static assert(__c_complex_real.max_10_exp == _Complex!real.max_10_exp); +static assert(__c_complex_real.max_exp == _Complex!real.max_exp); +static assert(__c_complex_real.min_10_exp == _Complex!real.min_10_exp); +static assert(__c_complex_real.min_exp == _Complex!real.min_exp); diff --git a/gcc/testsuite/gdc.test/compilable/test23533.d b/gcc/testsuite/gdc.test/compilable/test23533.d new file mode 100644 index 0000000..6cf116e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23533.d @@ -0,0 +1,10 @@ +// https://issues.dlang.org/show_bug.cgi?id=23533 +// REQUIRED_ARGS: -preview=nosharedaccess + +enum E { a, b } + +void main() +{ + E x = E.b; + E y = E.max; +} diff --git a/gcc/testsuite/gdc.test/compilable/test23586.d b/gcc/testsuite/gdc.test/compilable/test23586.d new file mode 100644 index 0000000..ee7ef3c --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23586.d @@ -0,0 +1,34 @@ +// https://issues.dlang.org/show_bug.cgi?id=23586 + +int test23686a(int x) +{ + switch(x) + { + case 0: + goto Bar; + + Bar: + default: + auto y = 6; + return y; + } +} + +int test23686b(int x) +{ + switch(x) + { + case 0: + Bar: + case 1: + case 2: + auto y = 7; + return y; + + default: + goto Bar; + } +} + +static assert(test23686a(0) == 6); +static assert(test23686b(3) == 7); diff --git a/gcc/testsuite/gdc.test/compilable/test23587.d b/gcc/testsuite/gdc.test/compilable/test23587.d new file mode 100644 index 0000000..6698f9c --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23587.d @@ -0,0 +1,18 @@ +// https://issues.dlang.org/show_bug.cgi?id=23587 +// REQUIRED_ARGS: -w +noreturn stuff() +{ + assert(false); +} + +void doStuff(alias fun)() +{ + cast(void) fun(); + string s = "never executed"; + static assert(is(typeof(cast(void) fun()) == void)); +} + +void main() +{ + doStuff!stuff(); +} diff --git a/gcc/testsuite/gdc.test/compilable/test23589.d b/gcc/testsuite/gdc.test/compilable/test23589.d new file mode 100644 index 0000000..beff31f --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23589.d @@ -0,0 +1,30 @@ +// https://issues.dlang.org/show_bug.cgi?id=23589 +struct TemplStr(string Description_) {} + +template A() { + bool member; + alias THIS = typeof(this); + static THIS staticInstance; + static asSize() + { + return staticInstance.member; + } +} + +template B() { + enum cols = columns(); + + enum cols_two = cols; + TemplStr!(cols_two) tstr; +} + +struct S +{ + mixin A; + mixin B; + + static string columns() { + auto dummy = &asSize; + return "as"; + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail109.d b/gcc/testsuite/gdc.test/fail_compilation/fail109.d index 7caae59..87297db 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail109.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail109.d @@ -90,3 +90,19 @@ enum RegValueType2b : DWORD DWORD = REG_DWORD, Unknown = DWORD.min, } + +/* +TEST_OUTPUT: +--- +fail_compilation/fail109.d(107): Error: enum member `fail109.d` initialization with `__anonymous.c+1` causes overflow for type `Q` +--- +*/ + +struct Q { + enum max = Q(); +} + +enum { + c = Q(), + d +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20618.d b/gcc/testsuite/gdc.test/fail_compilation/fail20618.d deleted file mode 100644 index ac6b33a..0000000 --- a/gcc/testsuite/gdc.test/fail_compilation/fail20618.d +++ /dev/null @@ -1,16 +0,0 @@ -/* -TEST_OUTPUT: ---- -fail_compilation/fail20618.d(13): Error: in slice `a[1 .. 12]`, upper bound is greater than array length `10` -fail_compilation/fail20618.d(14): Error: in slice `a[4 .. 3]`, lower bound is greater than upper bound -fail_compilation/fail20618.d(15): Error: in slice `a[0 .. 11]`, upper bound is greater than array length `10` ---- -*/ - -void main() -{ - int[10] a; - auto b = a[1..12]; - auto c = a[4..3]; - auto d = a[0..$ + 1]; -} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23151.d b/gcc/testsuite/gdc.test/fail_compilation/fail23151.d new file mode 100644 index 0000000..e24dcc2 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23151.d @@ -0,0 +1,41 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/fail23151.d(30): Error: class `fail23151.makeDerivedObj.Derived` is nested within `makeDerivedObj`, but super class `Base` is nested within `makeBaseObj` +--- +*/ +interface I +{ + void intfunc(int x); +} + +auto makeBaseObj() +{ + int realPrivateX; + class Base : I + { + private int modulePrivateX; + int publicX; + override void intfunc(int x) + { + realPrivateX++; // expected OK + } + } + return new Base; +} + +auto makeDerivedObj() +{ + int realPrivateY; + class Derived : typeof(makeBaseObj()) + { + private int modulePrivateY; + int publicY; + override void intfunc(int x) + { + realPrivateX++; // expected NG + modulePrivateX++; + } + } + return new Derived; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23574.d b/gcc/testsuite/gdc.test/fail_compilation/fail23574.d new file mode 100644 index 0000000..c314d92 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23574.d @@ -0,0 +1,41 @@ +// https://issues.dlang.org/show_bug.cgi?id=23574 +/* +TEST_OUTPUT: +--- +fail_compilation/fail23574.d(26): Error: function `object._xopEquals` has no `return` statement, but is expected to return a value of type `bool` +Error: undefined identifier `size_t` in module `object` +fail_compilation/fail23574.d(34): Error: template instance `object.S17915!(MyClass)` error instantiating +fail_compilation/fail23574.d(30): Error: function `object.SDL_GetKeyName` has no `return` statement, but is expected to return a value of type `const(char)` +--- +*/ +module object; + +class Object +{ +} + +bool opEquals(LHS, RHS)(LHS lhs, RHS) +{ + opEquals(cast()lhs); +} + +class TypeInfo +{ +} + +bool _xopEquals() +{ +} + +const(char)SDL_GetKeyName() +{ + class MyClass + { + S17915!MyClass m_member; + } +} + +struct S17915(T) +{ + T owner; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23591.d b/gcc/testsuite/gdc.test/fail_compilation/fail23591.d new file mode 100644 index 0000000..ddfc558 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23591.d @@ -0,0 +1,16 @@ +// https://issues.dlang.org/show_bug.cgi?id=23591 +/* +TEST_OUTPUT: +--- +fail_compilation/fail23591.d(13): Error: cannot implicitly convert expression `square(i) , null` of type `string` to `int` +fail_compilation/fail23591.d(14): Error: cannot implicitly convert expression `assert(0) , null` of type `real function(char)` to `int` +--- +*/ +noreturn square(int x); + +int example(int i) +{ + int x = cast(string)square(i); + int y = cast(real function(char))assert(0); + return x + y; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/failattr.d b/gcc/testsuite/gdc.test/fail_compilation/failattr.d index c7f0f31..012305a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/failattr.d +++ b/gcc/testsuite/gdc.test/fail_compilation/failattr.d @@ -3,14 +3,17 @@ /* TEST_OUTPUT: --- -fail_compilation/failattr.d(16): Error: variable `failattr.C2901.v1` cannot be `synchronized` -fail_compilation/failattr.d(17): Error: variable `failattr.C2901.v2` cannot be `override` -fail_compilation/failattr.d(18): Error: variable `failattr.C2901.v3` cannot be `abstract` -fail_compilation/failattr.d(19): Error: variable `failattr.C2901.v4` cannot be `final`, perhaps you meant `const`? -fail_compilation/failattr.d(31): Error: variable `failattr.C2901.v13` cannot be `final abstract synchronized override` -fail_compilation/failattr.d(33): Error: variable `failattr.C2901.v14` cannot be `final`, perhaps you meant `const`? +fail_compilation/failattr.d(103): Error: variable `failattr.C2901.v1` cannot be `synchronized` +fail_compilation/failattr.d(104): Error: variable `failattr.C2901.v2` cannot be `override` +fail_compilation/failattr.d(105): Error: variable `failattr.C2901.v3` cannot be `abstract` +fail_compilation/failattr.d(106): Error: variable `failattr.C2901.v4` cannot be `final`, perhaps you meant `const`? +fail_compilation/failattr.d(118): Error: variable `failattr.C2901.v13` cannot be `final abstract synchronized override` +fail_compilation/failattr.d(120): Error: variable `failattr.C2901.v14` cannot be `final`, perhaps you meant `const`? +fail_compilation/failattr.d(123): Error: undefined identifier `ERROR` --- */ +#line 100 + class C2901 { synchronized int v1; // error @@ -32,3 +35,5 @@ class C2901 static final int v14; // error, even if static is applied at the same time } + +enum B23122 { @ERROR e } diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice23564.d b/gcc/testsuite/gdc.test/fail_compilation/ice23564.d new file mode 100644 index 0000000..75b5d4e --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/ice23564.d @@ -0,0 +1,25 @@ +/* TEST_OUTPUT: +--- +fail_compilation/ice23564.d(10): Error: cannot construct nested class `FreeList` because no implicit `this` reference to outer class `RBTree` is available +--- +*/ +class BlockHeader +{ + this() + { + new FreeList; + } +} + +class RBTree +{ + class FreeList + { + } + + void _each_reverse() + { + } +} + +alias FreeList = RBTree.FreeList; diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice23569.d b/gcc/testsuite/gdc.test/fail_compilation/ice23569.d new file mode 100644 index 0000000..277814f --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/ice23569.d @@ -0,0 +1,19 @@ +// https://issues.dlang.org/show_bug.cgi?id=23569 +/* +TEST_OUTPUT: +--- +fail_compilation/ice23569.d(18): Error: cannot compare classes for equality because `object.Object` was not declared +--- +*/ +module object; + +@safe unittest1() +{ + class F + { + this(int ) + { + } + } + auto ice23569 = new F(0) == new F(0); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/staticassertargs.d b/gcc/testsuite/gdc.test/fail_compilation/staticassertargs.d new file mode 100644 index 0000000..9591fd8 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/staticassertargs.d @@ -0,0 +1,9 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/staticassertargs.d(9): Error: static assert: abcxe3!! +--- +*/ + +enum e = "!!"; +static assert(false, "abc", ['x', 'e'], 3, e); diff --git a/gcc/testsuite/gdc.test/fail_compilation/staticassertargsfail.d b/gcc/testsuite/gdc.test/fail_compilation/staticassertargsfail.d new file mode 100644 index 0000000..911d588 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/staticassertargsfail.d @@ -0,0 +1,10 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/staticassertargsfail.d(10): Error: incompatible types for `('x') : (new Object)`: `char` and `object.Object` +fail_compilation/staticassertargsfail.d(10): while evaluating `static assert` argument `['x', new Object] ~ ""` +--- +*/ + + +static assert(0, "abc", ['x', new Object] ~ ""); diff --git a/gcc/testsuite/gdc.test/fail_compilation/test12228.d b/gcc/testsuite/gdc.test/fail_compilation/test12228.d index a62eb86..d96b2a5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test12228.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test12228.d @@ -1,10 +1,9 @@ /* TEST_OUTPUT: --- -fail_compilation/test12228.d(13): Error: undefined identifier `this`, did you mean `typeof(this)`? -fail_compilation/test12228.d(18): Error: no property `x` for type `object.Object` +fail_compilation/test12228.d(12): Error: undefined identifier `this`, did you mean `typeof(this)`? +fail_compilation/test12228.d(18): Error: undefined identifier `super`, did you mean `typeof(super)`? fail_compilation/test12228.d(19): Error: undefined identifier `super`, did you mean `typeof(super)`? -fail_compilation/test12228.d(20): Error: undefined identifier `super`, did you mean `typeof(super)`? --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21008.d b/gcc/testsuite/gdc.test/fail_compilation/test21008.d index 641c802..7d5bb37 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test21008.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test21008.d @@ -12,7 +12,6 @@ fail_compilation/test21008.d(117): Error: `Monitor` has no effect fail_compilation/test21008.d(117): Error: function `object.Object.factory(string classname)` is not callable using argument types `()` fail_compilation/test21008.d(117): too few arguments, expected 1, got 0 fail_compilation/test21008.d(105): called from here: `handleMiddlewareAnnotation()` -fail_compilation/test21008.d(108): Error: class `test21008.C` no size because of forward reference --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23552.d b/gcc/testsuite/gdc.test/fail_compilation/test23552.d new file mode 100644 index 0000000..bf9e3a6 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23552.d @@ -0,0 +1,24 @@ +// https://issues.dlang.org/show_bug.cgi?id=23552 + +/* +TEST_OUTPUT: +--- +fail_compilation/test23552.d(17): Error: cannot implicitly override base class method `test23552.Base.foo` with `test23552.Derived.foo`; add `override` attribute +--- +*/ + +abstract class Base +{ + void foo(); +} + +class Derived : Base +{ + void foo() { } + int data() { return 0; } +} + +class DerivedX : Derived +{ + override int data() { return 1; } +} diff --git a/gcc/testsuite/gdc.test/runnable/issue22854.d b/gcc/testsuite/gdc.test/runnable/issue22854.d new file mode 100644 index 0000000..c4cae17 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/issue22854.d @@ -0,0 +1,27 @@ +// https://issues.dlang.org/show_bug.cgi?id=22854 +void main() +{ + uint loops = 0; + static foreach (i; 0 .. 50) + { + static foreach (ch; SomeContainer().range) + loops++; + } + assert(loops == 50 * 50); +} + +struct SomeContainer +{ + SomeRange range() { return SomeRange(); } + TypeWithDestructor data; +} + +struct TypeWithDestructor { ~this() { } } + +struct SomeRange +{ + int count = 50; + int front() { return count; } + bool empty() { return count <= 0; } + void popFront() { count--; } +} diff --git a/gcc/testsuite/gdc.test/runnable/test16098.d b/gcc/testsuite/gdc.test/runnable/test16098.d new file mode 100644 index 0000000..16b34f1 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test16098.d @@ -0,0 +1,14 @@ + +// https://issues.dlang.org/show_bug.cgi?id=16098 + +void main() { + byte a; + align(128) byte b; + assert((cast(size_t) &b) % 128 == 0); + + byte foo() { return b; } + dg = &foo; + assert(dg() == false); +} + +__gshared byte delegate() dg; diff --git a/gcc/testsuite/gdc.test/runnable/test20811.d b/gcc/testsuite/gdc.test/runnable/test20811.d new file mode 100644 index 0000000..a300d2a --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test20811.d @@ -0,0 +1,34 @@ +// https://issues.dlang.org/show_bug.cgi?id=20811 + +// OK: Mutable array literals are copied before CTFE takes ownership. +string issue20811a() +{ + char[1] counter = ['0']; + counter[$-1]++; + return counter.dup; +} + +static assert(issue20811a() == "1"); +static assert(issue20811a() == "1"); +static assert(issue20811a() == "1"); +static assert(issue20811a() == "1"); + +// Issue 20811: String literals were assumed to be read-only, so weren't copied. +string issue20811b() +{ + char[1] counter = "0"; + counter[$-1]++; + return counter.dup; +} + +static assert(issue20811b() == "1"); +static assert(issue20811b() == "1"); +static assert(issue20811b() == "1"); +static assert(issue20811b() == "1"); + +void main() +{ + // Ensure CTFE did not overwrite the original AST. + assert(issue20811a() == "1"); + assert(issue20811b() == "1"); +} diff --git a/gcc/testsuite/gdc.test/runnable/test23307.d b/gcc/testsuite/gdc.test/runnable/test23307.d new file mode 100644 index 0000000..a61b0d7 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test23307.d @@ -0,0 +1,93 @@ +// REQUIRED_ARGS: -inline -O + +// https://issues.dlang.org/show_bug.cgi?id=23307 +import core.simd; + +static if(__traits(compiles, int4)) +{ + +alias __m128i = int4; + +uint bitwiseRotateRight_uint(const uint value, const uint count) +{ + assert(count < 8 * uint.sizeof); + return cast(uint) ((value >> count) | (value << (uint.sizeof * 8 - count))); +} + + +__m128i _mm_sha256rnds2_epu32(__m128i a, __m128i b, __m128i k) +{ + + static uint Ch(uint x, uint y, uint z) + { + return z ^ (x & (y ^ z)); + } + + static uint Maj(uint x, uint y, uint z) + { + return (x & y) | (z & (x ^ y)); + } + + static uint sum0(uint x) + { + return bitwiseRotateRight_uint(x, 2) ^ bitwiseRotateRight_uint(x, 13) ^ bitwiseRotateRight_uint(x, 22); + } + + static uint sum1(uint x) + { + return bitwiseRotateRight_uint(x, 6) ^ bitwiseRotateRight_uint(x, 11) ^ bitwiseRotateRight_uint(x, 25); + } + + int4 dst; + int4 a4 = cast(int4) a; + int4 b4 = cast(int4) b; + int4 k4 = cast(int4) k; + + const A0 = b4.array[3]; + const B0 = b4.array[2]; + const C0 = a4.array[3]; + const D0 = a4.array[2]; + const E0 = b4.array[1]; + const F0 = b4.array[0]; + const G0 = a4.array[1]; + const H0 = a4.array[0]; + const W_K0 = k4.array[0]; + const W_K1 = k4.array[1]; + const A1 = Ch(E0, F0, G0) + sum1(E0) + W_K0 + H0 + Maj(A0, B0, C0) + sum0(A0); + const B1 = A0; + const C1 = B0; + const D1 = C0; + const E1 = Ch(E0, F0, G0) + sum1(E0) + W_K0 + H0 + D0; + const F1 = E0; + const G1 = F0; + const H1 = G0; + const A2 = Ch(E1, F1, G1) + sum1(E1) + W_K1 + H1 + Maj(A1, B1, C1) + sum0(A1); + const B2 = A1; + const C2 = B1; + const D2 = C1; + const E2 = Ch(E1, F1, G1) + sum1(E1) + W_K1 + H1 + D1; + const F2 = E1; + const G2 = F1; + const H2 = G1; + + dst.ptr[3] = A2; + dst.ptr[2] = B2; + dst.ptr[1] = E2; + dst.ptr[0] = F2; + + return cast(__m128i) dst; +} + +void main(string[] args) +{ + __m128i a = [15, 20, 130, 12345]; + __m128i b = [15, 20, 130, 12345]; + __m128i k = [15, 20, 130, 12345]; + __m128i result = _mm_sha256rnds2_epu32(a, b, k); + assert(result.array == [1384123044, -2050674062, 327754346, 956342016]); +} +} +else +{ +int main() { return 0; } +} diff --git a/gcc/testsuite/gdc.test/runnable/test34.d b/gcc/testsuite/gdc.test/runnable/test34.d index df46137..11543f1 100644 --- a/gcc/testsuite/gdc.test/runnable/test34.d +++ b/gcc/testsuite/gdc.test/runnable/test34.d @@ -1,3 +1,5 @@ +// REQUIRED_ARGS: -d + module test34; import core.exception; diff --git a/gcc/testsuite/gdc.test/runnable/xtest46.d b/gcc/testsuite/gdc.test/runnable/xtest46.d index 8ae08ad..a0907f4 100644 --- a/gcc/testsuite/gdc.test/runnable/xtest46.d +++ b/gcc/testsuite/gdc.test/runnable/xtest46.d @@ -1,4 +1,4 @@ -// REQUIRED_ARGS: -preview=rvaluerefparam +// REQUIRED_ARGS: -d -preview=rvaluerefparam // /* TEST_OUTPUT: --- diff --git a/gcc/testsuite/gdc.test/runnable/xtest46_gc.d b/gcc/testsuite/gdc.test/runnable/xtest46_gc.d index 348c05b..b0288a2 100644 --- a/gcc/testsuite/gdc.test/runnable/xtest46_gc.d +++ b/gcc/testsuite/gdc.test/runnable/xtest46_gc.d @@ -1,5 +1,5 @@ /* -REQUIRED_ARGS: -lowmem -Jrunnable -preview=rvaluerefparam +REQUIRED_ARGS: -d -lowmem -Jrunnable -preview=rvaluerefparam EXTRA_FILES: xtest46.d TEST_OUTPUT: --- diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 5ee6f62..ac3dd12 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -c8ae4adb2eda515b09b326948e3a4aa9f489af45 +09faa4eacd4fb147107e94eeebf56b3a73fdcc05 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/core/demangle.d b/libphobos/libdruntime/core/demangle.d index 869ade6..fe27331 100644 --- a/libphobos/libdruntime/core/demangle.d +++ b/libphobos/libdruntime/core/demangle.d @@ -2134,7 +2134,7 @@ pure @safe: */ char[] demangle(return scope const(char)[] buf, return scope char[] dst = null, CXX_DEMANGLER __cxa_demangle = null) nothrow pure @safe { - if (buf.length > 2 && buf[0..2] == "_Z") + if (__cxa_demangle && buf.length > 2 && buf[0..2] == "_Z") return demangleCXX(buf, __cxa_demangle, dst); auto d = Demangle!()(buf, dst); // fast path (avoiding throwing & catching exception) for obvious @@ -2734,6 +2734,9 @@ unittest s ~= "FiZi"; expected ~= "F"; assert(s.demangle == expected); + + // https://issues.dlang.org/show_bug.cgi?id=23562 + assert(demangle("_Zv") == "_Zv"); } // https://issues.dlang.org/show_bug.cgi?id=22235 @@ -2929,6 +2932,7 @@ CXX_DEMANGLER getCXXDemangler() nothrow @trusted version (FreeBSD) import core.sys.freebsd.dlfcn : RTLD_DEFAULT; version (linux) import core.sys.linux.dlfcn : RTLD_DEFAULT; version (NetBSD) import core.sys.netbsd.dlfcn : RTLD_DEFAULT; + version (OpenBSD) import core.sys.openbsd.dlfcn : RTLD_DEFAULT; version (OSX) import core.sys.darwin.dlfcn : RTLD_DEFAULT; version (Solaris) import core.sys.solaris.dlfcn : RTLD_DEFAULT; diff --git a/libphobos/libdruntime/core/exception.d b/libphobos/libdruntime/core/exception.d index 62179fe..d2016b1 100644 --- a/libphobos/libdruntime/core/exception.d +++ b/libphobos/libdruntime/core/exception.d @@ -278,7 +278,6 @@ class FinalizeError : Error this( TypeInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super( "Finalization error", file, line, next ); - super.info = SuppressTraceInfo.instance; info = ci; } @@ -393,7 +392,6 @@ class InvalidMemoryOperationError : Error this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc { super( "Invalid memory operation", file, line, next ); - this.info = SuppressTraceInfo.instance; } override string toString() const @trusted diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d index e29e426..6d19247 100644 --- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d +++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d @@ -110,13 +110,23 @@ alias GC gc_t; /* ============================ GC =============================== */ // register GC in C constructor (_STI_) -extern(C) pragma(crt_constructor) void _d_register_conservative_gc() +private pragma(crt_constructor) void gc_conservative_ctor() +{ + _d_register_conservative_gc(); +} + +extern(C) void _d_register_conservative_gc() { import core.gc.registry; registerGCFactory("conservative", &initialize); } -extern(C) pragma(crt_constructor) void _d_register_precise_gc() +private pragma(crt_constructor) void gc_precise_ctor() +{ + _d_register_precise_gc(); +} + +extern(C) void _d_register_precise_gc() { import core.gc.registry; registerGCFactory("precise", &initialize_precise); diff --git a/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d b/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d index a65c636..570781e 100644 --- a/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d +++ b/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d @@ -29,7 +29,12 @@ static import core.memory; extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */ // register GC in C constructor (_STI_) -extern(C) pragma(crt_constructor) void _d_register_manual_gc() +private pragma(crt_constructor) void gc_manual_ctor() +{ + _d_register_manual_gc(); +} + +extern(C) void _d_register_manual_gc() { import core.gc.registry; registerGCFactory("manual", &initialize); diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d index 799e525..19bb61b 100644 --- a/libphobos/libdruntime/core/runtime.d +++ b/libphobos/libdruntime/core/runtime.d @@ -112,7 +112,7 @@ private alias void delegate( Throwable ) ExceptionHandler; extern (C) void _d_print_throwable(Throwable t); - extern (C) void* thread_stackBottom(); + extern (C) void* thread_stackBottom() nothrow @nogc; } @@ -122,7 +122,7 @@ shared static this() // still possible the app could exit without a stack trace. If // this becomes an issue, the handler could be set in C main // before the module ctors are run. - Runtime.traceHandler = &defaultTraceHandler; + Runtime.traceHandler(&defaultTraceHandler, &defaultTraceDeallocator); } @@ -284,10 +284,18 @@ struct Runtime * If the supplied pointer is null then the trace routine should determine * an appropriate calling context from which to begin the trace. * + * If the deallocator is set, then it is called with the traceinfo when the + * exception is finalized. The deallocator is only set in the exception if + * the default handler is used to generate the trace info. + * * Params: * h = The new trace handler. Set to null to disable exception backtracing. + * d = The new trace deallocator. If non-null, this will be called on + * exception destruction with the trace info, only when the trace + * handler is used to generate TraceInfo. */ - extern(C) pragma(mangle, "rt_setTraceHandler") static @property void traceHandler(TraceHandler h); + extern(C) pragma(mangle, "rt_setTraceHandler") static @property void traceHandler(TraceHandler h, + Throwable.TraceDeallocator d = null); /** * Gets the current trace handler. @@ -298,6 +306,14 @@ struct Runtime extern(C) pragma(mangle, "rt_getTraceHandler") static @property TraceHandler traceHandler(); /** + * Gets the current trace deallocator. + * + * Returns: + * The current trace deallocator or null if none has been set. + */ + extern(C) pragma(mangle, "rt_getTraceDeallocator") static @property Throwable.TraceDeallocator traceDeallocator(); + + /** * Overrides the default collect hander with a user-supplied version. This * routine will be called for each resource object that is finalized in a * non-deterministic manner--typically during a garbage collection cycle. @@ -705,6 +721,10 @@ extern (C) UnitTestResult runModuleUnitTests() * This functions returns a trace handler, allowing to inspect the * current stack trace. * + * IMPORTANT NOTE! the returned trace is potentially not GC allocated, and so + * you must call `defaultTraceDeallocator` when you are finished with the + * `TraceInfo` + * * Params: * ptr = (Windows only) The context to get the stack trace from. * When `null` (the default), start from the current frame. @@ -714,14 +734,24 @@ extern (C) UnitTestResult runModuleUnitTests() * or `null`. If called from a finalizer (destructor), always returns `null` * as trace handlers allocate. */ -Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) +Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) // @nogc { + // NOTE: with traces now being allocated using C malloc, no need to worry + // about GC reentrancy. This code left commented out for reference. + // // avoid recursive GC calls in finalizer, trace handlers should be made @nogc instead - import core.memory : GC; + /*import core.memory : GC; if (GC.inFinalizer) - return null; + return null;*/ - static if (__traits(compiles, new LibBacktrace(0))) + static T allocate(T, Args...)(auto ref Args args) @nogc + { + import core.lifetime : emplace; + import core.stdc.stdlib : malloc; + auto result = cast(T)malloc(__traits(classInstanceSize, T)); + return emplace(result, args); + } + static if (__traits(compiles, allocate!LibBacktrace(0))) { version (Posix) static enum FIRSTFRAME = 4; @@ -729,9 +759,9 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) static enum FIRSTFRAME = 4; else static enum FIRSTFRAME = 0; - return new LibBacktrace(FIRSTFRAME); + return allocate!LibBacktrace(FIRSTFRAME); } - else static if (__traits(compiles, new UnwindBacktrace(0))) + else static if (__traits(compiles, allocate!UnwindBacktrace(0))) { version (Posix) static enum FIRSTFRAME = 5; @@ -739,25 +769,25 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) static enum FIRSTFRAME = 4; else static enum FIRSTFRAME = 0; - return new UnwindBacktrace(FIRSTFRAME); + return allocate!UnwindBacktrace(FIRSTFRAME); } else version (Windows) { import core.sys.windows.stacktrace; - static if (__traits(compiles, new StackTrace(0, null))) + static if (__traits(compiles, allocate!StackTrace(0, null))) { import core.sys.windows.winnt : CONTEXT; version (Win64) enum FIRSTFRAME = 4; else version (Win32) enum FIRSTFRAME = 0; - return new StackTrace(FIRSTFRAME, cast(CONTEXT*)ptr); + return allocate!StackTrace(FIRSTFRAME, cast(CONTEXT*)ptr); } else return null; } - else static if (__traits(compiles, new DefaultTraceInfo())) - return new DefaultTraceInfo(); + else static if (__traits(compiles, allocate!DefaultTraceInfo())) + return allocate!DefaultTraceInfo(); else return null; } @@ -775,9 +805,32 @@ unittest { printf("%.*s\n", cast(int)line.length, line.ptr); } + defaultTraceDeallocator(trace); } } +/*** + * Deallocate a traceinfo generated by deaultTraceHander. + * + * Call this function on a TraceInfo generated via `defaultTraceHandler` when + * you are done with it. If necessary, this cleans up any manually managed + * resources from the `TraceInfo`, and invalidates it. After this, the object + * is no longer valid. + * + * Params: + * info = The `TraceInfo` to deallocate. This should only be a value that + * was returned by `defaultTraceHandler`. + */ +void defaultTraceDeallocator(Throwable.TraceInfo info) nothrow +{ + if (info is null) + return; + auto obj = cast(Object)info; + destroy(obj); + import core.stdc.stdlib : free; + free(cast(void *)obj); +} + version (DRuntime_Use_Libunwind) { import core.internal.backtrace.handler; @@ -791,7 +844,7 @@ else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf import core.stdc.stdlib : free; import core.stdc.string : strlen, memchr, memmove; - this() + this() @nogc { // it may not be 1 but it is good enough to get // in CALL instruction address range for backtrace @@ -805,13 +858,13 @@ else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf elem -= CALL_INSTRUCTION_SIZE; else // backtrace() failed, do it ourselves { - static void** getBasePtr() + static void** getBasePtr() @nogc { version (D_InlineAsm_X86) - asm { naked; mov EAX, EBP; ret; } + asm @nogc { naked; mov EAX, EBP; ret; } else version (D_InlineAsm_X86_64) - asm { naked; mov RAX, RBP; ret; } + asm @nogc { naked; mov RAX, RBP; ret; } else return null; } diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d index c576e99..16bc475 100644 --- a/libphobos/libdruntime/core/stdc/config.d +++ b/libphobos/libdruntime/core/stdc/config.d @@ -286,6 +286,22 @@ private struct _Complex(T) { T re; T im; + + // Helper properties. + pragma(inline, true) + { + static @property epsilon()() { return _Complex(T.epsilon, T.epsilon); } + static @property infinity()() { return _Complex(T.infinity, T.infinity); } + static @property max()() { return _Complex(T.max, T.max); } + static @property min_normal()() { return _Complex(T.min_normal, T.min_normal); } + static @property nan()() { return _Complex(T.nan, T.nan); } + static @property dig()() { return T.dig; } + static @property mant_dig()() { return T.mant_dig; } + static @property max_10_exp()() { return T.max_10_exp; } + static @property max_exp()() { return T.max_exp; } + static @property min_10_exp()() { return T.min_10_exp; } + static @property min_exp()() { return T.min_exp; } + } } enum __c_complex_float : _Complex!float; diff --git a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d index dc42a2d..b6e10a8 100644 --- a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d +++ b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d @@ -148,7 +148,7 @@ version (CoreDdoc) * * auto mph = _NSGetMachExecuteHeader(); * int size; - * assert(getsectdata(mph, "__TEXT", "__text", &size)); + * assert(getsectiondata(mph, "__TEXT", "__text", &size)); * assert(size > 0); * } * --- diff --git a/libphobos/libdruntime/core/sys/posix/sys/wait.d b/libphobos/libdruntime/core/sys/posix/sys/wait.d index 145149b..f6b0674 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/wait.d +++ b/libphobos/libdruntime/core/sys/posix/sys/wait.d @@ -386,9 +386,15 @@ else version (NetBSD) else version (OpenBSD) { enum WCONTINUED = 8; - // OpenBSD does not define the following: - //enum WSTOPPED - //enum WNOWAIT + enum WSTOPPED = WUNTRACED; + enum WNOWAIT = 16; + + enum idtype_t + { + P_ALL, + P_PID, + P_PGID + } } else version (DragonFlyBSD) { diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d index de14bce..55fbc56 100644 --- a/libphobos/libdruntime/core/sys/windows/dbghelp.d +++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d @@ -31,7 +31,7 @@ extern(Windows) alias PVOID function(HANDLE hProcess, DWORD64 AddrBase) SymFunctionTableAccess64Func; alias BOOL function(DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, PVOID ContextRecord, ReadProcessMemoryProc64 ReadMemoryRoutine, FunctionTableAccessProc64 FunctoinTableAccess, - GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) StackWalk64Func; + GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) @nogc StackWalk64Func; alias BOOL function(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, IMAGEHLP_LINEA64 *line) SymGetLineFromAddr64Func; alias DWORD64 function(HANDLE hProcess, DWORD64 dwAddr) SymGetModuleBase64Func; alias BOOL function(HANDLE hProcess, DWORD64 dwAddr, IMAGEHLP_MODULEA64 *ModuleInfo) SymGetModuleInfo64Func; @@ -66,7 +66,7 @@ struct DbgHelp SymRegisterCallback64Func SymRegisterCallback64; ImagehlpApiVersionFunc ImagehlpApiVersion; - static DbgHelp* get() + static DbgHelp* get() @nogc { if ( sm_hndl != sm_hndl.init ) return &sm_inst; diff --git a/libphobos/libdruntime/core/sys/windows/stacktrace.d b/libphobos/libdruntime/core/sys/windows/stacktrace.d index 6e5c4cd..8df2972 100644 --- a/libphobos/libdruntime/core/sys/windows/stacktrace.d +++ b/libphobos/libdruntime/core/sys/windows/stacktrace.d @@ -24,10 +24,10 @@ import core.sys.windows.windef; debug(PRINTF) import core.stdc.stdio; -extern(Windows) void RtlCaptureContext(CONTEXT* ContextRecord); +extern(Windows) void RtlCaptureContext(CONTEXT* ContextRecord) @nogc; extern(Windows) DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR pBuffer, DWORD nSize); -extern(Windows) alias USHORT function(ULONG FramesToSkip, ULONG FramesToCapture, PVOID *BackTrace, PULONG BackTraceHash) RtlCaptureStackBackTraceFunc; +extern(Windows) alias USHORT function(ULONG FramesToSkip, ULONG FramesToCapture, PVOID *BackTrace, PULONG BackTraceHash) @nogc RtlCaptureStackBackTraceFunc; private __gshared RtlCaptureStackBackTraceFunc RtlCaptureStackBackTrace; private __gshared immutable bool initialized; @@ -42,7 +42,7 @@ public: * skip = The number of stack frames to skip. * context = The context to receive the stack trace from. Can be null. */ - this(size_t skip, CONTEXT* context) + this(size_t skip, CONTEXT* context) @nogc { if (context is null) { @@ -64,7 +64,7 @@ public: skip += INTERNALFRAMES; } if ( initialized ) - m_trace = trace(skip, context); + m_trace = trace(tracebuf[], skip, context); } int opApply( scope int delegate(ref const(char[])) dg ) const @@ -100,18 +100,27 @@ public: } /** - * Receive a stack trace in the form of an address list. + * Receive a stack trace in the form of an address list. One form accepts + * an allocated buffer, the other form automatically allocates the buffer. + * * Params: * skip = How many stack frames should be skipped. * context = The context that should be used. If null the current context is used. + * buffer = The buffer to use for the trace. This should be at least 63 elements. * Returns: * A list of addresses that can be passed to resolve at a later point in time. */ static ulong[] trace(size_t skip = 0, CONTEXT* context = null) { + return trace(new ulong[63], skip, context); + } + + /// ditto + static ulong[] trace(ulong[] buffer, size_t skip = 0, CONTEXT* context = null) @nogc + { synchronized( typeid(StackTrace) ) { - return traceNoSync(skip, context); + return traceNoSync(buffer, skip, context); } } @@ -131,38 +140,43 @@ public: } private: + ulong[128] tracebuf; ulong[] m_trace; - static ulong[] traceNoSync(size_t skip, CONTEXT* context) + static ulong[] traceNoSync(ulong[] buffer, size_t skip, CONTEXT* context) @nogc { auto dbghelp = DbgHelp.get(); if (dbghelp is null) return []; // dbghelp.dll not available - if (RtlCaptureStackBackTrace !is null && context is null) + if (buffer.length >= 63 && RtlCaptureStackBackTrace !is null && + context is null) { - size_t[63] buffer = void; // On windows xp the sum of "frames to skip" and "frames to capture" can't be greater then 63 - auto backtraceLength = RtlCaptureStackBackTrace(cast(ULONG)skip, cast(ULONG)(buffer.length - skip), cast(void**)buffer.ptr, null); + version (Win64) + { + auto bufptr = cast(void**)buffer.ptr; + } + version (Win32) + { + size_t[63] bufstorage = void; // On windows xp the sum of "frames to skip" and "frames to capture" can't be greater then 63 + auto bufptr = cast(void**)bufstorage.ptr; + } + auto backtraceLength = RtlCaptureStackBackTrace(cast(ULONG)skip, cast(ULONG)(63 - skip), bufptr, null); // If we get a backtrace and it does not have the maximum length use it. // Otherwise rely on tracing through StackWalk64 which is slower but works when no frame pointers are available. - if (backtraceLength > 1 && backtraceLength < buffer.length - skip) + if (backtraceLength > 1 && backtraceLength < 63 - skip) { debug(PRINTF) printf("Using result from RtlCaptureStackBackTrace\n"); - version (Win64) + version (Win32) { - return buffer[0..backtraceLength].dup; - } - else version (Win32) - { - auto result = new ulong[backtraceLength]; - foreach (i, ref e; result) + foreach (i, ref e; buffer[0 .. backtraceLength]) { - e = buffer[i]; + e = bufstorage[i]; } - return result; } + return buffer[0..backtraceLength]; } } @@ -210,21 +224,21 @@ private: else version (X86_64) enum imageType = IMAGE_FILE_MACHINE_AMD64; else static assert(0, "unimplemented"); - ulong[] result; size_t frameNum = 0; + size_t nframes = 0; // do ... while so that we don't skip the first stackframe do { if (frameNum >= skip) { - result ~= stackframe.AddrPC.Offset; + buffer[nframes++] = stackframe.AddrPC.Offset; } frameNum++; } while (dbghelp.StackWalk64(imageType, hProcess, hThread, &stackframe, &ctxt, null, null, null, null)); - return result; + return buffer[0 .. nframes]; } static char[][] resolveNoSync(const(ulong)[] addresses) diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d index 415430c..7316373 100644 --- a/libphobos/libdruntime/core/thread/osthread.d +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -1997,12 +1997,17 @@ extern (C) void thread_suspendAll() nothrow Thread.criticalRegionLock.lock_nothrow(); scope (exit) Thread.criticalRegionLock.unlock_nothrow(); size_t cnt; + bool suspendedSelf; Thread t = ThreadBase.sm_tbeg.toThread; while (t) { auto tn = t.next.toThread; if (suspend(t)) + { + if (t is ThreadBase.getThis()) + suspendedSelf = true; ++cnt; + } t = tn; } @@ -2010,9 +2015,12 @@ extern (C) void thread_suspendAll() nothrow {} else version (Posix) { - // subtract own thread + // Subtract own thread if we called suspend() on ourselves. + // For example, suspendedSelf would be false if the current + // thread ran thread_detachThis(). assert(cnt >= 1); - --cnt; + if (suspendedSelf) + --cnt; // wait for semaphore notifications for (; cnt; --cnt) { diff --git a/libphobos/libdruntime/core/time.d b/libphobos/libdruntime/core/time.d index ea163a0..8d50875 100644 --- a/libphobos/libdruntime/core/time.d +++ b/libphobos/libdruntime/core/time.d @@ -2822,7 +2822,7 @@ struct TickDuration } - @trusted shared static this() + static pragma(crt_constructor) void time_initializer() { version (Windows) { diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index 83351f2..0385b51 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -246,7 +246,7 @@ class Object * } * --- */ - static Object factory(string classname) + deprecated static Object factory(string classname) { auto ci = TypeInfo_Class.find(classname); if (ci) @@ -256,7 +256,7 @@ class Object return null; } - @system unittest + deprecated @system unittest { Object valid_obj = Object.factory("object.Object"); Object invalid_obj = Object.factory("object.__this_class_doesnt_exist__"); @@ -2481,6 +2481,8 @@ class Throwable : Object string toString() const; } + alias TraceDeallocator = void function(TraceInfo) nothrow; + string msg; /// A message describing the error. /** @@ -2502,6 +2504,12 @@ class Throwable : Object TraceInfo info; /** + * If set, this is used to deallocate the TraceInfo on destruction. + */ + TraceDeallocator infoDeallocator; + + + /** * A reference to the _next error in the list. This is used when a new * $(D Throwable) is thrown from inside a $(D catch) block. The originally * caught $(D Exception) will be chained to the new $(D Throwable) via this @@ -2614,6 +2622,13 @@ class Throwable : Object { if (nextInChain && nextInChain._refcount) _d_delThrowable(nextInChain); + // handle owned traceinfo + if (infoDeallocator !is null) + { + infoDeallocator(info); + info = null; // avoid any kind of dangling pointers if we can help + // it. + } } /** diff --git a/libphobos/libdruntime/rt/deh.d b/libphobos/libdruntime/rt/deh.d index 695f2ce..0a44be3 100644 --- a/libphobos/libdruntime/rt/deh.d +++ b/libphobos/libdruntime/rt/deh.d @@ -42,12 +42,14 @@ module rt.deh; extern (C) { Throwable.TraceInfo _d_traceContext(void* ptr = null); + Throwable.TraceDeallocator rt_getTraceDeallocator(); void _d_createTrace(Throwable t, void* context) { if (t !is null && t.info is null && cast(byte*) t !is typeid(t).initializer.ptr) { t.info = _d_traceContext(context); + t.infoDeallocator = rt_getTraceDeallocator(); } } } diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d index 264fdf6..8a10aac 100644 --- a/libphobos/libdruntime/rt/dmain2.d +++ b/libphobos/libdruntime/rt/dmain2.d @@ -182,6 +182,7 @@ extern (C) int rt_term() */ alias Throwable.TraceInfo function(void* ptr) TraceHandler; private __gshared TraceHandler traceHandler = null; +private __gshared Throwable.TraceDeallocator traceDeallocator = null; /** @@ -189,10 +190,12 @@ private __gshared TraceHandler traceHandler = null; * * Params: * h = The new trace handler. Set to null to use the default handler. + * d = The new dealloactor to use. */ -extern (C) void rt_setTraceHandler(TraceHandler h) +extern (C) void rt_setTraceHandler(TraceHandler h, Throwable.TraceDeallocator d = null) { traceHandler = h; + traceDeallocator = d; } /** @@ -203,6 +206,11 @@ extern (C) TraceHandler rt_getTraceHandler() return traceHandler; } +extern (C) Throwable.TraceDeallocator rt_getTraceDeallocator() +{ + return traceDeallocator; +} + /** * This function will be called when an exception is constructed. The * user-supplied trace handler will be called if one has been supplied, diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 09da6a8..be31395 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -792c8b7c1d5957767e138f78d04bf175d4b92f10 +13ef27a56e4c22e122fc4dd54bb46b5955babdb0 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 9a365d5..967d2a6 100644 --- a/libphobos/src/std/algorithm/iteration.d +++ b/libphobos/src/std/algorithm/iteration.d @@ -7737,8 +7737,9 @@ if (isInputRange!R && // uniq /** -Lazily iterates unique consecutive elements of the given range (functionality -akin to the $(HTTP wikipedia.org/wiki/_Uniq, _uniq) system +Lazily iterates unique consecutive elements of the given range, which is +assumed to be sorted (functionality akin to the +$(HTTP wikipedia.org/wiki/_Uniq, _uniq) system utility). Equivalence of elements is assessed by using the predicate `pred`, by default `"a == b"`. The predicate is passed to $(REF binaryFun, std,functional), and can either accept a string, or any callable diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d index d1b6421..aef2365 100644 --- a/libphobos/src/std/conv.d +++ b/libphobos/src/std/conv.d @@ -1891,9 +1891,7 @@ if (!is(S : T) && isAssociativeArray!S && } // test conversions floating => integral { - // AllInts[0 .. $ - 1] should be AllInts - // @@@ BUG IN COMPILER @@@ - foreach (Integral; AllInts[0 .. $ - 1]) + foreach (Integral; AllInts) { foreach (Floating; AllFloats) { @@ -1903,7 +1901,7 @@ if (!is(S : T) && isAssociativeArray!S && } // test conversion integral => floating { - foreach (Integral; AllInts[0 .. $ - 1]) + foreach (Integral; AllInts) { foreach (Floating; AllFloats) { diff --git a/libphobos/src/std/math/exponential.d b/libphobos/src/std/math/exponential.d index e32330f..66f4b8a 100644 --- a/libphobos/src/std/math/exponential.d +++ b/libphobos/src/std/math/exponential.d @@ -2910,7 +2910,7 @@ private alias log10P = logP; alias log10Q = logQ; - // Coefficients for log(x) = z + z^^3 P(z^^2)/Q(z^^2) + // Coefficients for log(x) = z + z^^3 R(z^^2)/S(z^^2) // where z = 2(x-1)/(x+1) // Theoretical peak relative error = 1.1e-35 static immutable real[6] logR = [ @@ -2931,7 +2931,8 @@ private 1.0 ]; } - else + else static if (floatTraits!T.realFormat == RealFormat.ieeeExtended || + floatTraits!T.realFormat == RealFormat.ieeeExtended53) { // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x) // Theoretical peak relative error = 2.32e-20 @@ -2980,7 +2981,7 @@ private alias log10P = log2P; alias log10Q = log2Q; - // Coefficients for log(x) = z + z^^3 P(z^^2)/Q(z^^2) + // Coefficients for log(x) = z + z^^3 R(z^^2)/S(z^^2) // where z = 2(x-1)/(x+1) // Theoretical peak relative error = 6.16e-22 static immutable real[4] logR = [ @@ -2996,6 +2997,85 @@ private 1.0000000000000000000000E0L, ]; } + else static if (floatTraits!T.realFormat == RealFormat.ieeeDouble) + { + // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x) + static immutable double[6] logP = [ + 7.70838733755885391666E0, + 1.79368678507819816313E1, + 1.44989225341610930846E1, + 4.70579119878881725854E0, + 4.97494994976747001425E-1, + 1.01875663804580931796E-4, + ]; + static immutable double[6] logQ = [ + 2.31251620126765340583E1, + 7.11544750618563894466E1, + 8.29875266912776603211E1, + 4.52279145837532221105E1, + 1.12873587189167450590E1, + 1.00000000000000000000E0, + ]; + + // log2 uses the same coefficients as log. + alias log2P = logP; + alias log2Q = logQ; + + // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x) + static immutable double[7] log10P = [ + 1.98892446572874072159E1, + 5.67349287391754285487E1, + 6.06127134467767258030E1, + 2.97877425097986925891E1, + 6.56312093769992875930E0, + 4.98531067254050724270E-1, + 4.58482948458143443514E-5, + ]; + static immutable double[7] log10Q = [ + 5.96677339718622216300E1, + 2.14955586696422947765E2, + 3.07254189979530058263E2, + 2.20664384982121929218E2, + 8.27410449222435217021E1, + 1.50314182634250003249E1, + 1.00000000000000000000E0, + ]; + + // Coefficients for log(x) = z + z^^3 R(z)/S(z) + // where z = 2(x-1)/(x+1) + static immutable double[3] logR = [ + -6.41409952958715622951E1, + 1.63866645699558079767E1, + -7.89580278884799154124E-1, + ]; + static immutable double[4] logS = [ + -7.69691943550460008604E2, + 3.12093766372244180303E2, + -3.56722798256324312549E1, + 1.00000000000000000000E0, + ]; + } + else static if (floatTraits!T.realFormat == RealFormat.ieeeSingle) + { + // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x) + static immutable float[9] logP = [ + 3.3333331174E-1, + -2.4999993993E-1, + 2.0000714765E-1, + -1.6668057665E-1, + 1.4249322787E-1, + -1.2420140846E-1, + 1.1676998740E-1, + -1.1514610310E-1, + 7.0376836292E-2, + ]; + + // log2 and log10 uses the same coefficients as log. + alias log2P = logP; + alias log10P = logP; + } + else + static assert(0, "no coefficients for log()"); } } @@ -3009,6 +3089,7 @@ private * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no)) * ) */ +pragma(inline, true) real log(real x) @safe pure nothrow @nogc { version (INLINE_YL2X) @@ -3020,6 +3101,31 @@ real log(real x) @safe pure nothrow @nogc return logImpl(x); } +/// ditto +pragma(inline, true) +double log(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log(cast(real) x) : logImpl(x); } + +/// ditto +pragma(inline, true) +float log(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log(cast(real) x) : logImpl(x); } + +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log` called with argument types `(int)` matches both " + ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.") +real log(int x) @safe pure nothrow @nogc { return log(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log` called with argument types `(uint)` matches both " + ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.") +real log(uint x) @safe pure nothrow @nogc { return log(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log` called with argument types `(long)` matches both " + ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.") +real log(long x) @safe pure nothrow @nogc { return log(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log` called with argument types `(ulong)` matches both " + ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.") +real log(ulong x) @safe pure nothrow @nogc { return log(cast(real) x); } + /// @safe pure nothrow @nogc unittest { @@ -3034,12 +3140,31 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc import std.math.constants : SQRT1_2; import std.math.algebraic : poly; import std.math.traits : isInfinity, isNaN, signbit; + import std.math : floatTraits, RealFormat; alias coeffs = LogCoeffs!T; + alias F = floatTraits!T; - // C1 + C2 = LN2. - enum T C1 = 6.93145751953125E-1L; - enum T C2 = 1.428606820309417232121458176568075500134E-6L; + static if (F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) + { + // C1 + C2 = LN2. + enum T C1 = 6.93145751953125E-1L; + enum T C2 = 1.428606820309417232121458176568075500134E-6L; + } + else static if (F.realFormat == RealFormat.ieeeDouble) + { + enum T C1 = 0.693359375; + enum T C2 = -2.121944400546905827679e-4; + } + else static if (F.realFormat == RealFormat.ieeeSingle) + { + enum T C1 = 0.693359375; + enum T C2 = -2.12194440e-4; + } + else + static assert(0, "Not implemented for this architecture"); // Special cases. if (isNaN(x)) @@ -3058,30 +3183,36 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc x = frexp(x, exp); - // Logarithm using log(x) = z + z^^3 R(z) / S(z), - // where z = 2(x - 1)/(x + 1) - if ((exp > 2) || (exp < -2)) + static if (F.realFormat == RealFormat.ieeeDouble || + F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) { - if (x < SQRT1_2) - { // 2(2x - 1)/(2x + 1) - exp -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } - else - { // 2(x - 1)/(x + 1) - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; - } - x = z / y; - z = x * x; - z = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); - z += exp * C2; - z += x; - z += exp * C1; + // Logarithm using log(x) = z + z^^3 R(z) / S(z), + // where z = 2(x - 1)/(x + 1) + if ((exp > 2) || (exp < -2)) + { + if (x < SQRT1_2) + { // 2(2x - 1)/(2x + 1) + exp -= 1; + z = x - 0.5; + y = 0.5 * z + 0.5; + } + else + { // 2(x - 1)/(x + 1) + z = x - 0.5; + z -= 0.5; + y = 0.5 * x + 0.5; + } + x = z / y; + z = x * x; + z = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); + z += exp * C2; + z += x; + z += exp * C1; - return z; + return z; + } } // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x) @@ -3095,7 +3226,10 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc x = x - 1.0; } z = x * x; - y = x * (z * poly(x, coeffs.logP) / poly(x, coeffs.logQ)); + static if (F.realFormat == RealFormat.ieeeSingle) + y = x * (z * poly(x, coeffs.logP)); + else + y = x * (z * poly(x, coeffs.logP) / poly(x, coeffs.logQ)); y += exp * C2; z = y - 0.5 * z; @@ -3117,6 +3251,7 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no)) * ) */ +pragma(inline, true) real log10(real x) @safe pure nothrow @nogc { version (INLINE_YL2X) @@ -3128,12 +3263,37 @@ real log10(real x) @safe pure nothrow @nogc return log10Impl(x); } +/// ditto +pragma(inline, true) +double log10(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log10(cast(real) x) : log10Impl(x); } + +/// ditto +pragma(inline, true) +float log10(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log10(cast(real) x) : log10Impl(x); } + +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log10` called with argument types `(int)` matches both " + ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.") +real log10(int x) @safe pure nothrow @nogc { return log10(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log10` called with argument types `(uint)` matches both " + ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.") +real log10(uint x) @safe pure nothrow @nogc { return log10(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log10` called with argument types `(long)` matches both " + ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.") +real log10(long x) @safe pure nothrow @nogc { return log10(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log10` called with argument types `(ulong)` matches both " + ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.") +real log10(ulong x) @safe pure nothrow @nogc { return log10(cast(real) x); } + /// @safe pure nothrow @nogc unittest { import std.math.algebraic : fabs; - assert(fabs(log10(1000) - 3) < .000001); + assert(fabs(log10(1000.0L) - 3) < .000001); } private T log10Impl(T)(T x) @safe pure nothrow @nogc @@ -3141,16 +3301,34 @@ private T log10Impl(T)(T x) @safe pure nothrow @nogc import std.math.constants : SQRT1_2; import std.math.algebraic : poly; import std.math.traits : isNaN, isInfinity, signbit; + import std.math : floatTraits, RealFormat; alias coeffs = LogCoeffs!T; + alias F = floatTraits!T; - // log10(2) split into two parts. - enum T L102A = 0.3125L; - enum T L102B = -1.14700043360188047862611052755069732318101185E-2L; + static if (F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) + { + // log10(2) split into two parts. + enum T L102A = 0.3125L; + enum T L102B = -1.14700043360188047862611052755069732318101185E-2L; - // log10(e) split into two parts. - enum T L10EA = 0.5L; - enum T L10EB = -6.570551809674817234887108108339491770560299E-2L; + // log10(e) split into two parts. + enum T L10EA = 0.5L; + enum T L10EB = -6.570551809674817234887108108339491770560299E-2L; + } + else static if (F.realFormat == RealFormat.ieeeDouble || + F.realFormat == RealFormat.ieeeSingle) + { + enum T L102A = 3.0078125E-1; + enum T L102B = 2.48745663981195213739E-4; + + enum T L10EA = 4.3359375E-1; + enum T L10EB = 7.00731903251827651129E-4; + } + else + static assert(0, "Not implemented for this architecture"); // Special cases are the same as for log. if (isNaN(x)) @@ -3169,26 +3347,31 @@ private T log10Impl(T)(T x) @safe pure nothrow @nogc x = frexp(x, exp); - // Logarithm using log(x) = z + z^^3 R(z) / S(z), - // where z = 2(x - 1)/(x + 1) - if ((exp > 2) || (exp < -2)) - { - if (x < SQRT1_2) - { // 2(2x - 1)/(2x + 1) - exp -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } - else - { // 2(x - 1)/(x + 1) - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; + static if (F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) + { + // Logarithm using log(x) = z + z^^3 R(z) / S(z), + // where z = 2(x - 1)/(x + 1) + if ((exp > 2) || (exp < -2)) + { + if (x < SQRT1_2) + { // 2(2x - 1)/(2x + 1) + exp -= 1; + z = x - 0.5; + y = 0.5 * z + 0.5; + } + else + { // 2(x - 1)/(x + 1) + z = x - 0.5; + z -= 0.5; + y = 0.5 * x + 0.5; + } + x = z / y; + z = x * x; + y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); + goto Ldone; } - x = z / y; - z = x * x; - y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); - goto Ldone; } // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x) @@ -3201,7 +3384,10 @@ private T log10Impl(T)(T x) @safe pure nothrow @nogc x = x - 1.0; z = x * x; - y = x * (z * poly(x, coeffs.log10P) / poly(x, coeffs.log10Q)); + static if (F.realFormat == RealFormat.ieeeSingle) + y = x * (z * poly(x, coeffs.log10P)); + else + y = x * (z * poly(x, coeffs.log10P) / poly(x, coeffs.log10Q)); y = y - 0.5 * z; // Multiply log of fraction by log10(e) and base 2 exponent by log10(2). @@ -3232,6 +3418,7 @@ Ldone: * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no)) * ) */ +pragma(inline, true) real log1p(real x) @safe pure nothrow @nogc { version (INLINE_YL2X) @@ -3245,6 +3432,31 @@ real log1p(real x) @safe pure nothrow @nogc return log1pImpl(x); } +/// ditto +pragma(inline, true) +double log1p(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log1p(cast(real) x) : log1pImpl(x); } + +/// ditto +pragma(inline, true) +float log1p(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log1p(cast(real) x) : log1pImpl(x); } + +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log1p` called with argument types `(int)` matches both " + ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.") +real log1p(int x) @safe pure nothrow @nogc { return log1p(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log1p` called with argument types `(uint)` matches both " + ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.") +real log1p(uint x) @safe pure nothrow @nogc { return log1p(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log1p` called with argument types `(long)` matches both " + ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.") +real log1p(long x) @safe pure nothrow @nogc { return log1p(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log1p` called with argument types `(ulong)` matches both " + ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.") +real log1p(ulong x) @safe pure nothrow @nogc { return log1p(cast(real) x); } + /// @safe pure unittest { @@ -3289,6 +3501,7 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no) ) * ) */ +pragma(inline, true) real log2(real x) @safe pure nothrow @nogc { version (INLINE_YL2X) @@ -3297,6 +3510,31 @@ real log2(real x) @safe pure nothrow @nogc return log2Impl(x); } +/// ditto +pragma(inline, true) +double log2(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log2(cast(real) x) : log2Impl(x); } + +/// ditto +pragma(inline, true) +float log2(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log2(cast(real) x) : log2Impl(x); } + +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log2` called with argument types `(int)` matches both " + ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.") +real log2(int x) @safe pure nothrow @nogc { return log2(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log2` called with argument types `(uint)` matches both " + ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.") +real log2(uint x) @safe pure nothrow @nogc { return log2(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log2` called with argument types `(long)` matches both " + ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.") +real log2(long x) @safe pure nothrow @nogc { return log2(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log2` called with argument types `(ulong)` matches both " + ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.") +real log2(ulong x) @safe pure nothrow @nogc { return log2(cast(real) x); } + /// @safe unittest { @@ -3318,8 +3556,10 @@ private T log2Impl(T)(T x) @safe pure nothrow @nogc import std.math.traits : isNaN, isInfinity, signbit; import std.math.constants : SQRT1_2, LOG2E; import std.math.algebraic : poly; + import std.math : floatTraits, RealFormat; alias coeffs = LogCoeffs!T; + alias F = floatTraits!T; // Special cases are the same as for log. if (isNaN(x)) @@ -3338,26 +3578,32 @@ private T log2Impl(T)(T x) @safe pure nothrow @nogc x = frexp(x, exp); - // Logarithm using log(x) = z + z^^3 R(z) / S(z), - // where z = 2(x - 1)/(x + 1) - if ((exp > 2) || (exp < -2)) + static if (F.realFormat == RealFormat.ieeeDouble || + F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) { - if (x < SQRT1_2) - { // 2(2x - 1)/(2x + 1) - exp -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } - else - { // 2(x - 1)/(x + 1) - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; + // Logarithm using log(x) = z + z^^3 R(z) / S(z), + // where z = 2(x - 1)/(x + 1) + if ((exp > 2) || (exp < -2)) + { + if (x < SQRT1_2) + { // 2(2x - 1)/(2x + 1) + exp -= 1; + z = x - 0.5; + y = 0.5 * z + 0.5; + } + else + { // 2(x - 1)/(x + 1) + z = x - 0.5; + z -= 0.5; + y = 0.5 * x + 0.5; + } + x = z / y; + z = x * x; + y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); + goto Ldone; } - x = z / y; - z = x * x; - y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); - goto Ldone; } // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x) @@ -3370,7 +3616,10 @@ private T log2Impl(T)(T x) @safe pure nothrow @nogc x = x - 1.0; z = x * x; - y = x * (z * poly(x, coeffs.log2P) / poly(x, coeffs.log2Q)); + static if (F.realFormat == RealFormat.ieeeSingle) + y = x * (z * poly(x, coeffs.log2P)); + else + y = x * (z * poly(x, coeffs.log2P) / poly(x, coeffs.log2Q)); y = y - 0.5 * z; // Multiply log of fraction by log10(e) and base 2 exponent by log10(2). diff --git a/libphobos/src/std/math/operations.d b/libphobos/src/std/math/operations.d index cb3c805..f2e1800 100644 --- a/libphobos/src/std/math/operations.d +++ b/libphobos/src/std/math/operations.d @@ -1793,7 +1793,7 @@ if (isFloatingPoint!T) } import std.math.exponential : log2; - enum log2_max_exp = cast(int) log2(T.max_exp); + enum log2_max_exp = cast(int) log2(T(T.max_exp)); ret.mantissa = ival & ((1L << (T.mant_dig - 1)) - 1); ret.exponent = (ival >> (T.mant_dig - 1)) & ((1L << (log2_max_exp + 1)) - 1); diff --git a/libphobos/src/std/numeric.d b/libphobos/src/std/numeric.d index df7ac39..648b70e 100644 --- a/libphobos/src/std/numeric.d +++ b/libphobos/src/std/numeric.d @@ -436,7 +436,7 @@ public: static @property size_t dig() { auto shiftcnt = precision - ((flags&Flags.storeNormalized) == 0); - return shiftcnt == 64 ? 19 : cast(size_t) log10(1uL << shiftcnt); + return shiftcnt == 64 ? 19 : cast(size_t) log10(real(1uL << shiftcnt)); } /// Returns: smallest increment to the value 1 diff --git a/libphobos/src/std/parallelism.d b/libphobos/src/std/parallelism.d index 2c97638..9b231f3 100644 --- a/libphobos/src/std/parallelism.d +++ b/libphobos/src/std/parallelism.d @@ -1508,7 +1508,7 @@ public: if (this.size == 0) { - return rangeLen; + return max(rangeLen, 1); } immutable size_t eightSize = 4 * (this.size + 1); @@ -3644,6 +3644,15 @@ ParallelForeach!R parallel(R)(R range, size_t workUnitSize) assert(arrIndex.sum == 10.iota.sum); } +// https://issues.dlang.org/show_bug.cgi?id=22745 +@system unittest +{ + auto pool = new TaskPool(0); + int[] empty; + foreach (i; pool.parallel(empty)) {} + pool.finish(); +} + // Thrown when a parallel foreach loop is broken from. class ParallelForeachError : Error { @@ -4339,7 +4348,7 @@ version (StdUnittest) foreach (i, elem; logs) { - assert(isClose(elem, cast(double) log(i + 1))); + assert(isClose(elem, log(double(i + 1)))); } assert(poolInstance.amap!"a * a"([1,2,3,4,5]) == [1,4,9,16,25]); diff --git a/libphobos/src/std/random.d b/libphobos/src/std/random.d index 9b3c5ed..93be764 100644 --- a/libphobos/src/std/random.d +++ b/libphobos/src/std/random.d @@ -2516,7 +2516,7 @@ if (!is(T == enum) && (isIntegral!T || isSomeChar!T)) assert(rnd.uniform!ulong == 4838462006927449017); enum Fruit { apple, mango, pear } - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(rnd.uniform!Fruit == Fruit.mango); } @@ -2798,7 +2798,7 @@ auto ref choice(Range)(ref Range range) auto rnd = MinstdRand0(42); auto elem = [1, 2, 3, 4, 5].choice(rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(elem == 3); } @@ -2913,7 +2913,7 @@ if (isRandomAccessRange!Range) auto rnd = MinstdRand0(42); auto arr = [1, 2, 3, 4, 5].randomShuffle(rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(arr == [3, 5, 2, 4, 1]); } @@ -3003,15 +3003,15 @@ if (isRandomAccessRange!Range) auto arr = [1, 2, 3, 4, 5, 6]; arr = arr.dup.partialShuffle(1, rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(arr == [2, 1, 3, 4, 5, 6]); // 1<->2 arr = arr.dup.partialShuffle(2, rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(arr == [1, 4, 3, 2, 5, 6]); // 1<->2, 2<->4 arr = arr.dup.partialShuffle(3, rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(arr == [5, 4, 6, 2, 1, 3]); // 1<->5, 2<->4, 3<->6 } @@ -3428,7 +3428,7 @@ if (isRandomAccessRange!Range) import std.range : iota; auto rnd = MinstdRand0(42); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(10.iota.randomCover(rnd).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5])); } diff --git a/libphobos/src/std/regex/package.d b/libphobos/src/std/regex/package.d index 1562d79..d6a01e2 100644 --- a/libphobos/src/std/regex/package.d +++ b/libphobos/src/std/regex/package.d @@ -212,7 +212,7 @@ They met on 24/01/1970. names work like aliases in addition to direct numbers. ) $(REG_TITLE Assertions, Match position rather than character ) - $(REG_ROW ^, Matches at the begining of input or line (in multiline mode).) + $(REG_ROW ^, Matches at the beginning of input or line (in multiline mode).) $(REG_ROW $, Matches at the end of input or line (in multiline mode). ) $(REG_ROW \b, Matches at word boundary. ) $(REG_ROW \B, Matches when $(U not) at word boundary. ) diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index e83b6171..25cf9e0 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -225,7 +225,10 @@ public: { if (_p !is null) { - destroy(_p); + static if (is(T == class) || is(T == interface)) + destroy(_p); + else + destroy(*_p); _p = null; } } @@ -259,7 +262,7 @@ private: /// @safe unittest { - static struct S + struct S { int i; this(int i){this.i = i;} @@ -284,6 +287,7 @@ private: Unique!S u1; assert(u1.isEmpty); u1 = produce(); + assert(u1.i == 5); increment(u1); assert(u1.i == 6); //consume(u1); // Error: u1 is not copyable @@ -292,6 +296,24 @@ private: assert(u1.isEmpty); } +@safe unittest +{ + int i; + struct S + { + ~this() + { + // check context pointer still exists - dtor also called before GC frees struct + if (this.tupleof[0]) + i++; + } + } + { + Unique!S u = new S; + } + assert(i == 1); +} + @system unittest { // test conversion to base ref diff --git a/libphobos/testsuite/libphobos.exceptions/refcounted.d b/libphobos/testsuite/libphobos.exceptions/refcounted.d index 2b7e79b..e4ed8e8 100644 --- a/libphobos/testsuite/libphobos.exceptions/refcounted.d +++ b/libphobos/testsuite/libphobos.exceptions/refcounted.d @@ -2,9 +2,9 @@ class E : Exception { static int instances; - this(string msg = "") + this(string msg = "", Throwable nextInChain = null) { - super(msg); + super(msg, nextInChain); instances++; } @@ -93,4 +93,34 @@ void main() } assert(E.instances == 0); + + try + { + throw new E("first"); + } + catch (E first) + { + assert(first.refcount == 2); + assert(E.instances == 1); + + try + { + throw new E("second", first); + } + catch (E second) + { + assert(first.next is null); + assert(second.next is first); + + assert(first.refcount == 3); + assert(second.refcount == 2); + + assert(E.instances == 2); + } + + assert(first.refcount == 2); + assert(E.instances == 1); + } + + assert(E.instances == 0); } diff --git a/libphobos/testsuite/libphobos.gc/issue22843.d b/libphobos/testsuite/libphobos.gc/issue22843.d new file mode 100644 index 0000000..bf6e830 --- /dev/null +++ b/libphobos/testsuite/libphobos.gc/issue22843.d @@ -0,0 +1,12 @@ +import core.memory; +void main() +{ + auto collections = GC.profileStats().numCollections; + // loop until we trigger a collection + for (;;) + { + cast(void)GC.malloc(100_000, GC.BlkAttr.NO_SCAN); + if (GC.profileStats().numCollections == collections+1) + break; + } +} diff --git a/libphobos/testsuite/libphobos.shared/finalize.d b/libphobos/testsuite/libphobos.shared/finalize.d index f31b818..fcec87b 100644 --- a/libphobos/testsuite/libphobos.shared/finalize.d +++ b/libphobos/testsuite/libphobos.shared/finalize.d @@ -7,9 +7,9 @@ import core.sys.posix.dlfcn; void runTest() { Object obj; - obj = Object.factory("lib.MyFinalizer"); + obj = Object.factory("lib.MyFinalizer"); // { dg-warning "is deprecated" } assert(obj.toString() == "lib.MyFinalizer"); - obj = Object.factory("lib.MyFinalizerBig"); + obj = Object.factory("lib.MyFinalizerBig"); // { dg-warning "is deprecated" } assert(obj.toString() == "lib.MyFinalizerBig"); } |