diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-03-29 16:57:10 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-04-02 23:56:52 +0200 |
commit | 235d5a96cb8dad0b4c427602346fcf966a4ec914 (patch) | |
tree | ca19c774a19ad923e5d6f09d43ee8d89c275a96e | |
parent | be07535d0f43390b8906826cc119473dea514b54 (diff) | |
download | gcc-235d5a96cb8dad0b4c427602346fcf966a4ec914.zip gcc-235d5a96cb8dad0b4c427602346fcf966a4ec914.tar.gz gcc-235d5a96cb8dad0b4c427602346fcf966a4ec914.tar.bz2 |
d: Merge upstream dmd 47871363d, druntime, c52e28b7, phobos 99e9c1b77.
D front-end changes:
- Import dmd v2.099.1-beta.1.
- The address of NRVO variables is now stored in scoped closures
when they have nested references.
- Using `__traits(parameters)' in foreach loops now always returns
the parameters to the function the foreach appears within.
Previously, when used inside a `foreach' using an overloaded
`opApply', the trait would yield the parameters to the delegate.
- The deprecation period of unannotated `asm' blocks has been ended.
- The `inout' attribute no longer implies the `return' attribute.
- Added new `D_PreConditions', `D_PostConditions', and
`D_Invariants' version identifiers.
D runtime changes:
- Import druntime v2.099.1-beta.1.
Phobos changes:
- Import phobos v2.099.1-beta.1.
- `Nullable' in `std.typecons' can now act as a range.
- std.experimental.logger default level changed to `info' instead of
`warning'.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 47871363d.
* d-builtins.cc (d_init_versions): Add predefined version identifiers
D_PreConditions, D_PostConditions, and D_Invariants.
* d-codegen.cc (d_build_call): Update for new front-end interface.
(build_frame_type): Generate reference field for NRVO variables with
nested references.
(build_closure): Generate assignment of return address to closure.
* d-tree.h (DECL_INSTANTIATED): Use DECL_LANG_FLAG_2.
(bind_expr): Remove.
* decl.cc (DeclVisitor::visit (FuncDeclaration *)): Update for new
front-end interface.
(get_symbol_decl): Likewise.
(get_decl_tree): Check DECL_LANG_FRAME_FIELD before DECL_LANG_NRVO.
Dereference the field when both are set.
* expr.cc (ExprVisitor::visit (DeleteExp *)): Update for new front-end
interface.
* modules.cc (get_internal_fn): Likewise.
* toir.cc (IRVisitor::visit (ReturnStatement *)): Likewise.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime c52e28b7.
* libdruntime/Makefile.am (DRUNTIME_DSOURCES_OPENBSD): Add
core/sys/openbsd/pwd.d.
* libdruntime/Makefile.in: Regenerate.
* src/MERGE: Merge upstream phobos 99e9c1b77.
* testsuite/libphobos.exceptions/message_with_null.d: New test.
gcc/testsuite/ChangeLog:
* gdc.dg/nrvo1.d: New test.
527 files changed, 2728 insertions, 1913 deletions
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc index 73b4766..7e7fb75 100644 --- a/gcc/d/d-builtins.cc +++ b/gcc/d/d-builtins.cc @@ -484,6 +484,15 @@ d_init_versions (void) if (global.params.useAssert == CHECKENABLEon) VersionCondition::addPredefinedGlobalIdent ("assert"); + if (global.params.useIn == CHECKENABLEon) + VersionCondition::addPredefinedGlobalIdent("D_PreConditions"); + + if (global.params.useOut == CHECKENABLEon) + VersionCondition::addPredefinedGlobalIdent("D_PostConditions"); + + if (global.params.useInvariants == CHECKENABLEon) + VersionCondition::addPredefinedGlobalIdent("D_Invariants"); + if (global.params.useArrayBounds == CHECKENABLEoff) VersionCondition::addPredefinedGlobalIdent ("D_NoBoundsChecks"); diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index 3206edd..bb96b2f 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -2207,9 +2207,9 @@ d_build_call (TypeFunction *tf, tree callable, tree object, build_address (targ)); } - /* Type `noreturn` is a terminator, as no other arguments can possibly - be evaluated after it. */ - if (TREE_TYPE (targ) == noreturn_type_node) + /* Type `noreturn` is a terminator, as no other arguments can possibly + be evaluated after it. */ + if (TREE_TYPE (targ) == noreturn_type_node) noreturn_call = true; vec_safe_push (args, targ); @@ -2690,9 +2690,15 @@ build_frame_type (tree ffi, FuncDeclaration *fd) DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym); TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym); - /* Can't do nrvo if the variable is put in a frame. */ - if (fd->nrvo_can && fd->nrvo_var == v) - fd->nrvo_can = 0; + if (DECL_LANG_NRVO (vsym)) + { + /* Store the nrvo variable in the frame by reference. */ + TREE_TYPE (field) = build_reference_type (TREE_TYPE (field)); + + /* Can't do nrvo if the variable is put in a closure, since what the + return slot points to may no longer exist. */ + gcc_assert (!FRAMEINFO_IS_CLOSURE (ffi)); + } if (FRAMEINFO_IS_CLOSURE (ffi)) { @@ -2769,13 +2775,17 @@ build_closure (FuncDeclaration *fd) for (size_t i = 0; i < fd->closureVars.length; i++) { VarDeclaration *v = fd->closureVars[i]; + tree vsym = get_symbol_decl (v); - if (!v->isParameter ()) + if (TREE_CODE (vsym) != PARM_DECL && !DECL_LANG_NRVO (vsym)) continue; - tree vsym = get_symbol_decl (v); - tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym)); + + /* Variable is an alias for the NRVO slot, store the reference. */ + if (DECL_LANG_NRVO (vsym)) + vsym = build_address (DECL_LANG_NRVO (vsym)); + tree expr = modify_expr (field, vsym); add_stmt (expr); } diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h index 5dec2e6..d93d02c 100644 --- a/gcc/d/d-tree.h +++ b/gcc/d/d-tree.h @@ -392,7 +392,7 @@ lang_tree_node /* True if the decl comes from a template instance. */ #define DECL_INSTANTIATED(NODE) \ - (DECL_LANG_FLAG_1 (VAR_OR_FUNCTION_DECL_CHECK (NODE))) + (DECL_LANG_FLAG_2 (VAR_OR_FUNCTION_DECL_CHECK (NODE))) enum d_tree_index { @@ -580,7 +580,6 @@ extern tree build_bounds_index_condition (IndexExp *, tree, tree); extern tree build_bounds_slice_condition (SliceExp *, tree, tree, tree); extern bool array_bounds_check (void); extern bool checkaction_trap_p (void); -extern tree bind_expr (tree, tree); extern TypeFunction *get_function_type (Type *); extern bool call_by_alias_p (FuncDeclaration *, FuncDeclaration *); extern tree d_build_call_expr (FuncDeclaration *, tree, Expressions *); diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 7ec0caf..ea8baef 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -791,7 +791,7 @@ public: return; } - if (d->semantic3Errors) + if (d->hasSemantic3Errors ()) return; if (d->isNested ()) @@ -805,7 +805,7 @@ public: break; /* Parent failed to compile, but errors were gagged. */ - if (fdp->semantic3Errors) + if (fdp->hasSemantic3Errors ()) return; } } @@ -921,15 +921,6 @@ public: } } - /* May change cfun->static_chain. */ - build_closure (d); - - if (d->vresult) - declare_local_var (d->vresult); - - if (d->v_argptr) - push_stmt_list (); - /* Named return value optimisation support for D. Implemented by overriding all the RETURN_EXPRs and replacing all occurrences of VAR with the RESULT_DECL for the function. @@ -951,7 +942,7 @@ public: else d->shidden = resdecl; - if (d->nrvo_can && d->nrvo_var) + if (d->isNRVO () && d->nrvo_var) { tree var = get_symbol_decl (d->nrvo_var); @@ -966,6 +957,15 @@ public: } } + /* May change cfun->static_chain. */ + build_closure (d); + + if (d->vresult) + declare_local_var (d->vresult); + + if (d->v_argptr) + push_stmt_list (); + build_function_body (d); /* Initialize the _argptr variable. */ @@ -1284,26 +1284,26 @@ get_symbol_decl (Declaration *decl) /* In [pragma/crtctor], Annotates a function so it is run after the C runtime library is initialized and before the D runtime library is initialized. */ - if (fd->isCrtCtorDtor == 1) + if (fd->isCrtCtor ()) { DECL_STATIC_CONSTRUCTOR (decl->csym) = 1; decl_init_priority_insert (decl->csym, DEFAULT_INIT_PRIORITY); } - else if (fd->isCrtCtorDtor == 2) + else if (fd->isCrtDtor ()) { DECL_STATIC_DESTRUCTOR (decl->csym) = 1; decl_fini_priority_insert (decl->csym, DEFAULT_INIT_PRIORITY); - } + } /* Function was declared `naked'. */ - if (fd->naked) + if (fd->isNaked ()) { insert_decl_attribute (decl->csym, "naked"); DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl->csym) = 1; } /* Mark compiler generated functions as artificial. */ - if (fd->generated) + if (fd->isGenerated ()) DECL_ARTIFICIAL (decl->csym) = 1; /* Ensure and require contracts are lexically nested in the function they @@ -1486,20 +1486,26 @@ get_decl_tree (Declaration *decl) if (vd == NULL || fd == NULL) return t; - /* Get the named return value. */ - if (DECL_LANG_NRVO (t)) - return DECL_LANG_NRVO (t); - /* Get the closure holding the var decl. */ if (DECL_LANG_FRAME_FIELD (t)) { FuncDeclaration *parent = vd->toParent2 ()->isFuncDeclaration (); tree frame_ref = get_framedecl (fd, parent); - return component_ref (build_deref (frame_ref), - DECL_LANG_FRAME_FIELD (t)); + tree field = component_ref (build_deref (frame_ref), + DECL_LANG_FRAME_FIELD (t)); + /* Frame field can also be a reference to the DECL_RESULT of a function. + Dereference it to get the value. */ + if (DECL_LANG_NRVO (t)) + field = build_deref (field); + + return field; } + /* Get the named return value. */ + if (DECL_LANG_NRVO (t)) + return DECL_LANG_NRVO (t); + /* Get the non-local `this' value by going through parent link of nested classes, this routine pretty much undoes what getRightThis in the frontend removes from codegen. */ diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 3e3e113..ca409df 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -2503f17e5767bc4fcd0cf3889c90fa0415b0edaa +47871363d804f54b29ccfd444b082c19716c2301 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 17724c6..16f49a7 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.099.0 +v2.099.1-beta.1 diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d index f790730..8895aa5 100644 --- a/gcc/d/dmd/aggregate.d +++ b/gcc/d/dmd/aggregate.d @@ -547,7 +547,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol if (overflow) assert(0); // Skip no-op for noreturn without custom aligment - if (memsize != 0 || !alignment.isDefault()) + if (memalignsize != 0 || !alignment.isDefault()) alignmember(alignment, memalignsize, &ofs); uint memoffset = ofs; @@ -570,7 +570,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol * definitions exposed some issues in their TypeInfo generation in DMD. * Related PR: https://github.com/dlang/dmd/pull/13312 */ - if (semanticRun == PASS.init && !isInterfaceDeclaration()) + if (semanticRun == PASS.initial && !isInterfaceDeclaration()) { auto stc = storage_class; if (_scope) @@ -747,7 +747,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol extern (C++) static int fp(Dsymbol s, void* ctxt) { auto f = s.isCtorDeclaration(); - if (f && f.semanticRun == PASS.init) + if (f && f.semanticRun == PASS.initial) f.dsymbolSemantic(null); return 0; } diff --git a/gcc/d/dmd/aliasthis.d b/gcc/d/dmd/aliasthis.d index 458e821..2771071b 100644 --- a/gcc/d/dmd/aliasthis.d +++ b/gcc/d/dmd/aliasthis.d @@ -100,9 +100,9 @@ Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false, bool find if (tthis && ad.aliasthis.sym.needThis()) { - if (e.op == EXP.variable) + if (auto ve = e.isVarExp()) { - if (auto fd = (cast(VarExp)e).var.isFuncDeclaration()) + if (auto fd = ve.var.isFuncDeclaration()) { // https://issues.dlang.org/show_bug.cgi?id=13009 // Support better match for the overloaded alias this. diff --git a/gcc/d/dmd/arrayop.d b/gcc/d/dmd/arrayop.d index e82413f..52f39d3 100644 --- a/gcc/d/dmd/arrayop.d +++ b/gcc/d/dmd/arrayop.d @@ -52,16 +52,16 @@ bool isArrayOpValid(Expression e) { if (isUnaArrayOp(e.op)) { - return isArrayOpValid((cast(UnaExp)e).e1); + return isArrayOpValid(e.isUnaExp().e1); } if (isBinArrayOp(e.op) || isBinAssignArrayOp(e.op) || e.op == EXP.assign) { - BinExp be = cast(BinExp)e; + BinExp be = e.isBinExp(); return isArrayOpValid(be.e1) && isArrayOpValid(be.e2); } if (e.op == EXP.construct) { - BinExp be = cast(BinExp)e; + BinExp be = e.isBinExp(); return be.e1.op == EXP.slice && isArrayOpValid(be.e2); } // if (e.op == EXP.call) @@ -76,7 +76,7 @@ bool isArrayOpValid(Expression e) bool isNonAssignmentArrayOp(Expression e) { if (e.op == EXP.slice) - return isNonAssignmentArrayOp((cast(SliceExp)e).e1); + return isNonAssignmentArrayOp(e.isSliceExp().e1); Type tb = e.type.toBasetype(); if (tb.ty == Tarray || tb.ty == Tsarray) @@ -176,7 +176,7 @@ Expression arrayOp(BinAssignExp e, Scope* sc) return e.e1.modifiableLvalue(sc, e.e1); } - return arrayOp(cast(BinExp)e, sc); + return arrayOp(e.isBinExp(), sc); } /****************************************** diff --git a/gcc/d/dmd/arraytypes.d b/gcc/d/dmd/arraytypes.d index ffbaf95..29b3a3d 100644 --- a/gcc/d/dmd/arraytypes.d +++ b/gcc/d/dmd/arraytypes.d @@ -54,4 +54,3 @@ alias TemplateInstances = Array!(TemplateInstance); alias Ensures = Array!(Ensure); alias Designators = Array!(Designator); alias DesigInits = Array!(DesigInit); - diff --git a/gcc/d/dmd/arraytypes.h b/gcc/d/dmd/arraytypes.h index d7dfa0b..ca2051c 100644 --- a/gcc/d/dmd/arraytypes.h +++ b/gcc/d/dmd/arraytypes.h @@ -67,4 +67,3 @@ typedef Array<struct Ensure> Ensures; typedef Array<struct Designator> Designators; typedef Array<struct DesigInit> DesigInits; - diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d index 5c01204..afd7ac0 100644 --- a/gcc/d/dmd/blockexit.d +++ b/gcc/d/dmd/blockexit.d @@ -99,9 +99,8 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) result = BE.halt; return; } - if (s.exp.op == EXP.assert_) + if (AssertExp a = s.exp.isAssertExp()) { - AssertExp a = cast(AssertExp)s.exp; if (a.e1.toBool().hasValue(false)) // if it's an assert(0) { result = BE.halt; @@ -505,7 +504,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow) if (!(s.stc & STC.nothrow_)) { if (mustNotThrow && !(s.stc & STC.nothrow_)) - s.deprecation("`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); + s.error("`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); else result |= BE.throw_; } diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index a6dbd8e..2ed0dc7 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -301,7 +301,7 @@ FuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc) auto tf = new TypeFunction(ParameterList(fparams), sd.handleType(), LINK.d, stc | STC.ref_); auto fop = new FuncDeclaration(declLoc, Loc.initial, Id.assign, stc, tf); fop.storage_class |= STC.inference; - fop.generated = true; + fop.flags |= FUNCFLAG.generated; Expression e; if (stc & STC.disable) { @@ -575,7 +575,7 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc) tf = tf.addSTC(STC.const_).toTypeFunction(); Identifier id = Id.xopEquals; auto fop = new FuncDeclaration(declLoc, Loc.initial, id, 0, tf); - fop.generated = true; + fop.flags |= FUNCFLAG.generated; fop.parent = sd; Expression e1 = new IdentifierExp(loc, Id.This); Expression e2 = new IdentifierExp(loc, Id.p); @@ -644,13 +644,13 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc) switch (e.op) { case EXP.overloadSet: - s = (cast(OverExp)e).vars; + s = e.isOverExp().vars; break; case EXP.scope_: - s = (cast(ScopeExp)e).sds; + s = e.isScopeExp().sds; break; case EXP.variable: - s = (cast(VarExp)e).var; + s = e.isVarExp().var; break; default: break; @@ -696,7 +696,7 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc) tf = tf.addSTC(STC.const_).toTypeFunction(); Identifier id = Id.xopCmp; auto fop = new FuncDeclaration(declLoc, Loc.initial, id, 0, tf); - fop.generated = true; + fop.flags |= FUNCFLAG.generated; fop.parent = sd; Expression e1 = new IdentifierExp(loc, Id.This); Expression e2 = new IdentifierExp(loc, Id.p); @@ -814,7 +814,7 @@ FuncDeclaration buildXtoHash(StructDeclaration sd, Scope* sc) auto tf = new TypeFunction(ParameterList(parameters), Type.thash_t, LINK.d, STC.nothrow_ | STC.trusted); Identifier id = Id.xtoHash; auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.static_, tf); - fop.generated = true; + fop.flags |= FUNCFLAG.generated; /* Do memberwise hashing. * @@ -937,13 +937,13 @@ void buildDtors(AggregateDeclaration ad, Scope* sc) if (stc & STC.safe) stc = (stc & ~STC.safe) | STC.trusted; - ex = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t), + SliceExp se = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t), new IntegerExp(loc, n, Type.tsize_t)); // Prevent redundant bounds check - (cast(SliceExp)ex).upperIsInBounds = true; - (cast(SliceExp)ex).lowerIsLessThanUpper = true; + se.upperIsInBounds = true; + se.lowerIsLessThanUpper = true; - ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), ex); + ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), se); } e = Expression.combine(ex, e); // combine in reverse order } @@ -952,7 +952,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc) { //printf("Building __fieldDtor(), %s\n", e.toChars()); auto dd = new DtorDeclaration(declLoc, Loc.initial, stc, Id.__fieldDtor); - dd.generated = true; + dd.flags |= FUNCFLAG.generated; dd.storage_class |= STC.inference; dd.fbody = new ExpStatement(loc, e); ad.members.push(dd); @@ -1008,7 +1008,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc) e = Expression.combine(e, ce); } auto dd = new DtorDeclaration(declLoc, Loc.initial, stc, Id.__aggrDtor); - dd.generated = true; + dd.flags |= FUNCFLAG.generated; dd.storage_class |= STC.inference; dd.fbody = new ExpStatement(loc, e); ad.members.push(dd); @@ -1079,7 +1079,7 @@ private DtorDeclaration buildWindowsCppDtor(AggregateDeclaration ad, DtorDeclara stmts.push(new ExpStatement(loc, call)); stmts.push(new ReturnStatement(loc, new CastExp(loc, new ThisExp(loc), Type.tvoidptr))); func.fbody = new CompoundStatement(loc, stmts); - func.generated = true; + func.flags |= FUNCFLAG.generated; auto sc2 = sc.push(); sc2.stc &= ~STC.static_; // not a static destructor @@ -1127,7 +1127,7 @@ private DtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc) auto call = new CallExp(dtor.loc, dtor, null); call.directcall = true; // non-virtual call Class.__dtor(); func.fbody = new ExpStatement(dtor.loc, call); - func.generated = true; + func.flags |= FUNCFLAG.generated; func.storage_class |= STC.inference; auto sc2 = sc.push(); @@ -1403,7 +1403,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) //printf("Building __fieldPostBlit()\n"); checkShared(); auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__fieldPostblit); - dd.generated = true; + dd.flags |= FUNCFLAG.generated; dd.storage_class |= STC.inference | STC.scope_; dd.fbody = (stc & STC.disable) ? null : new CompoundStatement(loc, postblitCalls); sd.postblits.shift(dd); @@ -1441,7 +1441,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) checkShared(); auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__aggrPostblit); - dd.generated = true; + dd.flags |= FUNCFLAG.generated; dd.storage_class |= STC.inference; dd.fbody = new ExpStatement(loc, e); sd.members.push(dd); @@ -1504,7 +1504,7 @@ private CtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const auto ccd = new CtorDeclaration(sd.loc, Loc.initial, STC.ref_, tf, true); ccd.storage_class |= funcStc; ccd.storage_class |= STC.inference; - ccd.generated = true; + ccd.flags |= FUNCFLAG.generated; return ccd; } @@ -1691,5 +1691,3 @@ bool buildCopyCtor(StructDeclaration sd, Scope* sc) } return true; } - - diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d index 9941c16..75ba9ea 100644 --- a/gcc/d/dmd/constfold.d +++ b/gcc/d/dmd/constfold.d @@ -217,15 +217,13 @@ UnionExp Add(const ref Loc loc, Type type, Expression e1, Expression e2) } emplaceExp!(ComplexExp)(&ue, loc, v, type); } - else if (e1.op == EXP.symbolOffset) + else if (SymOffExp soe = e1.isSymOffExp()) { - SymOffExp soe = cast(SymOffExp)e1; emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset + e2.toInteger()); ue.exp().type = type; } - else if (e2.op == EXP.symbolOffset) + else if (SymOffExp soe = e2.isSymOffExp()) { - SymOffExp soe = cast(SymOffExp)e2; emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset + e1.toInteger()); ue.exp().type = type; } @@ -320,9 +318,8 @@ UnionExp Min(const ref Loc loc, Type type, Expression e1, Expression e2) } emplaceExp!(ComplexExp)(&ue, loc, v, type); } - else if (e1.op == EXP.symbolOffset) + else if (SymOffExp soe = e1.isSymOffExp()) { - SymOffExp soe = cast(SymOffExp)e1; emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset - e2.toInteger()); ue.exp().type = type; } @@ -731,14 +728,12 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e { if (e2.op == EXP.null_) cmp = 1; - else if (e2.op == EXP.string_) + else if (StringExp es2 = e2.isStringExp()) { - StringExp es2 = cast(StringExp)e2; cmp = (0 == es2.len); } - else if (e2.op == EXP.arrayLiteral) + else if (ArrayLiteralExp es2 = e2.isArrayLiteralExp()) { - ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; cmp = !es2.elements || (0 == es2.elements.dim); } else @@ -749,14 +744,12 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e } else if (e2.op == EXP.null_) { - if (e1.op == EXP.string_) + if (StringExp es1 = e1.isStringExp()) { - StringExp es1 = cast(StringExp)e1; cmp = (0 == es1.len); } - else if (e1.op == EXP.arrayLiteral) + else if (ArrayLiteralExp es1 = e1.isArrayLiteralExp()) { - ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1; cmp = !es1.elements || (0 == es1.elements.dim); } else @@ -767,8 +760,8 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e } else if (e1.op == EXP.string_ && e2.op == EXP.string_) { - StringExp es1 = cast(StringExp)e1; - StringExp es2 = cast(StringExp)e2; + StringExp es1 = e1.isStringExp(); + StringExp es2 = e2.isStringExp(); if (es1.sz != es2.sz) { assert(global.errors); @@ -784,8 +777,8 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e } else if (e1.op == EXP.arrayLiteral && e2.op == EXP.arrayLiteral) { - ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1; - ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; + ArrayLiteralExp es1 = e1.isArrayLiteralExp(); + ArrayLiteralExp es2 = e2.isArrayLiteralExp(); if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim)) cmp = 1; // both arrays are empty else if (!es1.elements || !es2.elements) @@ -818,8 +811,8 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e else if (e1.op == EXP.string_ && e2.op == EXP.arrayLiteral) { Lsa: - StringExp es1 = cast(StringExp)e1; - ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; + StringExp es1 = e1.isStringExp(); + ArrayLiteralExp es2 = e2.isArrayLiteralExp(); size_t dim1 = es1.len; size_t dim2 = es2.elements ? es2.elements.dim : 0; if (dim1 != dim2) @@ -844,8 +837,8 @@ UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e } else if (e1.op == EXP.structLiteral && e2.op == EXP.structLiteral) { - StructLiteralExp es1 = cast(StructLiteralExp)e1; - StructLiteralExp es2 = cast(StructLiteralExp)e2; + StructLiteralExp es1 = e1.isStructLiteralExp(); + StructLiteralExp es2 = e2.isStructLiteralExp(); if (es1.sd != es2.sd) cmp = 0; else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim)) @@ -935,8 +928,8 @@ UnionExp Identity(EXP op, const ref Loc loc, Type type, Expression e1, Expressio } else if (e1.op == EXP.symbolOffset && e2.op == EXP.symbolOffset) { - SymOffExp es1 = cast(SymOffExp)e1; - SymOffExp es2 = cast(SymOffExp)e2; + SymOffExp es1 = e1.isSymOffExp(); + SymOffExp es2 = e2.isSymOffExp(); cmp = (es1.var == es2.var && es1.offset == es2.offset); } else @@ -976,8 +969,8 @@ UnionExp Cmp(EXP op, const ref Loc loc, Type type, Expression e1, Expression e2) //printf("Cmp(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars()); if (e1.op == EXP.string_ && e2.op == EXP.string_) { - StringExp es1 = cast(StringExp)e1; - StringExp es2 = cast(StringExp)e2; + StringExp es1 = e1.isStringExp(); + StringExp es2 = e2.isStringExp(); size_t sz = es1.sz; assert(sz == es2.sz); size_t len = es1.len; @@ -1045,7 +1038,7 @@ UnionExp Cast(const ref Loc loc, Type type, Type to, Expression e1) } if (e1.op == EXP.vector && (cast(TypeVector)e1.type).basetype.equals(type) && type.equals(to)) { - Expression ex = (cast(VectorExp)e1).e1; + Expression ex = e1.isVectorExp().e1; emplaceExp!(UnionExp)(&ue, ex); return ue; } @@ -1201,20 +1194,17 @@ UnionExp ArrayLength(Type type, Expression e1) { UnionExp ue = void; Loc loc = e1.loc; - if (e1.op == EXP.string_) + if (StringExp es1 = e1.isStringExp()) { - StringExp es1 = cast(StringExp)e1; emplaceExp!(IntegerExp)(&ue, loc, es1.len, type); } - else if (e1.op == EXP.arrayLiteral) + else if (ArrayLiteralExp ale = e1.isArrayLiteralExp()) { - ArrayLiteralExp ale = cast(ArrayLiteralExp)e1; size_t dim = ale.elements ? ale.elements.dim : 0; emplaceExp!(IntegerExp)(&ue, loc, dim, type); } - else if (e1.op == EXP.assocArrayLiteral) + else if (AssocArrayLiteralExp ale = e1.isAssocArrayLiteralExp) { - AssocArrayLiteralExp ale = cast(AssocArrayLiteralExp)e1; size_t dim = ale.keys.dim; emplaceExp!(IntegerExp)(&ue, loc, dim, type); } @@ -1238,7 +1228,7 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds) assert(e1.type); if (e1.op == EXP.string_ && e2.op == EXP.int64) { - StringExp es1 = cast(StringExp)e1; + StringExp es1 = e1.isStringExp(); uinteger_t i = e2.toInteger(); if (i >= es1.len) { @@ -1261,9 +1251,8 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds) e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), length); emplaceExp!(ErrorExp)(&ue); } - else if (e1.op == EXP.arrayLiteral) + else if (ArrayLiteralExp ale = e1.isArrayLiteralExp()) { - ArrayLiteralExp ale = cast(ArrayLiteralExp)e1; auto e = ale[cast(size_t)i]; e.type = type; e.loc = loc; @@ -1278,9 +1267,8 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds) else if (e1.type.toBasetype().ty == Tarray && e2.op == EXP.int64) { uinteger_t i = e2.toInteger(); - if (e1.op == EXP.arrayLiteral) + if (ArrayLiteralExp ale = e1.isArrayLiteralExp()) { - ArrayLiteralExp ale = cast(ArrayLiteralExp)e1; if (i >= ale.elements.dim) { e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), cast(ulong) ale.elements.dim); @@ -1300,9 +1288,8 @@ UnionExp Index(Type type, Expression e1, Expression e2, bool indexIsInBounds) else cantExp(ue); } - else if (e1.op == EXP.assocArrayLiteral) + else if (AssocArrayLiteralExp ae = e1.isAssocArrayLiteralExp()) { - AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)e1; /* Search the keys backwards, in case there are duplicate keys */ for (size_t i = ae.keys.dim; i;) @@ -1350,7 +1337,7 @@ UnionExp Slice(Type type, Expression e1, Expression lwr, Expression upr) if (e1.op == EXP.string_ && lwr.op == EXP.int64 && upr.op == EXP.int64) { - StringExp es1 = cast(StringExp)e1; + StringExp es1 = e1.isStringExp(); const uinteger_t ilwr = lwr.toInteger(); const uinteger_t iupr = upr.toInteger(); if (sliceBoundsCheck(0, es1.len, ilwr, iupr)) @@ -1363,14 +1350,14 @@ UnionExp Slice(Type type, Expression e1, Expression lwr, Expression upr) const data1 = es1.peekData(); memcpy(s, data1.ptr + ilwr * sz, len * sz); emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz, es1.postfix); - StringExp es = cast(StringExp)ue.exp(); + StringExp es = ue.exp().isStringExp(); es.committed = es1.committed; es.type = type; } } else if (e1.op == EXP.arrayLiteral && lwr.op == EXP.int64 && upr.op == EXP.int64 && !hasSideEffect(e1)) { - ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1; + ArrayLiteralExp es1 = e1.isArrayLiteralExp(); const uinteger_t ilwr = lwr.toInteger(); const uinteger_t iupr = upr.toInteger(); if (sliceBoundsCheck(0, es1.elements.dim, ilwr, iupr)) @@ -1491,15 +1478,15 @@ private Expressions* copyElements(Expression e1, Expression e2 = null) } } - if (e1.op == EXP.arrayLiteral) - append(cast(ArrayLiteralExp)e1); + if (auto ale = e1.isArrayLiteralExp()) + append(ale); else elems.push(e1); if (e2) { - if (e2.op == EXP.arrayLiteral) - append(cast(ArrayLiteralExp)e2); + if (auto ale = e2.isArrayLiteralExp()) + append(ale); else elems.push(e2); } @@ -1544,7 +1531,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) else utf_encode(sz, s, cast(dchar)v); emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz); - StringExp es = cast(StringExp)ue.exp(); + StringExp es = ue.exp().isStringExp(); es.type = type; es.committed = 1; } @@ -1589,8 +1576,8 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) else if (e1.op == EXP.string_ && e2.op == EXP.string_) { // Concatenate the strings - StringExp es1 = cast(StringExp)e1; - StringExp es2 = cast(StringExp)e2; + StringExp es1 = e1.isStringExp(); + StringExp es2 = e2.isStringExp(); size_t len = es1.len + es2.len; ubyte sz = es1.sz; if (sz != es2.sz) @@ -1609,7 +1596,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) memcpy(cast(char*)s, data1.ptr, es1.len * sz); memcpy(cast(char*)s + es1.len * sz, data2.ptr, es2.len * sz); emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz); - StringExp es = cast(StringExp)ue.exp(); + StringExp es = ue.exp().isStringExp(); es.committed = es1.committed | es2.committed; es.type = type; assert(ue.exp().type); @@ -1618,8 +1605,8 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) else if (e2.op == EXP.string_ && e1.op == EXP.arrayLiteral && t1.nextOf().isintegral()) { // [chars] ~ string --> [chars] - StringExp es = cast(StringExp)e2; - ArrayLiteralExp ea = cast(ArrayLiteralExp)e1; + StringExp es = e2.isStringExp(); + ArrayLiteralExp ea = e1.isArrayLiteralExp(); size_t len = es.len + ea.elements.dim; auto elems = new Expressions(len); for (size_t i = 0; i < ea.elements.dim; ++i) @@ -1627,7 +1614,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) (*elems)[i] = ea[i]; } emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elems); - ArrayLiteralExp dest = cast(ArrayLiteralExp)ue.exp(); + ArrayLiteralExp dest = ue.exp().isArrayLiteralExp(); sliceAssignArrayLiteralFromString(dest, es, ea.elements.dim); assert(ue.exp().type); return ue; @@ -1635,8 +1622,8 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) else if (e1.op == EXP.string_ && e2.op == EXP.arrayLiteral && t2.nextOf().isintegral()) { // string ~ [chars] --> [chars] - StringExp es = cast(StringExp)e1; - ArrayLiteralExp ea = cast(ArrayLiteralExp)e2; + StringExp es = e1.isStringExp(); + ArrayLiteralExp ea = e2.isArrayLiteralExp(); size_t len = es.len + ea.elements.dim; auto elems = new Expressions(len); for (size_t i = 0; i < ea.elements.dim; ++i) @@ -1644,7 +1631,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) (*elems)[es.len + i] = ea[i]; } emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, type, elems); - ArrayLiteralExp dest = cast(ArrayLiteralExp)ue.exp(); + ArrayLiteralExp dest = ue.exp().isArrayLiteralExp(); sliceAssignArrayLiteralFromString(dest, es, 0); assert(ue.exp().type); return ue; @@ -1652,7 +1639,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) else if (e1.op == EXP.string_ && e2.op == EXP.int64) { // string ~ char --> string - StringExp es1 = cast(StringExp)e1; + StringExp es1 = e1.isStringExp(); StringExp es; const sz = es1.sz; dinteger_t v = e2.toInteger(); @@ -1668,7 +1655,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) else utf_encode(sz, cast(char*)s + (sz * es1.len), cast(dchar)v); emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz); - es = cast(StringExp)ue.exp(); + es = ue.exp().isStringExp(); es.committed = es1.committed; es.type = type; assert(ue.exp().type); @@ -1679,7 +1666,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) // [w|d]?char ~ string --> string // We assume that we only ever prepend one char of the same type // (wchar,dchar) as the string's characters. - StringExp es2 = cast(StringExp)e2; + StringExp es2 = e2.isStringExp(); const len = 1 + es2.len; const sz = es2.sz; dinteger_t v = e1.toInteger(); @@ -1688,7 +1675,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) const data2 = es2.peekData(); memcpy(cast(char*)s + sz, data2.ptr, data2.length); emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz); - StringExp es = cast(StringExp)ue.exp(); + StringExp es = ue.exp().isStringExp(); es.sz = sz; es.committed = es2.committed; es.type = type; @@ -1796,7 +1783,7 @@ UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2) } if (!e.type.equals(type)) { - StringExp se = cast(StringExp)e.copy(); + StringExp se = e.copy().isStringExp(); e = se.castTo(null, type); emplaceExp!(UnionExp)(&ue, e); e = ue.exp(); @@ -1812,23 +1799,21 @@ UnionExp Ptr(Type type, Expression e1) { //printf("Ptr(e1 = %s)\n", e1.toChars()); UnionExp ue = void; - if (e1.op == EXP.add) + if (AddExp ae = e1.isAddExp()) { - AddExp ae = cast(AddExp)e1; - if (ae.e1.op == EXP.address && ae.e2.op == EXP.int64) + if (AddrExp ade = ae.e1.isAddrExp()) { - AddrExp ade = cast(AddrExp)ae.e1; - if (ade.e1.op == EXP.structLiteral) - { - StructLiteralExp se = cast(StructLiteralExp)ade.e1; - uint offset = cast(uint)ae.e2.toInteger(); - Expression e = se.getField(type, offset); - if (e) + if (ae.e2.op == EXP.int64) + if (StructLiteralExp se = ade.e1.isStructLiteralExp()) { - emplaceExp!(UnionExp)(&ue, e); - return ue; + uint offset = cast(uint)ae.e2.toInteger(); + Expression e = se.getField(type, offset); + if (e) + { + emplaceExp!(UnionExp)(&ue, e); + return ue; + } } - } } } cantExp(ue); diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index fb52b63..bb12aa7 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -981,7 +981,12 @@ final class CParser(AST) : Parser!AST e = new AST.DotIdExp(loc, e, Id.__sizeof); break; } + // must be an expression + e = cparsePrimaryExp(); + e = new AST.DotIdExp(loc, e, Id.__sizeof); + break; } + e = cparseUnaryExp(); e = new AST.DotIdExp(loc, e, Id.__sizeof); break; @@ -1016,10 +1021,16 @@ final class CParser(AST) : Parser!AST { if (token.value == TOK.leftParenthesis) { + //printf("cparseCastExp()\n"); auto tk = peek(&token); - if (tk.value == TOK.identifier && - !isTypedef(tk.ident) && - peek(tk).value == TOK.rightParenthesis) + bool iscast; + bool isexp; + if (tk.value == TOK.identifier) + { + iscast = isTypedef(tk.ident); + isexp = !iscast; + } + if (isexp) { // ( identifier ) is an expression return cparseUnaryExp(); @@ -1045,9 +1056,18 @@ final class CParser(AST) : Parser!AST auto ce = new AST.CompoundLiteralExp(loc, t, ci); return cparsePostfixOperators(ce); } - else if (t.isTypeIdentifier() && - token.value == TOK.leftParenthesis && - !isCastExpression(pt)) + + if (iscast) + { + // ( type-name ) cast-expression + auto ce = cparseCastExp(); + return new AST.CastExp(loc, ce, t); + } + + if (t.isTypeIdentifier() && + isexp && + token.value == TOK.leftParenthesis && + !isCastExpression(pt)) { /* (t)(...)... might be a cast expression or a function call, * with different grammars: a cast would be cparseCastExp(), @@ -1061,12 +1081,10 @@ final class CParser(AST) : Parser!AST AST.Expression e = new AST.CallExp(loc, ie, cparseArguments()); return cparsePostfixOperators(e); } - else - { - // ( type-name ) cast-expression - auto ce = cparseCastExp(); - return new AST.CastExp(loc, ce, t); - } + + // ( type-name ) cast-expression + auto ce = cparseCastExp(); + return new AST.CastExp(loc, ce, t); } } return cparseUnaryExp(); @@ -1764,8 +1782,6 @@ final class CParser(AST) : Parser!AST symbols.push(stag); if (tt.tok == TOK.enum_) { - if (!stag.members) - error(tt.loc, "`enum %s` has no members", stag.toChars()); isalias = false; s = new AST.AliasDeclaration(token.loc, id, stag); } @@ -2382,7 +2398,19 @@ final class CParser(AST) : Parser!AST const idx = previd.toString(); if (idx.length > 2 && idx[0] == '_' && idx[1] == '_') // leading double underscore importBuiltins = true; // probably one of those compiler extensions - t = new AST.TypeIdentifier(loc, previd); + t = null; + if (scw & SCW.xtypedef) + { + /* Punch through to what the typedef is, to support things like: + * typedef T* T; + */ + auto pt = lookupTypedef(previd); + if (pt && *pt) // if previd is a known typedef + t = *pt; + } + + if (!t) + t = new AST.TypeIdentifier(loc, previd); break; } @@ -4767,7 +4795,8 @@ final class CParser(AST) : Parser!AST scan(&n); if (n.value == TOK.identifier && n.ident == Id.pack) return pragmaPack(loc); - skipToNextLine(); + if (n.value != TOK.endOfLine) + skipToNextLine(); } /********* @@ -4786,7 +4815,8 @@ final class CParser(AST) : Parser!AST if (n.value != TOK.leftParenthesis) { error(loc, "left parenthesis expected to follow `#pragma pack`"); - skipToNextLine(); + if (n.value != TOK.endOfLine) + skipToNextLine(); return; } @@ -4796,7 +4826,8 @@ final class CParser(AST) : Parser!AST { error(loc, "right parenthesis expected to close `#pragma pack(`"); } - skipToNextLine(); + if (n.value != TOK.endOfLine) + skipToNextLine(); } void setPackAlign(ref const Token t) @@ -4923,7 +4954,8 @@ final class CParser(AST) : Parser!AST } error(loc, "unrecognized `#pragma pack(%s)`", n.toChars()); - skipToNextLine(); + if (n.value != TOK.endOfLine) + skipToNextLine(); } //} diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d index 9078f90..32aed16 100644 --- a/gcc/d/dmd/ctfeexpr.d +++ b/gcc/d/dmd/ctfeexpr.d @@ -232,11 +232,11 @@ bool needToCopyLiteral(const Expression expr) switch (e.op) { case EXP.arrayLiteral: - return (cast(ArrayLiteralExp)e).ownedByCtfe == OwnedBy.code; + return e.isArrayLiteralExp().ownedByCtfe == OwnedBy.code; case EXP.assocArrayLiteral: - return (cast(AssocArrayLiteralExp)e).ownedByCtfe == OwnedBy.code; + return e.isAssocArrayLiteralExp().ownedByCtfe == OwnedBy.code; case EXP.structLiteral: - return (cast(StructLiteralExp)e).ownedByCtfe == OwnedBy.code; + return e.isStructLiteralExp().ownedByCtfe == OwnedBy.code; case EXP.string_: case EXP.this_: case EXP.variable: @@ -247,14 +247,14 @@ bool needToCopyLiteral(const Expression expr) case EXP.dotVariable: case EXP.slice: case EXP.cast_: - e = (cast(UnaExp)e).e1; + e = e.isUnaExp().e1; continue; case EXP.concatenate: - return needToCopyLiteral((cast(BinExp)e).e1) || needToCopyLiteral((cast(BinExp)e).e2); + return needToCopyLiteral(e.isBinExp().e1) || needToCopyLiteral(e.isBinExp().e2); case EXP.concatenateAssign: case EXP.concatenateElemAssign: case EXP.concatenateDcharAssign: - e = (cast(BinExp)e).e2; + e = e.isBinExp().e2; continue; default: return false; @@ -286,7 +286,7 @@ UnionExp copyLiteral(Expression e) const slice = se.peekData(); memcpy(s, slice.ptr, slice.length); emplaceExp!(StringExp)(&ue, se.loc, s[0 .. se.len * se.sz], se.len, se.sz); - StringExp se2 = cast(StringExp)ue.exp(); + StringExp se2 = ue.exp().isStringExp(); se2.committed = se.committed; se2.postfix = se.postfix; se2.type = se.type; @@ -299,14 +299,14 @@ UnionExp copyLiteral(Expression e) emplaceExp!(ArrayLiteralExp)(&ue, e.loc, e.type, elements); - ArrayLiteralExp r = cast(ArrayLiteralExp)ue.exp(); + ArrayLiteralExp r = ue.exp().isArrayLiteralExp(); r.ownedByCtfe = OwnedBy.ctfe; return ue; } if (auto aae = e.isAssocArrayLiteralExp()) { emplaceExp!(AssocArrayLiteralExp)(&ue, e.loc, copyLiteralArray(aae.keys), copyLiteralArray(aae.values)); - AssocArrayLiteralExp r = cast(AssocArrayLiteralExp)ue.exp(); + AssocArrayLiteralExp r = ue.exp().isAssocArrayLiteralExp(); r.type = e.type; r.ownedByCtfe = OwnedBy.ctfe; return ue; @@ -482,7 +482,7 @@ private UnionExp paintTypeOntoLiteralCopy(Type type, Expression lit) // just a ref to the keys and values. OwnedBy wasOwned = aae.ownedByCtfe; emplaceExp!(AssocArrayLiteralExp)(&ue, lit.loc, aae.keys, aae.values); - aae = cast(AssocArrayLiteralExp)ue.exp(); + aae = ue.exp().isAssocArrayLiteralExp(); aae.ownedByCtfe = wasOwned; } else @@ -526,7 +526,7 @@ Expression resolveSlice(Expression e, UnionExp* pue = null) * It's very wasteful to resolve the slice when we only * need the length. */ -uinteger_t resolveArrayLength(const Expression e) +uinteger_t resolveArrayLength(Expression e) { switch (e.op) { @@ -538,7 +538,7 @@ uinteger_t resolveArrayLength(const Expression e) case EXP.slice: { - auto se = cast(SliceExp)e; + auto se = e.isSliceExp(); const ilo = se.lwr.toInteger(); const iup = se.upr.toInteger(); return iup - ilo; @@ -720,16 +720,16 @@ Expression getAggregateFromPointer(Expression e, dinteger_t* ofs) *ofs = soe.offset; if (auto dve = e.isDotVarExp()) { - const ex = dve.e1; + auto ex = dve.e1; const v = dve.var.isVarDeclaration(); assert(v); StructLiteralExp se = (ex.op == EXP.classReference) - ? (cast(ClassReferenceExp)ex).value - : cast(StructLiteralExp)ex; + ? ex.isClassReferenceExp().value + : ex.isStructLiteralExp(); // We can't use getField, because it makes a copy const i = (ex.op == EXP.classReference) - ? (cast(ClassReferenceExp)ex).getFieldIndex(e.type, v.offset) + ? ex.isClassReferenceExp().getFieldIndex(e.type, v.offset) : se.getFieldIndex(e.type, v.offset); e = (*se.elements)[i]; } @@ -777,11 +777,11 @@ bool pointToSameMemoryBlock(Expression agg1, Expression agg2) } // Note that type painting can occur with VarExp, so we // must compare the variables being pointed to. - if (agg1.op == EXP.variable && agg2.op == EXP.variable && (cast(VarExp)agg1).var == (cast(VarExp)agg2).var) + if (agg1.op == EXP.variable && agg2.op == EXP.variable && agg1.isVarExp().var == agg2.isVarExp().var) { return true; } - if (agg1.op == EXP.symbolOffset && agg2.op == EXP.symbolOffset && (cast(SymOffExp)agg1).var == (cast(SymOffExp)agg2).var) + if (agg1.op == EXP.symbolOffset && agg2.op == EXP.symbolOffset && agg1.isSymOffExp().var == agg2.isSymOffExp().var) { return true; } @@ -801,14 +801,14 @@ Expression pointerDifference(UnionExp* pue, const ref Loc loc, Type type, Expres emplaceExp!(IntegerExp)(pue, loc, (ofs1 - ofs2) * sz, type); } else if (agg1.op == EXP.string_ && agg2.op == EXP.string_ && - (cast(StringExp)agg1).peekString().ptr == (cast(StringExp)agg2).peekString().ptr) + agg1.isStringExp().peekString().ptr == agg2.isStringExp().peekString().ptr) { Type pointee = (cast(TypePointer)agg1.type).next; const sz = pointee.size(); emplaceExp!(IntegerExp)(pue, loc, (ofs1 - ofs2) * sz, type); } else if (agg1.op == EXP.symbolOffset && agg2.op == EXP.symbolOffset && - (cast(SymOffExp)agg1).var == (cast(SymOffExp)agg2).var) + agg1.isSymOffExp().var == agg2.isSymOffExp().var) { emplaceExp!(IntegerExp)(pue, loc, ofs1 - ofs2, type); } @@ -832,12 +832,12 @@ Expression pointerArithmetic(UnionExp* pue, const ref Loc loc, EXP op, Type type return pue.exp(); } if (eptr.op == EXP.address) - eptr = (cast(AddrExp)eptr).e1; + eptr = eptr.isAddrExp().e1; dinteger_t ofs1; Expression agg1 = getAggregateFromPointer(eptr, &ofs1); if (agg1.op == EXP.symbolOffset) { - if ((cast(SymOffExp)agg1).var.type.ty != Tsarray) + if (agg1.isSymOffExp().var.type.ty != Tsarray) { error(loc, "cannot perform pointer arithmetic on arrays of unknown length at compile time"); goto Lcant; @@ -856,7 +856,7 @@ Expression pointerArithmetic(UnionExp* pue, const ref Loc loc, EXP op, Type type if (agg1.op == EXP.symbolOffset) { indx = ofs1 / sz; - len = (cast(TypeSArray)(cast(SymOffExp)agg1).var.type).dim.toInteger(); + len = (cast(TypeSArray)agg1.isSymOffExp().var.type).dim.toInteger(); } else { @@ -881,8 +881,8 @@ Expression pointerArithmetic(UnionExp* pue, const ref Loc loc, EXP op, Type type } if (agg1.op == EXP.symbolOffset) { - emplaceExp!(SymOffExp)(pue, loc, (cast(SymOffExp)agg1).var, indx * sz); - SymOffExp se = cast(SymOffExp)pue.exp(); + emplaceExp!(SymOffExp)(pue, loc, agg1.isSymOffExp().var, indx * sz); + SymOffExp se = pue.exp().isSymOffExp(); se.type = type; return pue.exp(); } @@ -1016,7 +1016,7 @@ Expression paintFloatInt(UnionExp* pue, Expression fromVal, Type to) bool isCtfeComparable(Expression e) { if (e.op == EXP.slice) - e = (cast(SliceExp)e).e1; + e = e.isSliceExp().e1; if (e.isConst() != 1) { if (e.op == EXP.null_ || e.op == EXP.string_ || e.op == EXP.function_ || e.op == EXP.delegate_ || e.op == EXP.arrayLiteral || e.op == EXP.structLiteral || e.op == EXP.assocArrayLiteral || e.op == EXP.classReference) @@ -1191,7 +1191,7 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide if (e1.op == EXP.classReference || e2.op == EXP.classReference) { if (e1.op == EXP.classReference && e2.op == EXP.classReference && - (cast(ClassReferenceExp)e1).value == (cast(ClassReferenceExp)e2).value) + e1.isClassReferenceExp().value == e2.isClassReferenceExp().value) return 0; return 1; } @@ -1199,8 +1199,8 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide { // printf("e1: %s\n", e1.toChars()); // printf("e2: %s\n", e2.toChars()); - Type t1 = isType((cast(TypeidExp)e1).obj); - Type t2 = isType((cast(TypeidExp)e2).obj); + Type t1 = isType(e1.isTypeidExp().obj); + Type t2 = isType(e2.isTypeidExp().obj); assert(t1); assert(t2); return t1 != t2; @@ -1214,7 +1214,7 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide dinteger_t ofs1, ofs2; Expression agg1 = getAggregateFromPointer(e1, &ofs1); Expression agg2 = getAggregateFromPointer(e2, &ofs2); - if ((agg1 == agg2) || (agg1.op == EXP.variable && agg2.op == EXP.variable && (cast(VarExp)agg1).var == (cast(VarExp)agg2).var)) + if ((agg1 == agg2) || (agg1.op == EXP.variable && agg2.op == EXP.variable && agg1.isVarExp().var == agg2.isVarExp().var)) { if (ofs1 == ofs2) return 0; @@ -1232,13 +1232,13 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide return 0; assert(e1.op == EXP.delegate_ && e2.op == EXP.delegate_); // Same .funcptr. Do they have the same .ptr? - Expression ptr1 = (cast(DelegateExp)e1).e1; - Expression ptr2 = (cast(DelegateExp)e2).e1; + Expression ptr1 = e1.isDelegateExp().e1; + Expression ptr2 = e2.isDelegateExp().e1; dinteger_t ofs1, ofs2; Expression agg1 = getAggregateFromPointer(ptr1, &ofs1); Expression agg2 = getAggregateFromPointer(ptr2, &ofs2); // If they are EXP.variable, it means they are FuncDeclarations - if ((agg1 == agg2 && ofs1 == ofs2) || (agg1.op == EXP.variable && agg2.op == EXP.variable && (cast(VarExp)agg1).var == (cast(VarExp)agg2).var)) + if ((agg1 == agg2 && ofs1 == ofs2) || (agg1.op == EXP.variable && agg2.op == EXP.variable && agg1.isVarExp().var == agg2.isVarExp().var)) { return 0; } @@ -1291,8 +1291,8 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide } if (e1.op == EXP.structLiteral && e2.op == EXP.structLiteral) { - StructLiteralExp es1 = cast(StructLiteralExp)e1; - StructLiteralExp es2 = cast(StructLiteralExp)e2; + StructLiteralExp es1 = e1.isStructLiteralExp(); + StructLiteralExp es2 = e2.isStructLiteralExp(); // For structs, we only need to return 0 or 1 (< and > aren't legal). if (es1.sd != es2.sd) return 1; @@ -1326,8 +1326,8 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide } if (e1.op == EXP.assocArrayLiteral && e2.op == EXP.assocArrayLiteral) { - AssocArrayLiteralExp es1 = cast(AssocArrayLiteralExp)e1; - AssocArrayLiteralExp es2 = cast(AssocArrayLiteralExp)e2; + AssocArrayLiteralExp es1 = e1.isAssocArrayLiteralExp(); + AssocArrayLiteralExp es2 = e2.isAssocArrayLiteralExp(); size_t dim = es1.keys.dim; if (es2.keys.dim != dim) return 1; @@ -1394,8 +1394,8 @@ bool ctfeIdentity(const ref Loc loc, EXP op, Expression e1, Expression e2) } else if (e1.op == EXP.symbolOffset && e2.op == EXP.symbolOffset) { - SymOffExp es1 = cast(SymOffExp)e1; - SymOffExp es2 = cast(SymOffExp)e2; + SymOffExp es1 = e1.isSymOffExp(); + SymOffExp es2 = e2.isSymOffExp(); cmp = (es1.var == es2.var && es1.offset == es2.offset); } else if (e1.type.isreal()) @@ -1443,8 +1443,8 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2) if (e2.op == EXP.string_ && e1.op == EXP.arrayLiteral && t1.nextOf().isintegral()) { // [chars] ~ string => string (only valid for CTFE) - StringExp es1 = cast(StringExp)e2; - ArrayLiteralExp es2 = cast(ArrayLiteralExp)e1; + StringExp es1 = e2.isStringExp(); + ArrayLiteralExp es2 = e1.isArrayLiteralExp(); const len = es1.len + es2.elements.dim; const sz = es1.sz; void* s = mem.xmalloc((len + 1) * sz); @@ -1464,7 +1464,7 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2) // Add terminating 0 memset(cast(char*)s + len * sz, 0, sz); emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz); - StringExp es = cast(StringExp)ue.exp(); + StringExp es = ue.exp().isStringExp(); es.committed = 0; es.type = type; return ue; @@ -1473,8 +1473,8 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2) { // string ~ [chars] => string (only valid for CTFE) // Concatenate the strings - StringExp es1 = cast(StringExp)e1; - ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; + StringExp es1 = e1.isStringExp(); + ArrayLiteralExp es2 = e2.isArrayLiteralExp(); const len = es1.len + es2.elements.dim; const sz = es1.sz; void* s = mem.xmalloc((len + 1) * sz); @@ -1494,7 +1494,7 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2) // Add terminating 0 memset(cast(char*)s + len * sz, 0, sz); emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz); - StringExp es = cast(StringExp)ue.exp(); + StringExp es = ue.exp().isStringExp(); es.sz = sz; es.committed = 0; //es1.committed; es.type = type; @@ -1503,10 +1503,10 @@ UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2) if (e1.op == EXP.arrayLiteral && e2.op == EXP.arrayLiteral && t1.nextOf().equals(t2.nextOf())) { // [ e1 ] ~ [ e2 ] ---> [ e1, e2 ] - ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1; - ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; + ArrayLiteralExp es1 = e1.isArrayLiteralExp(); + ArrayLiteralExp es2 = e2.isArrayLiteralExp(); emplaceExp!(ArrayLiteralExp)(&ue, es1.loc, type, copyLiteralArray(es1.elements)); - es1 = cast(ArrayLiteralExp)ue.exp(); + es1 = ue.exp().isArrayLiteralExp(); es1.elements.insert(es1.elements.dim, copyLiteralArray(es2.elements)); return ue; } @@ -1594,7 +1594,7 @@ Expression ctfeCast(UnionExp* pue, const ref Loc loc, Type type, Type to, Expres // Disallow reinterpreting class casts. Do this by ensuring that // the original class can implicitly convert to the target class. // Also do not check 'alias this' for explicit cast expressions. - auto tclass = (cast(ClassReferenceExp)e).originalClass().type.isTypeClass(); + auto tclass = e.isClassReferenceExp().originalClass().type.isTypeClass(); auto match = explicitCast ? tclass.implicitConvToWithoutAliasThis(to.mutableOf()) : tclass.implicitConvTo(to.mutableOf()); if (match) @@ -1665,9 +1665,9 @@ void assignInPlace(Expression dest, Expression src) if (dest.op == EXP.structLiteral) { assert(dest.op == src.op); - oldelems = (cast(StructLiteralExp)dest).elements; - newelems = (cast(StructLiteralExp)src).elements; - auto sd = (cast(StructLiteralExp)dest).sd; + oldelems = dest.isStructLiteralExp().elements; + newelems = src.isStructLiteralExp().elements; + auto sd = dest.isStructLiteralExp().sd; const nfields = sd.nonHiddenFields(); const nvthis = sd.fields.dim - nfields; if (nvthis && oldelems.dim >= nfields && oldelems.dim < newelems.dim) @@ -1676,22 +1676,22 @@ void assignInPlace(Expression dest, Expression src) } else if (dest.op == EXP.arrayLiteral && src.op == EXP.arrayLiteral) { - oldelems = (cast(ArrayLiteralExp)dest).elements; - newelems = (cast(ArrayLiteralExp)src).elements; + oldelems = dest.isArrayLiteralExp().elements; + newelems = src.isArrayLiteralExp().elements; } else if (dest.op == EXP.string_ && src.op == EXP.string_) { - sliceAssignStringFromString(cast(StringExp)dest, cast(StringExp)src, 0); + sliceAssignStringFromString(dest.isStringExp(), src.isStringExp(), 0); return; } else if (dest.op == EXP.arrayLiteral && src.op == EXP.string_) { - sliceAssignArrayLiteralFromString(cast(ArrayLiteralExp)dest, cast(StringExp)src, 0); + sliceAssignArrayLiteralFromString(dest.isArrayLiteralExp(), src.isStringExp(), 0); return; } else if (src.op == EXP.arrayLiteral && dest.op == EXP.string_) { - sliceAssignStringFromArrayLiteral(cast(StringExp)dest, cast(ArrayLiteralExp)src, 0); + sliceAssignStringFromArrayLiteral(dest.isStringExp(), src.isArrayLiteralExp(), 0); return; } else @@ -1761,13 +1761,13 @@ Expression changeArrayLiteralLength(UnionExp* pue, const ref Loc loc, TypeArray size_t indxlo = 0; if (oldval.op == EXP.slice) { - indxlo = cast(size_t)(cast(SliceExp)oldval).lwr.toInteger(); - oldval = (cast(SliceExp)oldval).e1; + indxlo = cast(size_t)oldval.isSliceExp().lwr.toInteger(); + oldval = oldval.isSliceExp().e1; } size_t copylen = oldlen < newlen ? oldlen : newlen; if (oldval.op == EXP.string_) { - StringExp oldse = cast(StringExp)oldval; + StringExp oldse = oldval.isStringExp(); void* s = mem.xcalloc(newlen + 1, oldse.sz); const data = oldse.peekData(); memcpy(s, data.ptr, copylen * oldse.sz); @@ -1790,7 +1790,7 @@ Expression changeArrayLiteralLength(UnionExp* pue, const ref Loc loc, TypeArray } } emplaceExp!(StringExp)(pue, loc, s[0 .. newlen * oldse.sz], newlen, oldse.sz); - StringExp se = cast(StringExp)pue.exp(); + StringExp se = pue.exp().isStringExp(); se.type = arrayType; se.sz = oldse.sz; se.committed = oldse.committed; @@ -1801,7 +1801,7 @@ Expression changeArrayLiteralLength(UnionExp* pue, const ref Loc loc, TypeArray if (oldlen != 0) { assert(oldval.op == EXP.arrayLiteral); - ArrayLiteralExp ae = cast(ArrayLiteralExp)oldval; + ArrayLiteralExp ae = oldval.isArrayLiteralExp(); foreach (size_t i; 0 .. copylen) (*elements)[i] = (*ae.elements)[indxlo + i]; } @@ -1819,7 +1819,7 @@ Expression changeArrayLiteralLength(UnionExp* pue, const ref Loc loc, TypeArray (*elements)[i] = defaultElem; } emplaceExp!(ArrayLiteralExp)(pue, loc, arrayType, elements); - ArrayLiteralExp aae = cast(ArrayLiteralExp)pue.exp(); + ArrayLiteralExp aae = pue.exp().isArrayLiteralExp(); aae.ownedByCtfe = OwnedBy.ctfe; } return pue.exp(); @@ -1874,14 +1874,14 @@ bool isCtfeValueValid(Expression newval) { // &struct.func or &clasinst.func // &nestedfunc - Expression ethis = (cast(DelegateExp)newval).e1; - return (ethis.op == EXP.structLiteral || ethis.op == EXP.classReference || ethis.op == EXP.variable && (cast(VarExp)ethis).var == (cast(DelegateExp)newval).func); + Expression ethis = newval.isDelegateExp().e1; + return (ethis.op == EXP.structLiteral || ethis.op == EXP.classReference || ethis.op == EXP.variable && ethis.isVarExp().var == newval.isDelegateExp().func); } case EXP.symbolOffset: { // function pointer, or pointer to static variable - Declaration d = (cast(SymOffExp)newval).var; + Declaration d = newval.isSymOffExp().var; return d.isFuncDeclaration() || d.isDataseg(); } @@ -1894,7 +1894,7 @@ bool isCtfeValueValid(Expression newval) case EXP.address: { // e1 should be a CTFE reference - Expression e1 = (cast(AddrExp)newval).e1; + Expression e1 = newval.isAddrExp().e1; return tb.ty == Tpointer && ( (e1.op == EXP.structLiteral || e1.op == EXP.arrayLiteral) && isCtfeValueValid(e1) || @@ -1908,7 +1908,7 @@ bool isCtfeValueValid(Expression newval) case EXP.slice: { // e1 should be an array aggregate - const SliceExp se = cast(SliceExp)newval; + const SliceExp se = newval.isSliceExp(); assert(se.lwr && se.lwr.op == EXP.int64); assert(se.upr && se.upr.op == EXP.int64); return (tb.ty == Tarray || tb.ty == Tsarray) && (se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral); @@ -1932,7 +1932,7 @@ bool isCtfeReferenceValid(Expression newval) case EXP.variable: { - const VarDeclaration v = (cast(VarExp)newval).var.isVarDeclaration(); + const VarDeclaration v = newval.isVarExp().var.isVarDeclaration(); assert(v); // Must not be a reference to a reference return true; @@ -1940,13 +1940,13 @@ bool isCtfeReferenceValid(Expression newval) case EXP.index: { - const Expression eagg = (cast(IndexExp)newval).e1; + const Expression eagg = newval.isIndexExp().e1; return eagg.op == EXP.string_ || eagg.op == EXP.arrayLiteral || eagg.op == EXP.assocArrayLiteral; } case EXP.dotVariable: { - Expression eagg = (cast(DotVarExp)newval).e1; + Expression eagg = newval.isDotVarExp().e1; return (eagg.op == EXP.structLiteral || eagg.op == EXP.classReference) && isCtfeValueValid(eagg); } @@ -1968,19 +1968,19 @@ void showCtfeExpr(Expression e, int level = 0) ClassDeclaration cd = null; if (e.op == EXP.structLiteral) { - elements = (cast(StructLiteralExp)e).elements; - sd = (cast(StructLiteralExp)e).sd; + elements = e.isStructLiteralExp().elements; + sd = e.isStructLiteralExp().sd; printf("STRUCT type = %s %p:\n", e.type.toChars(), e); } else if (e.op == EXP.classReference) { - elements = (cast(ClassReferenceExp)e).value.elements; - cd = (cast(ClassReferenceExp)e).originalClass(); - printf("CLASS type = %s %p:\n", e.type.toChars(), (cast(ClassReferenceExp)e).value); + elements = e.isClassReferenceExp().value.elements; + cd = e.isClassReferenceExp().originalClass(); + printf("CLASS type = %s %p:\n", e.type.toChars(), e.isClassReferenceExp().value); } else if (e.op == EXP.arrayLiteral) { - elements = (cast(ArrayLiteralExp)e).elements; + elements = e.isArrayLiteralExp().elements; printf("ARRAY LITERAL type=%s %p:\n", e.type.toChars(), e); } else if (e.op == EXP.assocArrayLiteral) @@ -1994,19 +1994,19 @@ void showCtfeExpr(Expression e, int level = 0) else if (e.op == EXP.slice) { printf("SLICE %p: %s\n", e, e.toChars()); - showCtfeExpr((cast(SliceExp)e).e1, level + 1); + showCtfeExpr(e.isSliceExp().e1, level + 1); } else if (e.op == EXP.variable) { printf("VAR %p %s\n", e, e.toChars()); - VarDeclaration v = (cast(VarExp)e).var.isVarDeclaration(); + VarDeclaration v = e.isVarExp().var.isVarDeclaration(); if (v && getValue(v)) showCtfeExpr(getValue(v), level + 1); } else if (e.op == EXP.address) { // This is potentially recursive. We mustn't try to print the thing we're pointing to. - printf("POINTER %p to %p: %s\n", e, (cast(AddrExp)e).e1, e.toChars()); + printf("POINTER %p to %p: %s\n", e, e.isAddrExp().e1, e.toChars()); } else printf("VALUE %p: %s\n", e, e.toChars()); @@ -2086,7 +2086,7 @@ UnionExp voidInitLiteral(Type t, VarDeclaration var) (*elements)[i] = elem; } emplaceExp!(ArrayLiteralExp)(&ue, var.loc, tsa, elements); - ArrayLiteralExp ae = cast(ArrayLiteralExp)ue.exp(); + ArrayLiteralExp ae = ue.exp().isArrayLiteralExp(); ae.ownedByCtfe = OwnedBy.ctfe; } else if (t.ty == Tstruct) @@ -2098,7 +2098,7 @@ UnionExp voidInitLiteral(Type t, VarDeclaration var) (*exps)[i] = voidInitLiteral(ts.sym.fields[i].type, ts.sym.fields[i]).copy(); } emplaceExp!(StructLiteralExp)(&ue, var.loc, ts.sym, exps); - StructLiteralExp se = cast(StructLiteralExp)ue.exp(); + StructLiteralExp se = ue.exp().isStructLiteralExp(); se.type = ts; se.ownedByCtfe = OwnedBy.ctfe; } diff --git a/gcc/d/dmd/ctorflow.d b/gcc/d/dmd/ctorflow.d index cc251b0..c04793d 100644 --- a/gcc/d/dmd/ctorflow.d +++ b/gcc/d/dmd/ctorflow.d @@ -222,4 +222,3 @@ bool mergeFieldInit(ref CSX a, const CSX b) pure nothrow } return ok; } - diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 887bb89..685987b 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -3880,4 +3880,3 @@ IntRange getIntRange(Expression e) case EXP.negate : return visitNeg(e.isNegExp()); } } - diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index 82a5f3b..c0e40a5 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -292,7 +292,7 @@ extern (C++) abstract class Declaration : Dsymbol * postblit. Print the first field that has * a disabled postblit. */ - if (postblit.generated) + if (postblit.isGenerated()) { auto sd = p.isStructDeclaration(); assert(sd); @@ -334,7 +334,7 @@ extern (C++) abstract class Declaration : Dsymbol if (auto ctor = isCtorDeclaration()) { - if (ctor.isCpCtor && ctor.generated) + if (ctor.isCpCtor && ctor.isGenerated()) { .error(loc, "Generating an `inout` copy constructor for `struct %s` failed, therefore instances of it are uncopyable", parent.toPrettyChars()); return true; @@ -1060,24 +1060,51 @@ extern (C++) class VarDeclaration : Declaration enum AdrOnStackNone = ~0u; uint ctfeAdrOnStack; - bool isargptr; // if parameter that _argptr points to - bool ctorinit; // it has been initialized in a ctor - bool iscatchvar; // this is the exception object variable in catch() clause - bool isowner; // this is an Owner, despite it being `scope` - bool setInCtorOnly; // field can only be set in a constructor, as it is const or immutable + // `bool` fields that are compacted into bit fields in a string mixin + private extern (D) static struct BitFields + { + bool isargptr; /// if parameter that _argptr points to + bool ctorinit; /// it has been initialized in a ctor + bool iscatchvar; /// this is the exception object variable in catch() clause + bool isowner; /// this is an Owner, despite it being `scope` + bool setInCtorOnly; /// field can only be set in a constructor, as it is const or immutable + + /// It is a class that was allocated on the stack + /// + /// This means the var is not rebindable once assigned, + /// and the destructor gets run when it goes out of scope + bool onstack; - // Both these mean the var is not rebindable once assigned, - // and the destructor gets run when it goes out of scope - bool onstack; // it is a class that was allocated on the stack + bool overlapped; /// if it is a field and has overlapping + bool overlapUnsafe; /// if it is an overlapping field and the overlaps are unsafe + bool doNotInferScope; /// do not infer 'scope' for this variable + bool doNotInferReturn; /// do not infer 'return' for this variable + + bool isArgDtorVar; /// temporary created to handle scope destruction of a function argument + } + private ushort bitFields; // stores multiple booleans for BitFields byte canassign; // it can be assigned to - bool overlapped; // if it is a field and has overlapping - bool overlapUnsafe; // if it is an overlapping field and the overlaps are unsafe - bool doNotInferScope; // do not infer 'scope' for this variable - bool doNotInferReturn; // do not infer 'return' for this variable ubyte isdataseg; // private data for isDataseg 0 unset, 1 true, 2 false - bool isArgDtorVar; // temporary created to handle scope destruction of a function argument + // Generate getter and setter functions for `bitFields` + extern (D) mixin(() { + string result = "extern (C++) pure nothrow @nogc @safe final {"; + foreach (size_t i, mem; __traits(allMembers, BitFields)) + { + result ~= " + /// set or get the corresponding BitFields member + bool "~mem~"() const { return !!(bitFields & (1 << "~i.stringof~")); } + /// ditto + bool "~mem~"(bool v) + { + v ? (bitFields |= (1 << "~i.stringof~")) : (bitFields &= ~(1 << "~i.stringof~")); + return v; + }"; + } + return result ~ "}"; + }()); + final extern (D) this(const ref Loc loc, Type type, Identifier ident, Initializer _init, StorageClass storage_class = STC.undefined_) in @@ -1642,64 +1669,6 @@ extern (C++) class VarDeclaration : Declaration { v.visit(this); } - - /********************************** - * Determine if `this` has a lifetime that lasts past - * the destruction of `v` - * Params: - * v = variable to test against - * Returns: - * true if it does - */ - final bool enclosesLifetimeOf(VarDeclaration v) const pure - { - // VarDeclaration's with these STC's need special treatment - enum special = STC.temp | STC.foreach_; - - // Sequence numbers work when there are no special VarDeclaration's involved - if (!((this.storage_class | v.storage_class) & special)) - { - assert(this.sequenceNumber != this.sequenceNumber.init); - assert(v.sequenceNumber != v.sequenceNumber.init); - - return (this.sequenceNumber < v.sequenceNumber); - } - - // Assume that semantic produces temporaries according to their lifetime - // (It won't create a temporary before the actual content) - if ((this.storage_class & special) && (v.storage_class & special)) - return this.sequenceNumber < v.sequenceNumber; - - // Fall back to lexical order - assert(this.loc != Loc.initial); - assert(v.loc != Loc.initial); - - if (this.loc.linnum != v.loc.linnum) - return this.loc.linnum < v.loc.linnum; - - if (this.loc.charnum != v.loc.charnum) - return this.loc.charnum < v.loc.charnum; - - // Default fallback - return this.sequenceNumber < v.sequenceNumber; - } - - /*************************************** - * Add variable to maybes[]. - * When a maybescope variable `v` is assigned to a maybescope variable `this`, - * we cannot determine if `this` is actually scope until the semantic - * analysis for the function is completed. Thus, we save the data - * until then. - * Params: - * v = an STC.maybescope variable that was assigned to `this` - */ - final void addMaybe(VarDeclaration v) - { - //printf("add %s to %s's list of dependencies\n", v.toChars(), toChars()); - if (!maybes) - maybes = new VarDeclarations(); - maybes.push(v); - } } /******************************************************* diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index 9986ea3..441a966 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -241,22 +241,33 @@ public: // When interpreting, these point to the value (NULL if value not determinable) // The index of this variable on the CTFE stack, ~0u if not allocated unsigned ctfeAdrOnStack; - - bool isargptr; // if parameter that _argptr points to - bool ctorinit; // it has been initialized in a ctor - bool iscatchvar; // this is the exception object variable in catch() clause - bool isowner; // this is an Owner, despite it being `scope` - bool setInCtorOnly; // field can only be set in a constructor, as it is const or immutable - bool onstack; // it is a class that was allocated on the stack - char canassign; // it can be assigned to - bool overlapped; // if it is a field and has overlapping - bool overlapUnsafe; // if it is an overlapping field and the overlaps are unsafe - bool doNotInferScope; // do not infer 'scope' for this variable - bool doNotInferReturn; // do not infer 'return' for this variable - unsigned char isdataseg; // private data for isDataseg - bool isArgDtorVar; // temporary created to handle scope destruction of a function argument - -public: +private: + uint16_t bitFields; +public: + int8_t canassign; // // it can be assigned to + uint8_t isdataseg; // private data for isDataseg + bool isargptr() const; // if parameter that _argptr points to + bool isargptr(bool v); + bool ctorinit() const; // it has been initialized in a ctor + bool ctorinit(bool v); + bool iscatchvar() const; // this is the exception object variable in catch() clause + bool iscatchvar(bool v); + bool isowner() const; // this is an Owner, despite it being `scope` + bool isowner(bool v); + bool setInCtorOnly() const; // field can only be set in a constructor, as it is const or immutable + bool setInCtorOnly(bool v); + bool onstack() const; // it is a class that was allocated on the stack + bool onstack(bool v); + bool overlapped() const; // if it is a field and has overlapping + bool overlapped(bool v); + bool overlapUnsafe() const; // if it is an overlapping field and the overlaps are unsafe + bool overlapUnsafe(bool v); + bool doNotInferScope() const; // do not infer 'scope' for this variable + bool doNotInferScope(bool v); + bool doNotInferReturn() const; // do not infer 'return' for this variable + bool doNotInferReturn(bool v); + bool isArgDtorVar() const; // temporary created to handle scope destruction of a function argument + bool isArgDtorVar(bool v); static VarDeclaration *create(const Loc &loc, Type *t, Identifier *id, Initializer *init, StorageClass storage_class = STCundefined); VarDeclaration *syntaxCopy(Dsymbol *); void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion); @@ -273,7 +284,6 @@ public: bool hasPointers(); bool canTakeAddressOf(); bool needsScopeDtor(); - bool enclosesLifetimeOf(VarDeclaration *v) const; void checkCtorConstInit(); Dsymbol *toAlias(); // Eliminate need for dynamic_cast @@ -541,7 +551,6 @@ public: // scopes from having the same name DsymbolTable *localsymtab; VarDeclaration *vthis; // 'this' parameter (member and nested) - bool isThis2; // has a dual-context 'this' parameter VarDeclaration *v_arguments; // '_arguments' parameter VarDeclaration *v_argptr; // '_argptr' variable @@ -551,29 +560,20 @@ public: FuncDeclaration *overnext0; // next in overload list (only used during IFTI) Loc endloc; // location of closing curly bracket int vtblIndex; // for member functions, index into vtbl[] - bool naked; // true if naked - bool generated; // true if function was generated by the compiler rather than - // supplied by the user - bool hasAlwaysInlines; // contains references to functions that must be inlined - unsigned char isCrtCtorDtor; // has attribute pragma(crt_constructor(1)/crt_destructor(2)) - // not set before the glue layer + ILS inlineStatusStmt; ILS inlineStatusExp; PINLINE inlining; int inlineNest; // !=0 if nested inline - bool eh_none; /// true if no exception unwinding is needed // true if errors in semantic3 this function's frame ptr - bool semantic3Errors; ForeachStatement *fes; // if foreach body, this is the foreach BaseClass* interfaceVirtual; // if virtual, but only appears in interface vtbl[] - bool introducing; // true if 'introducing' function // if !=NULL, then this is the type // of the 'introducing' function // this one is overriding Type *tintro; - bool inferRetType; // true if return type is to be inferred StorageClass storage_class2; // storage class for template onemember's // Things that should really go into Scope @@ -585,8 +585,6 @@ public: // 16 if there are multiple return statements int hasReturnExp; - // Support for NRVO (named return value optimization) - bool nrvo_can; // true means we can do it VarDeclaration *nrvo_var; // variable to replace with shidden Symbol *shidden; // hidden pointer passed to function @@ -654,6 +652,19 @@ public: bool isNogc(); bool isNogcBypassingInference(); + bool isNRVO() const; + void isNRVO(bool v); + bool isNaked() const; + bool isGenerated() const; + void isGenerated(bool v); + bool isIntroducing() const; + bool hasSemantic3Errors() const; + bool hasNoEH() const; + bool inferRetType() const; + bool hasDualContext() const; + bool hasAlwaysInlines() const; + bool isCrtCtor() const; + bool isCrtDtor() const; virtual bool isNested() const; AggregateDeclaration *isThis(); diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d index 90e48f8..aba290b 100644 --- a/gcc/d/dmd/denum.d +++ b/gcc/d/dmd/denum.d @@ -96,7 +96,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol override void setScope(Scope* sc) { - if (semanticRun > PASS.init) + if (semanticRun > PASS.initial) return; ScopeDsymbol.setScope(sc); } @@ -163,6 +163,9 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol if (defaultval) return defaultval; + if (isCsymbol()) + return memtype.defaultInit(loc, true); + if (_scope) dsymbolSemantic(this, _scope); if (errors) diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index 30a8a44..3cfc07a 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -535,7 +535,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta istatex.caller = istate; istatex.fd = fd; - if (fd.isThis2) + if (fd.hasDualContext()) { Expression arg0 = thisarg; if (arg0 && arg0.type.ty == Tstruct) @@ -678,7 +678,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta e = CTFEExp.voidexp; if (tf.isref && e.op == EXP.variable && e.isVarExp().var == fd.vthis) e = thisarg; - if (tf.isref && fd.isThis2 && e.op == EXP.index) + if (tf.isref && fd.hasDualContext() && e.op == EXP.index) { auto ie = e.isIndexExp(); auto pe = ie.e1.isPtrExp(); @@ -944,7 +944,7 @@ public: if (auto eaddr = e.isAddrExp()) x = eaddr.e1; VarDeclaration v; - while (x.op == EXP.variable && (v = (cast(VarExp)x).var.isVarDeclaration()) !is null) + while (x.op == EXP.variable && (v = x.isVarExp().var.isVarDeclaration()) !is null) { if (v.storage_class & STC.ref_) { @@ -1526,7 +1526,7 @@ public: } while ((*boss.value.elements)[next].op == EXP.classReference) { - boss = cast(ClassReferenceExp)(*boss.value.elements)[next]; + boss = (*boss.value.elements)[next].isClassReferenceExp(); } (*boss.value.elements)[next] = collateral; return oldest; @@ -1752,7 +1752,7 @@ public: if (istate && istate.fd.vthis) { result = ctfeEmplaceExp!VarExp(e.loc, istate.fd.vthis); - if (istate.fd.isThis2) + if (istate.fd.hasDualContext()) { result = ctfeEmplaceExp!PtrExp(e.loc, result); result.type = Type.tvoidptr.sarrayOf(2); @@ -1768,15 +1768,15 @@ public: result = ctfeGlobals.stack.getThis(); if (result) { - if (istate && istate.fd.isThis2) + if (istate && istate.fd.hasDualContext()) { assert(result.op == EXP.address); - result = (cast(AddrExp)result).e1; + result = result.isAddrExp().e1; assert(result.op == EXP.arrayLiteral); - result = (*(cast(ArrayLiteralExp)result).elements)[0]; + result = (*result.isArrayLiteralExp().elements)[0]; if (e.type.ty == Tstruct) { - result = (cast(AddrExp)result).e1; + result = result.isAddrExp().e1; } return; } @@ -1873,7 +1873,9 @@ public: { fromType = (cast(TypeArray)e.var.type).next; } - if (e.var.isDataseg() && ((e.offset == 0 && isSafePointerCast(e.var.type, pointee)) || (fromType && isSafePointerCast(fromType, pointee)))) + if (e.var.isDataseg() && ((e.offset == 0 && isSafePointerCast(e.var.type, pointee)) || + (fromType && isSafePointerCast(fromType, pointee)) || + (e.var.isCsymbol() && e.offset + pointee.size() <= e.var.type.size()))) { result = e; return; @@ -1980,7 +1982,7 @@ public: if (decl.isDataseg()) { // Normally this is already done by optimize() // Do it here in case optimize(WANTvalue) wasn't run before CTFE - emplaceExp!(SymOffExp)(pue, e.loc, (cast(VarExp)e.e1).var, 0); + emplaceExp!(SymOffExp)(pue, e.loc, e.e1.isVarExp().var, 0); result = pue.exp(); result.type = e.type; return; @@ -2399,7 +2401,7 @@ public: return; } - ClassDeclaration cd = (cast(ClassReferenceExp)result).originalClass(); + ClassDeclaration cd = result.isClassReferenceExp().originalClass(); assert(cd); emplaceExp!(TypeidExp)(pue, e.loc, cd.type); @@ -2487,7 +2489,7 @@ public: else { // segfault bug 6250 - assert(exp.op != EXP.index || (cast(IndexExp)exp).e1 != e); + assert(exp.op != EXP.index || exp.isIndexExp().e1 != e); ex = interpretRegion(exp, istate); if (exceptionOrCant(ex)) @@ -2521,7 +2523,7 @@ public: return; } emplaceExp!(ArrayLiteralExp)(pue, e.loc, e.type, basis, expsx); - auto ale = cast(ArrayLiteralExp)pue.exp(); + auto ale = pue.exp().isArrayLiteralExp(); ale.ownedByCtfe = OwnedBy.ctfe; result = ale; } @@ -2705,7 +2707,7 @@ public: return; } emplaceExp!(StructLiteralExp)(pue, e.loc, e.sd, expsx); - auto sle = cast(StructLiteralExp)pue.exp(); + auto sle = pue.exp().isStructLiteralExp(); sle.type = e.type; sle.ownedByCtfe = OwnedBy.ctfe; sle.origin = e.origin; @@ -2737,7 +2739,7 @@ public: foreach (ref element; *elements) element = copyLiteral(elem).copy(); emplaceExp!(ArrayLiteralExp)(pue, loc, newtype, elements); - auto ae = cast(ArrayLiteralExp)pue.exp(); + auto ae = pue.exp().isArrayLiteralExp(); ae.ownedByCtfe = OwnedBy.ctfe; return ae; } @@ -2959,7 +2961,7 @@ public: result = e; // optimize: reuse this CTFE reference else { - auto edt = cast(DotTypeExp)e.copy(); + auto edt = e.copy().isDotTypeExp(); edt.e1 = (e1 == ue.exp()) ? e1.copy() : e1; // don't return pointer to ue result = edt; } @@ -3335,7 +3337,7 @@ public: if (exceptionOrCant(newval)) return; - VarDeclaration v = (cast(VarExp)e1).var.isVarDeclaration(); + VarDeclaration v = e1.isVarExp().var.isVarDeclaration(); setValue(v, newval); // Get the value to return. Note that 'newval' is an Lvalue, @@ -3351,7 +3353,7 @@ public: { while (e1.op == EXP.cast_) { - CastExp ce = cast(CastExp)e1; + CastExp ce = e1.isCastExp(); e1 = ce.e1; } } @@ -3362,7 +3364,7 @@ public: AssocArrayLiteralExp existingAA = null; Expression lastIndex = null; Expression oldval = null; - if (e1.op == EXP.index && (cast(IndexExp)e1).e1.type.toBasetype().ty == Taarray) + if (e1.op == EXP.index && e1.isIndexExp().e1.type.toBasetype().ty == Taarray) { // --------------------------------------- // Deal with AA index assignment @@ -3374,12 +3376,12 @@ public: * (2) If the ultimate AA is null, no insertion happens at all. Instead, * we create nested AA literals, and change it into a assignment. */ - IndexExp ie = cast(IndexExp)e1; + IndexExp ie = e1.isIndexExp(); int depth = 0; // how many nested AA indices are there? - while (ie.e1.op == EXP.index && (cast(IndexExp)ie.e1).e1.type.toBasetype().ty == Taarray) + while (ie.e1.op == EXP.index && ie.e1.isIndexExp().e1.type.toBasetype().ty == Taarray) { assert(ie.modifiable); - ie = cast(IndexExp)ie.e1; + ie = ie.e1.isIndexExp(); ++depth; } @@ -3392,7 +3394,7 @@ public: // Normal case, ultimate parent AA already exists // We need to walk from the deepest index up, checking that an AA literal // already exists on each level. - lastIndex = interpretRegion((cast(IndexExp)e1).e2, istate); + lastIndex = interpretRegion(e1.isIndexExp().e2, istate); lastIndex = resolveSlice(lastIndex); // only happens with AA assignment if (exceptionOrCant(lastIndex)) return; @@ -3400,9 +3402,9 @@ public: while (depth > 0) { // Walk the syntax tree to find the indexExp at this depth - IndexExp xe = cast(IndexExp)e1; + IndexExp xe = e1.isIndexExp(); foreach (d; 0 .. depth) - xe = cast(IndexExp)xe.e1; + xe = xe.e1.isIndexExp(); Expression ekey = interpretRegion(xe.e2, istate); if (exceptionOrCant(ekey)) @@ -3450,9 +3452,9 @@ public: oldval = copyLiteral(e.e1.type.defaultInitLiteral(e.loc)).copy(); Expression newaae = oldval; - while (e1.op == EXP.index && (cast(IndexExp)e1).e1.type.toBasetype().ty == Taarray) + while (e1.op == EXP.index && e1.isIndexExp().e1.type.toBasetype().ty == Taarray) { - Expression ekey = interpretRegion((cast(IndexExp)e1).e2, istate); + Expression ekey = interpretRegion(e1.isIndexExp().e2, istate); if (exceptionOrCant(ekey)) return; ekey = resolveSlice(ekey); // only happens with AA assignment @@ -3463,7 +3465,7 @@ public: valuesx.push(newaae); auto aae = ctfeEmplaceExp!AssocArrayLiteralExp(e.loc, keysx, valuesx); - aae.type = (cast(IndexExp)e1).e1.type; + aae.type = e1.isIndexExp().e1.type; aae.ownedByCtfe = OwnedBy.ctfe; if (!existingAA) { @@ -3471,7 +3473,7 @@ public: lastIndex = ekey; } newaae = aae; - e1 = (cast(IndexExp)e1).e1; + e1 = e1.isIndexExp().e1; } // We must set to aggregate with newaae @@ -3521,11 +3523,11 @@ public: if (exceptionOrCant(e1)) return; - if (e1.op == EXP.index && (cast(IndexExp)e1).e1.type.toBasetype().ty == Taarray) + if (e1.op == EXP.index && e1.isIndexExp().e1.type.toBasetype().ty == Taarray) { - IndexExp ie = cast(IndexExp)e1; + IndexExp ie = e1.isIndexExp(); assert(ie.e1.op == EXP.assocArrayLiteral); - existingAA = cast(AssocArrayLiteralExp)ie.e1; + existingAA = ie.e1.isAssocArrayLiteralExp(); lastIndex = ie.e2; } } @@ -3657,7 +3659,7 @@ public: // We have changed it into a reference assignment // Note that returnValue is still the new length. - e1 = (cast(ArrayLengthExp)e1).e1; + e1 = e1.isArrayLengthExp().e1; Type t = e1.type.toBasetype(); if (t.ty != Tarray) { @@ -3733,8 +3735,8 @@ public: if (auto dve = e1x.isDotVarExp()) { auto ex = dve.e1; - auto sle = ex.op == EXP.structLiteral ? (cast(StructLiteralExp)ex) - : ex.op == EXP.classReference ? (cast(ClassReferenceExp)ex).value + auto sle = ex.op == EXP.structLiteral ? ex.isStructLiteralExp() + : ex.op == EXP.classReference ? ex.isClassReferenceExp().value : null; auto v = dve.var.isVarDeclaration(); if (!sle || !v) @@ -3792,10 +3794,10 @@ public: * e.v = newval */ auto ex = dve.e1; - auto sle = ex.op == EXP.structLiteral ? (cast(StructLiteralExp)ex) - : ex.op == EXP.classReference ? (cast(ClassReferenceExp)ex).value + auto sle = ex.op == EXP.structLiteral ? ex.isStructLiteralExp() + : ex.op == EXP.classReference ? ex.isClassReferenceExp().value : null; - auto v = (cast(DotVarExp)e1).var.isVarDeclaration(); + auto v = e1.isDotVarExp().var.isVarDeclaration(); if (!sle || !v) { e.error("CTFE internal error: dotvar assignment"); @@ -3808,7 +3810,7 @@ public: } int fieldi = ex.op == EXP.structLiteral ? findFieldIndexByName(sle.sd, v) - : (cast(ClassReferenceExp)ex).findFieldIndexByName(v); + : ex.isClassReferenceExp().findFieldIndexByName(v); if (fieldi == -1) { e.error("CTFE internal error: cannot find field `%s` in `%s`", v.toChars(), ex.toChars()); @@ -3865,7 +3867,7 @@ public: return CTFEExp.cantexp; } - ArrayLiteralExp existingAE = cast(ArrayLiteralExp)aggregate; + ArrayLiteralExp existingAE = aggregate.isArrayLiteralExp(); if (existingAE.ownedByCtfe != OwnedBy.ctfe) { e.error("cannot modify read-only constant `%s`", existingAE.toChars()); @@ -3920,8 +3922,8 @@ public: assert(oldval.op == EXP.arrayLiteral); assert(newval.op == EXP.arrayLiteral); - Expressions* oldelems = (cast(ArrayLiteralExp)oldval).elements; - Expressions* newelems = (cast(ArrayLiteralExp)newval).elements; + Expressions* oldelems = oldval.isArrayLiteralExp().elements; + Expressions* newelems = newval.isArrayLiteralExp().elements; assert(oldelems.dim == newelems.dim); Type elemtype = oldval.type.nextOf(); @@ -4124,7 +4126,7 @@ public: if (newval.op == EXP.slice && !isBlockAssignment) { - auto se = cast(SliceExp)newval; + auto se = newval.isSliceExp(); auto aggr2 = se.e1; const srclower = se.lwr.toInteger(); const srcupper = se.upr.toInteger(); @@ -4140,7 +4142,7 @@ public: // https://issues.dlang.org/show_bug.cgi?id=14024 assert(aggr2.op == EXP.arrayLiteral); Expressions* oldelems = existingAE.elements; - Expressions* newelems = (cast(ArrayLiteralExp)aggr2).elements; + Expressions* newelems = aggr2.isArrayLiteralExp().elements; Type elemtype = aggregate.type.nextOf(); bool needsPostblit = e.e2.isLvalue(); @@ -4213,13 +4215,13 @@ public: /* Mixed slice: it was initialized as an array literal of chars/integers. * Now a slice of it is being set with a string. */ - sliceAssignArrayLiteralFromString(existingAE, cast(StringExp)newval, cast(size_t)firstIndex); + sliceAssignArrayLiteralFromString(existingAE, newval.isStringExp(), cast(size_t)firstIndex); return newval; } if (newval.op == EXP.arrayLiteral && !isBlockAssignment) { Expressions* oldelems = existingAE.elements; - Expressions* newelems = (cast(ArrayLiteralExp)newval).elements; + Expressions* newelems = newval.isArrayLiteralExp().elements; Type elemtype = existingAE.type.nextOf(); bool needsPostblit = e.op != EXP.blit && e.e2.isLvalue(); foreach (j, newelem; *newelems) @@ -4264,7 +4266,7 @@ public: if (!directblk && (*w)[k].op == EXP.arrayLiteral) { // Multidimensional array block assign - if (Expression ex = assignTo(cast(ArrayLiteralExp)(*w)[k])) + if (Expression ex = assignTo((*w)[k].isArrayLiteralExp())) return ex; } else if (refCopy) @@ -4420,7 +4422,7 @@ public: while (e.op == EXP.not) { ret *= -1; - e = (cast(NotExp)e).e1; + e = e.isNotExp().e1; } switch (e.op) { @@ -4430,8 +4432,8 @@ public: goto case; /+ fall through +/ case EXP.greaterThan: case EXP.greaterOrEqual: - *p1 = (cast(BinExp)e).e1; - *p2 = (cast(BinExp)e).e2; + *p1 = e.isBinExp().e1; + *p2 = e.isBinExp().e2; if (!(isPointer((*p1).type) && isPointer((*p2).type))) ret = 0; break; @@ -4898,7 +4900,7 @@ public: } } - if (fd && fd.semanticRun >= PASS.semantic3done && fd.semantic3Errors) + if (fd && fd.semanticRun >= PASS.semantic3done && fd.hasSemantic3Errors()) { e.error("CTFE failed because of previous errors in `%s`", fd.toChars()); result = CTFEExp.cantexp; @@ -5201,7 +5203,7 @@ public: // Pointer to a non-array variable if (agg.op == EXP.symbolOffset) { - e.error("mutable variable `%s` cannot be %s at compile time, even through a pointer", cast(char*)(modify ? "modified" : "read"), (cast(SymOffExp)agg).var.toChars()); + e.error("mutable variable `%s` cannot be %s at compile time, even through a pointer", cast(char*)(modify ? "modified" : "read"), agg.isSymOffExp().var.toChars()); return false; } @@ -5285,7 +5287,7 @@ public: e.error("index %llu exceeds array length %llu", index, iupr - ilwr); return false; } - *pagg = (cast(SliceExp)e1).e1; + *pagg = e1.isSliceExp().e1; *pidx = index + ilwr; } else @@ -5377,7 +5379,7 @@ public: assert(e1.op == EXP.assocArrayLiteral); UnionExp e2tmp = void; e2 = resolveSlice(e2, &e2tmp); - result = findKeyInAA(e.loc, cast(AssocArrayLiteralExp)e1, e2); + result = findKeyInAA(e.loc, e1.isAssocArrayLiteralExp(), e2); if (!result) { e.error("key `%s` not found in associative array `%s`", e2.toChars(), e.e1.toChars()); @@ -5637,7 +5639,7 @@ public: } e1 = resolveSlice(e1); - result = findKeyInAA(e.loc, cast(AssocArrayLiteralExp)e2, e1); + result = findKeyInAA(e.loc, e2.isAssocArrayLiteralExp(), e1); if (exceptionOrCant(result)) return; if (!result) @@ -5742,7 +5744,7 @@ public: return; } - auto cre = cast(ClassReferenceExp)result; + auto cre = result.isClassReferenceExp(); auto cd = cre.originalClass(); // Find dtor(s) in inheritance chain @@ -5859,10 +5861,10 @@ public: result = pue.exp(); return; } - if (e1.op == EXP.index && !(cast(IndexExp)e1).e1.type.equals(e1.type)) + if (e1.op == EXP.index && !e1.isIndexExp().e1.type.equals(e1.type)) { // type painting operation - IndexExp ie = cast(IndexExp)e1; + IndexExp ie = e1.isIndexExp(); if (castBackFromVoid) { // get the original type. For strings, it's just the type... @@ -5870,7 +5872,7 @@ public: // ..but for arrays of type void*, it's the type of the element if (ie.e1.op == EXP.arrayLiteral && ie.e2.op == EXP.int64) { - ArrayLiteralExp ale = cast(ArrayLiteralExp)ie.e1; + ArrayLiteralExp ale = ie.e1.isArrayLiteralExp(); const indx = cast(size_t)ie.e2.toInteger(); if (indx < ale.elements.dim) { @@ -5912,7 +5914,7 @@ public: { // &val[idx] dinteger_t dim = (cast(TypeSArray)pointee.toBasetype()).dim.toInteger(); - IndexExp ie = cast(IndexExp)ae.e1; + IndexExp ie = ae.e1.isIndexExp(); Expression lwr = ie.e2; Expression upr = ctfeEmplaceExp!IntegerExp(ie.e2.loc, ie.e2.toInteger() + dim, Type.tsize_t); @@ -5938,7 +5940,7 @@ public: if (auto ve = e1.isVarExp()) emplaceExp!(VarExp)(pue, e.loc, ve.var); else - emplaceExp!(SymOffExp)(pue, e.loc, (cast(SymOffExp)e1).var, (cast(SymOffExp)e1).offset); + emplaceExp!(SymOffExp)(pue, e.loc, e1.isSymOffExp().var, e1.isSymOffExp().offset); result = pue.exp(); result.type = e.to; return; @@ -5966,7 +5968,7 @@ public: { // Note that the slice may be void[], so when checking for dangerous // casts, we need to use the original type, which is se.e1. - SliceExp se = cast(SliceExp)e1; + SliceExp se = e1.isSliceExp(); if (!isSafePointerCast(se.e1.type.nextOf(), e.to.nextOf())) { e.error("array cast from `%s` to `%s` is not supported at compile time", se.e1.type.toChars(), e.to.toChars()); @@ -6086,7 +6088,7 @@ public: { if (ae.e1.op == EXP.address && ae.e2.op == EXP.int64) { - AddrExp ade = cast(AddrExp)ae.e1; + AddrExp ade = ae.e1.isAddrExp(); Expression ex = interpretRegion(ade.e1, istate); if (exceptionOrCant(ex)) return; @@ -6131,7 +6133,7 @@ public: } // *(&x) ==> x - result = (cast(AddrExp)result).e1; + result = result.isAddrExp().e1; if (result.op == EXP.slice && e.type.toBasetype().ty == Tsarray) { @@ -6211,8 +6213,8 @@ public: // We can't use getField, because it makes a copy if (ex.op == EXP.classReference) { - se = (cast(ClassReferenceExp)ex).value; - i = (cast(ClassReferenceExp)ex).findFieldIndexByName(v); + se = ex.isClassReferenceExp().value; + i = ex.isClassReferenceExp().findFieldIndexByName(v); } else if (ex.op == EXP.typeid_) { @@ -6233,7 +6235,7 @@ public: } else { - se = cast(StructLiteralExp)ex; + se = ex.isStructLiteralExp(); i = findFieldIndexByName(se.sd, v); } if (i == -1) @@ -6540,7 +6542,7 @@ private Expression scrubReturnValue(const ref Loc loc, Expression e) if (e.op == EXP.classReference) { - StructLiteralExp sle = (cast(ClassReferenceExp)e).value; + StructLiteralExp sle = e.isClassReferenceExp().value; if (auto ex = scrubSE(sle)) return ex; } @@ -6620,7 +6622,7 @@ private Expression scrubCacheValue(Expression e) if (e.op == EXP.classReference) { - if (auto ex = scrubSE((cast(ClassReferenceExp)e).value)) + if (auto ex = scrubSE(e.isClassReferenceExp().value)) return ex; } else if (auto sle = e.isStructLiteralExp()) @@ -6767,14 +6769,14 @@ private Expression copyRegionExp(Expression e) case EXP.vector: case EXP.dotVariable: { - UnaExp ue = cast(UnaExp)e; + UnaExp ue = e.isUnaExp(); ue.e1 = copyRegionExp(ue.e1); break; } case EXP.index: { - BinExp be = cast(BinExp)e; + BinExp be = e.isBinExp(); be.e1 = copyRegionExp(be.e1); be.e2 = copyRegionExp(be.e2); break; @@ -6939,7 +6941,7 @@ private Expression interpret_aaApply(UnionExp* pue, InterState* istate, Expressi Expressions args = Expressions(numParams); - AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)aa; + AssocArrayLiteralExp ae = aa.isAssocArrayLiteralExp(); if (!ae.keys || ae.keys.dim == 0) return ctfeEmplaceExp!IntegerExp(deleg.loc, 0, Type.tsize_t); Expression eresult; @@ -7298,7 +7300,7 @@ private Expression evaluateIfBuiltin(UnionExp* pue, InterState* istate, const re { // At present, the constructors just copy their arguments into the struct. // But we might need some magic if stack tracing gets added to druntime. - StructLiteralExp se = (cast(ClassReferenceExp)pthis).value; + StructLiteralExp se = pthis.isClassReferenceExp().value; assert(arguments.dim <= se.elements.dim); foreach (i, arg; *arguments) { diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d index 1e6799f..c3662a7 100644 --- a/gcc/d/dmd/dmangle.d +++ b/gcc/d/dmd/dmangle.d @@ -991,10 +991,6 @@ public: if (stc & STC.returninferred) stc &= ~(STC.return_ | STC.returninferred); - // 'return inout ref' is the same as 'inout ref' - if ((stc & (STC.return_ | STC.wild)) == (STC.return_ | STC.wild)) - stc &= ~STC.return_; - // much like hdrgen.stcToBuffer() string rrs; const isout = (stc & STC.out_) != 0; @@ -1365,5 +1361,3 @@ extern (D) const(char)[] externallyMangledIdentifier(Declaration d) } return null; } - - diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index 35d2aba..c7e6418 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -662,7 +662,7 @@ extern (C++) final class Module : Package return true; // already read //printf("Module::read('%s') file '%s'\n", toChars(), srcfile.toChars()); - if (auto result = FileManager.fileManager.lookup(srcfile)) + if (auto result = global.fileManager.lookup(srcfile)) { this.src = result.data; if (global.params.emitMakeDeps) diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d index aa30b5d..c3a1d05 100644 --- a/gcc/d/dmd/dscope.d +++ b/gcc/d/dmd/dscope.d @@ -708,6 +708,31 @@ struct Scope return null; } + /******************************************** + * Find the lexically enclosing function (if any). + * + * This function skips through generated FuncDeclarations, + * e.g. rewritten foreach bodies. + * + * Returns: the function or null + */ + inout(FuncDeclaration) getEnclosingFunction() inout + { + if (!this.func) + return null; + + auto fd = cast(FuncDeclaration) this.func; + + // Look through foreach bodies rewritten as delegates + while (fd.fes) + { + assert(fd.fes.func); + fd = fd.fes.func; + } + + return cast(inout(FuncDeclaration)) fd; + } + /******************************************* * For TemplateDeclarations, we need to remember the Scope * where it was declared. So mark the Scope as not diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index 9e50bd5..cb6c278 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -190,7 +190,7 @@ struct Visibility enum PASS : ubyte { - init, // initial state + initial, // initial state semantic, // semantic() started semanticdone, // semantic() done semantic2, // semantic2() started @@ -249,7 +249,7 @@ extern (C++) class Dsymbol : ASTNode Scope* _scope; // !=null means context to use for semantic() const(char)* prettystring; // cached value of toPrettyChars() bool errors; // this symbol failed to pass semantic() - PASS semanticRun = PASS.init; + PASS semanticRun = PASS.initial; ushort localNum; /// perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab DeprecatedDeclaration depdecl; // customized deprecation message @@ -621,7 +621,7 @@ extern (C++) class Dsymbol : ASTNode static bool has2This(Dsymbol s) { if (auto f = s.isFuncDeclaration()) - return f.isThis2; + return f.hasDualContext(); if (auto ad = s.isAggregateDeclaration()) return ad.vthis2 !is null; return false; @@ -2399,6 +2399,7 @@ Dsymbol handleTagSymbols(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds) { enum log = false; if (log) printf("handleTagSymbols('%s') add %p existing %p\n", s.toChars(), s, s2); + if (log) printf(" add %s %s, existing %s %s\n", s.kind(), s.toChars(), s2.kind(), s2.toChars()); auto sd = s.isScopeDsymbol(); // new declaration auto sd2 = s2.isScopeDsymbol(); // existing declaration @@ -2457,6 +2458,7 @@ Dsymbol handleTagSymbols(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds) sc._module.tagSymTab[cast(void*)s] = s2; return s; } + // neither s2 nor s is a tag if (log) printf(" collision\n"); return null; } @@ -2483,6 +2485,7 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy { enum log = false; if (log) printf("handleSymbolRedeclarations('%s')\n", s.toChars()); + if (log) printf(" add %s %s, existing %s %s\n", s.kind(), s.toChars(), s2.kind(), s2.toChars()); static Dsymbol collision() { @@ -2552,8 +2555,16 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy if (fd.fbody) // fd is the definition { + if (log) printf(" replace existing with new\n"); sds.symtab.update(fd); // replace fd2 in symbol table with fd fd.overnext = fd2; + + /* If fd2 is covering a tag symbol, then fd has to cover the same one + */ + auto ps = cast(void*)fd2 in sc._module.tagSymTab; + if (ps) + sc._module.tagSymTab[cast(void*)fd] = *ps; + return fd; } diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h index aad0f2d..35500af 100644 --- a/gcc/d/dmd/dsymbol.h +++ b/gcc/d/dmd/dsymbol.h @@ -111,7 +111,7 @@ struct Visibility */ enum class PASS : uint8_t { - init, // initial state + initial, // initial state semantic, // semantic() started semanticdone, // semantic() done semantic2, // semantic2() started diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index b31dc9d..c990636 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -231,7 +231,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor override void visit(AliasThis dsym) { - if (dsym.semanticRun != PASS.init) + if (dsym.semanticRun != PASS.initial) return; if (dsym._scope) @@ -346,7 +346,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor printf("linkage = %d\n", dsym.linkage); //if (strcmp(toChars(), "mul") == 0) assert(0); } - //if (semanticRun > PASS.init) + //if (semanticRun > PASS.initial) // return; //semanticRun = PSSsemantic; @@ -417,7 +417,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } //printf("inferring type for %s with init %s\n", dsym.toChars(), dsym._init.toChars()); dsym._init = dsym._init.inferType(sc); - dsym.type = dsym._init.initializerToExpression().type; + dsym.type = dsym._init.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0).type; if (needctfe) sc = sc.endCTFE(); @@ -527,7 +527,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor * and add those. */ size_t nelems = Parameter.dim(tt.arguments); - Expression ie = (dsym._init && !dsym._init.isVoidInitializer()) ? dsym._init.initializerToExpression() : null; + Expression ie = (dsym._init && !dsym._init.isVoidInitializer()) ? dsym._init.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0) : null; if (ie) ie = ie.expressionSemantic(sc); if (nelems > 0 && ie) @@ -987,12 +987,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (ai && tb.ty == Taarray) e = ai.toAssocArrayLiteral(); else - e = dsym._init.initializerToExpression(); + e = dsym._init.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0); if (!e) { // Run semantic, but don't need to interpret dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITnointerpret); - e = dsym._init.initializerToExpression(); + e = dsym._init.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0); if (!e) { dsym.error("is not a static and cannot have static initializer"); @@ -1162,23 +1162,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor dsym.edtor = dsym.callScopeDtor(sc); if (dsym.edtor) { - /* If dsym is a local variable, who's type is a struct with a scope destructor, - * then make dsym scope, too. - */ - if (global.params.useDIP1000 == FeatureState.enabled && - !(dsym.storage_class & (STC.parameter | STC.temp | STC.field | STC.in_ | STC.foreach_ | STC.result | STC.manifest)) && - !dsym.isDataseg() && - !dsym.doNotInferScope && - dsym.type.hasPointers()) - { - auto tv = dsym.type.baseElemOf(); - if (tv.ty == Tstruct && - tv.isTypeStruct().sym.dtor.storage_class & STC.scope_) - { - dsym.storage_class |= STC.scope_; - } - } - if (sc.func && dsym.storage_class & (STC.static_ | STC.gshared)) dsym.edtor = dsym.edtor.expressionSemantic(sc._module._scope); else @@ -1256,7 +1239,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor override void visit(Import imp) { //printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars()); - if (imp.semanticRun > PASS.init) + if (imp.semanticRun > PASS.initial) return; if (imp._scope) @@ -1433,7 +1416,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor void attribSemantic(AttribDeclaration ad) { - if (ad.semanticRun != PASS.init) + if (ad.semanticRun != PASS.initial) return; ad.semanticRun = PASS.semantic; Dsymbols* d = ad.include(sc); @@ -1776,7 +1759,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } else if (auto f = s.isFuncDeclaration()) { - f.isCrtCtorDtor |= isCtor ? 1 : 2; + f.flags |= isCtor ? FUNCFLAG.CRTCtor : FUNCFLAG.CRTDtor; return 1; } else @@ -1990,7 +1973,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor override void visit(Module m) { - if (m.semanticRun != PASS.init) + if (m.semanticRun != PASS.initial) return; //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); m.semanticRun = PASS.semantic; @@ -2099,7 +2082,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor deferDsymbolSemantic(ed, scx); Module.dprogress = dprogress_save; //printf("\tdeferring %s\n", toChars()); - ed.semanticRun = PASS.init; + ed.semanticRun = PASS.initial; return; } else @@ -2503,7 +2486,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor printf("sc.stc = %llx\n", sc.stc); printf("sc.module = %s\n", sc._module.toChars()); } - if (tempdecl.semanticRun != PASS.init) + if (tempdecl.semanticRun != PASS.initial) return; // semantic() already run if (tempdecl._scope) @@ -2648,11 +2631,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor printf("+TemplateMixin.dsymbolSemantic('%s', this=%p)\n", tm.toChars(), tm); fflush(stdout); } - if (tm.semanticRun != PASS.init) + if (tm.semanticRun != PASS.initial) { // When a class/struct contains mixin members, and is done over // because of forward references, never reach here so semanticRun - // has been reset to PASS.init. + // has been reset to PASS.initial. static if (LOG) { printf("\tsemantic done\n"); @@ -2678,7 +2661,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor */ if (!tm.findTempDecl(sc) || !tm.semanticTiargs(sc) || !tm.findBestMatch(sc, null)) { - if (tm.semanticRun == PASS.init) // forward reference had occurred + if (tm.semanticRun == PASS.initial) // forward reference had occurred { //printf("forward reference - deferring\n"); return deferDsymbolSemantic(tm, scx); @@ -2865,7 +2848,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor override void visit(Nspace ns) { - if (ns.semanticRun != PASS.init) + if (ns.semanticRun != PASS.initial) return; static if (LOG) { @@ -2989,7 +2972,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor printf("type: %p, %s\n", funcdecl.type, funcdecl.type.toChars()); } - if (funcdecl.semanticRun != PASS.init && funcdecl.isFuncLiteralDeclaration()) + if (funcdecl.semanticRun != PASS.initial && funcdecl.isFuncLiteralDeclaration()) { /* Member functions that have return types that are * forward references can have semantic() run more than @@ -3023,7 +3006,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor AggregateDeclaration ad = funcdecl.isThis(); // Don't nest structs b/c of generated methods which should not access the outer scopes. // https://issues.dlang.org/show_bug.cgi?id=16627 - if (ad && !funcdecl.generated) + if (ad && !funcdecl.isGenerated()) { funcdecl.storage_class |= ad.storage_class & (STC.TYPECTOR | STC.synchronized_); ad.makeNested(); @@ -3061,12 +3044,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor funcdecl.inlining = pragmadecl.evalPragmaInline(sc); // check pragma(crt_constructor) - if (funcdecl.isCrtCtorDtor) + if (funcdecl.flags & (FUNCFLAG.CRTCtor | FUNCFLAG.CRTDtor)) { if (funcdecl.linkage != LINK.c) { funcdecl.error("must be `extern(C)` for `pragma(%s)`", - funcdecl.isCrtCtorDtor == 1 ? "crt_constructor".ptr : "crt_destructor".ptr); + (funcdecl.flags & FUNCFLAG.CRTCtor) ? "crt_constructor".ptr : "crt_destructor".ptr); } } @@ -3293,7 +3276,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (sc.scopesym && sc.scopesym.isAggregateDeclaration()) funcdecl.error("`static` member has no `this` to which `return` can apply"); else - error(funcdecl.loc, "Top-level function `%s` has no `this` to which `return` can apply", funcdecl.toChars()); + error(funcdecl.loc, "top-level function `%s` has no `this` to which `return` can apply", funcdecl.toChars()); } if (funcdecl.isAbstract() && !funcdecl.isVirtual()) @@ -3524,7 +3507,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else { //printf("\tintroducing function %s\n", funcdecl.toChars()); - funcdecl.introducing = 1; + funcdecl.flags |= FUNCFLAG.introducing; if (cd.classKind == ClassKind.cpp && target.cpp.reverseOverloads) { /* Overloaded functions with same name are grouped and in reverse order. @@ -3916,8 +3899,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } } - if (funcdecl.isMain()) - funcdecl.checkDmain(); // Check main() parameters and return type + funcdecl.checkMain(); // Check main() parameters and return type /* Purity and safety can be inferred for some functions by examining * the function body. @@ -4525,7 +4507,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (sd.errors) sd.type = Type.terror; - if (sd.semanticRun == PASS.init) + if (sd.semanticRun == PASS.initial) sd.type = sd.type.addSTC(sc.stc | sd.storage_class); sd.type = sd.type.typeSemantic(sd.loc, sc); if (auto ts = sd.type.isTypeStruct()) @@ -4539,7 +4521,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // Ungag errors when not speculative Ungag ungag = sd.ungagSpeculative(); - if (sd.semanticRun == PASS.init) + if (sd.semanticRun == PASS.initial) { sd.visibility = sc.visibility; @@ -4747,7 +4729,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (cldec.errors) cldec.type = Type.terror; - if (cldec.semanticRun == PASS.init) + if (cldec.semanticRun == PASS.initial) cldec.type = cldec.type.addSTC(sc.stc | cldec.storage_class); cldec.type = cldec.type.typeSemantic(cldec.loc, sc); if (auto tc = cldec.type.isTypeClass()) @@ -4761,7 +4743,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // Ungag errors when not speculative Ungag ungag = cldec.ungagSpeculative(); - if (cldec.semanticRun == PASS.init) + if (cldec.semanticRun == PASS.initial) { cldec.visibility = sc.visibility; @@ -5259,7 +5241,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor auto ctor = new CtorDeclaration(cldec.loc, Loc.initial, 0, tf); ctor.storage_class |= STC.inference; - ctor.generated = true; + ctor.flags |= FUNCFLAG.generated; ctor.fbody = new CompoundStatement(Loc.initial, new Statements()); cldec.members.push(ctor); @@ -5416,7 +5398,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // Ungag errors when not speculative Ungag ungag = idec.ungagSpeculative(); - if (idec.semanticRun == PASS.init) + if (idec.semanticRun == PASS.initial) { idec.visibility = sc.visibility; @@ -5750,7 +5732,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions* } return; } - if (tempinst.semanticRun != PASS.init) + if (tempinst.semanticRun != PASS.initial) { static if (LOG) { @@ -5761,7 +5743,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions* global.gag = 0; tempinst.error(tempinst.loc, "recursive template expansion"); if (tempinst.gagged) - tempinst.semanticRun = PASS.init; + tempinst.semanticRun = PASS.initial; else tempinst.inst = tempinst; tempinst.errors = true; @@ -5800,7 +5782,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions* { // https://issues.dlang.org/show_bug.cgi?id=13220 // Roll back status for later semantic re-running - tempinst.semanticRun = PASS.init; + tempinst.semanticRun = PASS.initial; } else tempinst.inst = tempinst; @@ -6034,7 +6016,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions* // Create our own scope for the template parameters Scope* _scope = tempdecl._scope; - if (tempdecl.semanticRun == PASS.init) + if (tempdecl.semanticRun == PASS.initial) { tempinst.error("template instantiation `%s` forward references template declaration `%s`", tempinst.toChars(), tempdecl.toChars()); return; @@ -6332,7 +6314,7 @@ Laftersemantic: target_symbol_list.remove(target_symbol_list_idx); tempinst.memberOf = null; // no longer a member } - tempinst.semanticRun = PASS.init; + tempinst.semanticRun = PASS.initial; tempinst.inst = null; tempinst.symtab = null; } @@ -6495,10 +6477,10 @@ void aliasSemantic(AliasDeclaration ds, Scope* sc) // Ungag errors when not instantiated DeclDefs scope alias auto ungag = Ungag(global.gag); - //printf("%s parent = %s, gag = %d, instantiated = %d\n", toChars(), parent, global.gag, isInstantiated()); - if (ds.parent && global.gag && !ds.isInstantiated() && !ds.toParent2().isFuncDeclaration()) + //printf("%s parent = %s, gag = %d, instantiated = %d\n", ds.toChars(), ds.parent.toChars(), global.gag, ds.isInstantiated() !is null); + if (ds.parent && global.gag && !ds.isInstantiated() && !ds.toParent2().isFuncDeclaration() && (sc.minst || sc.tinst)) { - //printf("%s type = %s\n", toPrettyChars(), type.toChars()); + //printf("%s type = %s\n", ds.toPrettyChars(), ds.type.toChars()); global.gag = 0; } @@ -6572,13 +6554,13 @@ void aliasSemantic(AliasDeclaration ds, Scope* sc) } if (s) // it's a symbolic alias { - //printf("alias %s resolved to %s %s\n", toChars(), s.kind(), s.toChars()); + //printf("alias %s resolved to %s %s\n", ds.toChars(), s.kind(), s.toChars()); ds.type = null; ds.aliassym = s; } else // it's a type alias { - //printf("alias %s resolved to type %s\n", toChars(), type.toChars()); + //printf("alias %s resolved to type %s\n", ds.toChars(), ds.type.toChars()); ds.type = ds.type.typeSemantic(ds.loc, sc); ds.aliassym = null; } diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index 366ed60..a5ec63c 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -1173,7 +1173,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol fd = new FuncDeclaration(fd.loc, fd.endloc, fd.ident, fd.storage_class, tf); fd.parent = ti; - fd.inferRetType = true; + fd.flags |= FUNCFLAG.inferRetType; // Shouldn't run semantic on default arguments and return type. foreach (ref param; *tf.parameterList.parameters) @@ -2827,13 +2827,13 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, if (!sc) sc = td._scope; // workaround for Type.aliasthisOf - if (td.semanticRun == PASS.init && td._scope) + if (td.semanticRun == PASS.initial && td._scope) { // Try to fix forward reference. Ungag errors while doing so. Ungag ungag = td.ungagSpeculative(); td.dsymbolSemantic(td._scope); } - if (td.semanticRun == PASS.init) + if (td.semanticRun == PASS.initial) { .error(loc, "forward reference to template `%s`", td.toChars()); Lerror: @@ -2851,7 +2851,7 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, tiargs = new Objects(); auto ti = new TemplateInstance(loc, td, tiargs); Objects dedtypes = Objects(td.parameters.dim); - assert(td.semanticRun != PASS.init); + assert(td.semanticRun != PASS.initial); MATCH mta = td.matchWithInstance(sc, ti, &dedtypes, fargs, 0); //printf("matchWithInstance = %d\n", mta); if (mta == MATCH.nomatch || mta < ta_last) // no match or less match @@ -6425,7 +6425,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol if (!td) return 0; - if (td.semanticRun == PASS.init) + if (td.semanticRun == PASS.initial) { if (td._scope) { @@ -6433,7 +6433,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol Ungag ungag = td.ungagSpeculative(); td.dsymbolSemantic(td._scope); } - if (td.semanticRun == PASS.init) + if (td.semanticRun == PASS.initial) { error("`%s` forward references template declaration `%s`", toChars(), td.toChars()); @@ -6786,7 +6786,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol (*tiargs)[j] = sa; TemplateDeclaration td = sa.isTemplateDeclaration(); - if (td && td.semanticRun == PASS.init && td.literal) + if (td && td.semanticRun == PASS.initial && td.literal) { td.dsymbolSemantic(sc); } @@ -6915,7 +6915,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol dedtypes.setDim(td.parameters.dim); dedtypes.zero(); - assert(td.semanticRun != PASS.init); + assert(td.semanticRun != PASS.initial); MATCH m = td.matchWithInstance(sc, this, &dedtypes, fargs, 0); //printf("matchWithInstance = %d\n", m); @@ -7093,7 +7093,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol extern (D) final bool needsTypeInference(Scope* sc, int flag = 0) { //printf("TemplateInstance.needsTypeInference() %s\n", toChars()); - if (semanticRun != PASS.init) + if (semanticRun != PASS.initial) return false; uint olderrs = global.errors; @@ -7174,7 +7174,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol */ dedtypes.setDim(td.parameters.dim); dedtypes.zero(); - if (td.semanticRun == PASS.init) + if (td.semanticRun == PASS.initial) { if (td._scope) { @@ -7182,7 +7182,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol Ungag ungag = td.ungagSpeculative(); td.dsymbolSemantic(td._scope); } - if (td.semanticRun == PASS.init) + if (td.semanticRun == PASS.initial) { error("`%s` forward references template declaration `%s`", toChars(), td.toChars()); return 1; @@ -7740,13 +7740,13 @@ extern (C++) final class TemplateMixin : TemplateInstance if (!td) return 0; - if (td.semanticRun == PASS.init) + if (td.semanticRun == PASS.initial) { if (td._scope) td.dsymbolSemantic(td._scope); else { - semanticRun = PASS.init; + semanticRun = PASS.initial; return 1; } } diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d index 46982e3..41fb82b 100644 --- a/gcc/d/dmd/dtoh.d +++ b/gcc/d/dmd/dtoh.d @@ -445,6 +445,9 @@ public: */ private void writeIdentifier(const AST.Dsymbol s, const bool canFix = false) { + if (const mn = getMangleOverride(s)) + return buf.writestring(mn); + writeIdentifier(s.ident, s.loc, s.kind(), canFix); } @@ -719,15 +722,20 @@ public: visited[cast(void*)fd] = true; // silently ignore non-user-defined destructors - if (fd.generated && fd.isDtorDeclaration()) + if (fd.isGenerated && fd.isDtorDeclaration()) return; // Note that tf might be null for templated (member) functions auto tf = cast(AST.TypeFunction)fd.type; - if ((tf && tf.linkage != LINK.c && tf.linkage != LINK.cpp) || (!tf && fd.isPostBlitDeclaration())) + if ((tf && (tf.linkage != LINK.c || adparent) && tf.linkage != LINK.cpp) || (!tf && fd.isPostBlitDeclaration())) { ignored("function %s because of linkage", fd.toPrettyChars()); - return checkVirtualFunction(fd); + return checkFunctionNeedsPlaceholder(fd); + } + if (fd.mangleOverride && tf && tf.linkage != LINK.c) + { + ignored("function %s because C++ doesn't support explicit mangling", fd.toPrettyChars()); + return checkFunctionNeedsPlaceholder(fd); } if (!adparent && !fd.fbody) { @@ -742,7 +750,7 @@ public: if (tf && !isSupportedType(tf.next)) { ignored("function %s because its return type cannot be mapped to C++", fd.toPrettyChars()); - return checkVirtualFunction(fd); + return checkFunctionNeedsPlaceholder(fd); } if (tf) foreach (i, fparam; tf.parameterList) { @@ -750,7 +758,7 @@ public: { ignored("function %s because one of its parameters has type `%s` which cannot be mapped to C++", fd.toPrettyChars(), fparam.type.toChars()); - return checkVirtualFunction(fd); + return checkFunctionNeedsPlaceholder(fd); } } @@ -822,13 +830,19 @@ public: } - /// Checks whether `fd` is a virtual function and emits a dummy declaration - /// if required to ensure proper vtable layout - private void checkVirtualFunction(AST.FuncDeclaration fd) + /++ + + Checks whether `fd` is a function that requires a dummy declaration + + instead of simply emitting the declaration (because it would cause + + ABI / behaviour issues). This includes: + + + + - virtual functions to ensure proper vtable layout + + - destructors that would break RAII + +/ + private void checkFunctionNeedsPlaceholder(AST.FuncDeclaration fd) { // Omit redundant declarations - the slot was already // reserved in the base class - if (fd.isVirtual() && fd.introducing) + if (fd.isVirtual() && fd.isIntroducing()) { // Hide placeholders because they are not ABI compatible writeProtection(AST.Visibility.Kind.private_); @@ -837,6 +851,15 @@ public: buf.printf("virtual void __vtable_slot_%u();", counter++); buf.writenl(); } + else if (fd.isDtorDeclaration()) + { + // Create inaccessible dtor to prevent code from keeping instances that + // need to be destroyed on the C++ side (but cannot call the dtor) + writeProtection(AST.Visibility.Kind.private_); + buf.writeByte('~'); + buf.writestring(adparent.ident.toString()); + buf.writestringln("();"); + } } override void visit(AST.UnitTestDeclaration utd) @@ -948,6 +971,11 @@ public: ignored("variable %s because of linkage", vd.toPrettyChars()); return; } + if (vd.mangleOverride && vd.linkage != LINK.c) + { + ignored("variable %s because C++ doesn't support explicit mangling", vd.toPrettyChars()); + return; + } if (!isSupportedType(type)) { ignored("variable %s because its type cannot be mapped to C++", vd.toPrettyChars()); @@ -1073,7 +1101,7 @@ public: auto fd = ad.aliassym.isFuncDeclaration(); - if (fd && (fd.generated || fd.isDtorDeclaration())) + if (fd && (fd.isGenerated() || fd.isDtorDeclaration())) { // Ignore. It's taken care of while visiting FuncDeclaration return; @@ -1106,7 +1134,7 @@ public: // Print prefix of the base class if this function originates from a superclass // because alias might be resolved through multiple classes, e.g. // e.g. for alias visit = typeof(super).visit in the visitors - if (!fd.introducing) + if (!fd.isIntroducing()) printPrefix(ad.toParent().isClassDeclaration().baseClass); else printPrefix(pd); @@ -1655,7 +1683,16 @@ public: scope(exit) printf("[typeToBuffer(AST.Type, AST.Dsymbol) exit] %s sym %s\n", t.toChars(), s.toChars()); } - this.ident = s.ident; + // The context pointer (represented as `ThisDeclaration`) is named + // `this` but accessible via `outer` + if (auto td = s.isThisDeclaration()) + { + import dmd.id; + this.ident = Id.outer; + } + else + this.ident = s.ident; + auto type = origType !is null ? origType : t; AST.Dsymbol customLength; @@ -1702,7 +1739,12 @@ public: if (this.ident) { buf.writeByte(' '); - writeIdentifier(s, canFixup); + // Custom identifier doesn't need further checks + if (this.ident !is s.ident) + buf.writestring(this.ident.toString()); + else + writeIdentifier(s, canFixup); + } this.ident = null; @@ -2922,6 +2964,10 @@ public: scope(exit) printf("[writeFullName exit] %s\n", sym.toPrettyChars()); } + // Explicit `pragma(mangle, "<some string>` overrides the declared name + if (auto mn = getMangleOverride(sym)) + return buf.writestring(mn); + /// Checks whether `sym` is nested in `par` and hence doesn't need the FQN static bool isNestedIn(AST.Dsymbol sym, AST.Dsymbol par) { @@ -2970,6 +3016,15 @@ public: else buf.writestring(sym.ident.toString()); } + + /// Returns: Explicit mangling for `sym` if present + extern(D) static const(char)[] getMangleOverride(const AST.Dsymbol sym) + { + if (auto decl = sym.isDeclaration()) + return decl.mangleOverride; + + return null; + } } /// Namespace for identifiers used to represent special enums in C++ @@ -3037,7 +3092,7 @@ void hashEndIf(ref OutBuffer buf) /// Writes `#define <content>` into the supplied buffer void hashDefine(ref OutBuffer buf, string content) { - buf.writestring("# define "); + buf.writestring("#define "); buf.writestringln(content); } diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index e9dcdc0..4196c05 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -692,9 +692,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag) // If va's lifetime encloses v's, then error if (va && !va.isDataseg() && - (va.enclosesLifetimeOf(v) && !(v.storage_class & STC.temp) || - vaIsRef || - va.isReference() && !(v.storage_class & (STC.parameter | STC.temp))) && + ((va.enclosesLifetimeOf(v) && !(v.storage_class & STC.temp)) || vaIsRef) && fd.setUnsafe()) { if (!gag) @@ -793,7 +791,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag) // If va's lifetime encloses v's, then error if (va && - (va.enclosesLifetimeOf(v) || (va.isRef() && !(va.storage_class & STC.temp)) || va.isDataseg()) && + (va.enclosesLifetimeOf(v) || (va.isReference() && !(va.storage_class & STC.temp)) || va.isDataseg()) && fd.setUnsafe()) { if (!gag) @@ -1284,27 +1282,24 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag) { if (!gag) { - const(char)* msg, supplemental; - if (v.storage_class & STC.parameter && - (v.type.hasPointers() || v.storage_class & STC.ref_)) - { - msg = "returning `%s` escapes a reference to parameter `%s`"; - supplemental = vsr == ScopeRef.Ref_ReturnScope - ? "perhaps remove `scope` parameter annotation so `return` applies to `ref`" - : v.ident is Id.This - ? "perhaps annotate the function with `return`" - : "perhaps annotate the parameter with `return`"; - } - else + const(char)* varKind = v.isParameter() ? "parameter" : "local variable"; + previewErrorFunc(sc.isDeprecated(), featureState)(e.loc, + "returning `%s` escapes a reference to %s `%s`", e.toChars(), varKind, v.toChars()); + + if (v.isParameter() && v.isReference()) { - msg = "returning `%s` escapes a reference to local variable `%s`"; - if (v.ident is Id.This) - supplemental = "perhaps annotate the function with `return`"; + if (v.storage_class & STC.returnScope) + { + previewSupplementalFunc(sc.isDeprecated(), featureState)(v.loc, + "perhaps change the `return scope` into `scope return`"); + } + else + { + const(char)* annotateKind = (v.ident is Id.This) ? "function" : "parameter"; + previewSupplementalFunc(sc.isDeprecated(), featureState)(v.loc, + "perhaps annotate the %s with `return`", annotateKind); + } } - - previewErrorFunc(sc.isDeprecated(), featureState)(e.loc, msg, e.toChars(), v.toChars()); - if (supplemental) - previewSupplementalFunc(sc.isDeprecated(), featureState)(e.loc, supplemental); } result = true; } @@ -1897,7 +1892,7 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false) override void visit(ThisExp e) { - if (e.var && e.var.toParent2().isFuncDeclaration().isThis2) + if (e.var && e.var.toParent2().isFuncDeclaration().hasDualContext()) escapeByValue(e, er, live); else if (e.var) er.byref.push(e.var); @@ -2297,3 +2292,37 @@ bool isReferenceToMutable(Parameter p, Type t) } return isReferenceToMutable(p.type); } + +/********************************** +* Determine if `va` has a lifetime that lasts past +* the destruction of `v` +* Params: +* va = variable assigned to +* v = variable being assigned +* Returns: +* true if it does +*/ +private bool enclosesLifetimeOf(const VarDeclaration va, const VarDeclaration v) pure +{ + assert(va.sequenceNumber != va.sequenceNumber.init); + assert(v.sequenceNumber != v.sequenceNumber.init); + return va.sequenceNumber < v.sequenceNumber; +} + +/*************************************** + * Add variable `v` to maybes[] + * + * When a maybescope variable `v` is assigned to a maybescope variable `va`, + * we cannot determine if `this` is actually scope until the semantic + * analysis for the function is completed. Thus, we save the data + * until then. + * Params: + * v = an `STC.maybescope` variable that was assigned to `this` + */ +private void addMaybe(VarDeclaration va, VarDeclaration v) +{ + //printf("add %s to %s's list of dependencies\n", v.toChars(), toChars()); + if (!va.maybes) + va.maybes = new VarDeclarations(); + va.maybes.push(v); +} diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 7abfe7f..07d885b 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -170,7 +170,7 @@ FuncDeclaration hasThis(Scope* sc) { return null; } - if (!fd.isNested() || fd.isThis() || (fd.isThis2 && fd.isMember2())) + if (!fd.isNested() || fd.isThis() || (fd.hasDualContext() && fd.isMember2())) break; Dsymbol parent = fd.parent; @@ -187,7 +187,7 @@ FuncDeclaration hasThis(Scope* sc) fd = parent.isFuncDeclaration(); } - if (!fd.isThis() && !(fd.isThis2 && fd.isMember2())) + if (!fd.isThis() && !(fd.hasDualContext() && fd.isMember2())) { return null; } @@ -1210,7 +1210,7 @@ extern (C++) abstract class Expression : ASTNode scope bool function(DtorDeclaration) check, const string checkName ) { auto dd = f.isDtorDeclaration(); - if (!dd || !dd.generated) + if (!dd || !dd.isGenerated()) return; // DtorDeclaration without parents should fail at an earlier stage @@ -1227,7 +1227,7 @@ extern (C++) abstract class Expression : ASTNode } dd.loc.errorSupplemental("%s`%s.~this` is %.*s because of the following field's destructors:", - dd.generated ? "generated " : "".ptr, + dd.isGenerated() ? "generated " : "".ptr, ad.toChars, cast(int) checkName.length, checkName.ptr); @@ -1258,7 +1258,7 @@ extern (C++) abstract class Expression : ASTNode { field.loc.errorSupplemental(" - %s %s", field.type.toChars(), field.toChars()); - if (fieldSd.dtor.generated) + if (fieldSd.dtor.isGenerated()) checkOverridenDtor(sc, fieldSd.dtor, check, checkName); else fieldSd.dtor.loc.errorSupplemental(" %.*s `%s.~this` is declared here", @@ -1288,7 +1288,7 @@ extern (C++) abstract class Expression : ASTNode return false; // magic variable never violates pure and safe if (v.isImmutable()) return false; // always safe and pure to access immutables... - if (v.isConst() && !v.isRef() && (v.isDataseg() || v.isParameter()) && v.type.implicitConvTo(v.type.immutableOf())) + if (v.isConst() && !v.isReference() && (v.isDataseg() || v.isParameter()) && v.type.implicitConvTo(v.type.immutableOf())) return false; // or const global/parameter values which have no mutable indirections if (v.storage_class & STC.manifest) return false; // ...or manifest constants @@ -3461,7 +3461,7 @@ extern (C++) final class ScopeExp : Expression //assert(ti.needsTypeInference(sc)); if (ti.tempdecl && ti.semantictiargsdone && - ti.semanticRun == PASS.init) + ti.semanticRun == PASS.initial) { error("partial %s `%s` has no type", sds.kind(), toChars()); return true; @@ -3859,7 +3859,7 @@ extern (C++) final class FuncExp : Expression { if (td) return new FuncExp(loc, td.syntaxCopy(null)); - else if (fd.semanticRun == PASS.init) + else if (fd.semanticRun == PASS.initial) return new FuncExp(loc, fd.syntaxCopy(null)); else // https://issues.dlang.org/show_bug.cgi?id=13481 // Prevent multiple semantic analysis of lambda body. @@ -4950,7 +4950,7 @@ extern (C++) final class DotTemplateInstanceExp : UnaExp // Same logic as ScopeExp.checkType() if (ti.tempdecl && ti.semantictiargsdone && - ti.semanticRun == PASS.init) + ti.semanticRun == PASS.initial) { error("partial %s `%s` has no type", ti.kind(), toChars()); return true; @@ -4962,7 +4962,7 @@ extern (C++) final class DotTemplateInstanceExp : UnaExp { if (ti.tempdecl && ti.semantictiargsdone && - ti.semanticRun == PASS.init) + ti.semanticRun == PASS.initial) error("partial %s `%s` has no value", ti.kind(), toChars()); else diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 5802816..7b7c489 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -1046,7 +1046,7 @@ L1: if (e1.op == EXP.this_) { FuncDeclaration f = hasThis(sc); - if (f && f.isThis2) + if (f && f.hasDualContext()) { if (f.followInstantiationContext(ad)) { @@ -1444,13 +1444,6 @@ private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps) Expression ex = condexp.expressionSemantic(sc); if (ex.op == EXP.error) e = ex; - else if (e.op == EXP.function_ || e.op == EXP.delegate_) - { - // https://issues.dlang.org/show_bug.cgi?id=21285 - // Functions and delegates don't convert correctly with castTo below - exps[i] = condexp.e1; - e = condexp.e2; - } else { // Convert to common type @@ -1723,7 +1716,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, if (sc._module) sc._module.hasAlwaysInlines = true; if (sc.func) - sc.func.hasAlwaysInlines = true; + sc.func.flags |= FUNCFLAG.hasAlwaysInline; } const isCtorCall = fd && fd.needThis() && fd.isCtorDeclaration(); @@ -3743,7 +3736,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); } - if (sd.hasRegularCtor() && nargs) + // https://issues.dlang.org/show_bug.cgi?id=22639 + // If the new expression has arguments, we either should call a + // regular constructor of a copy constructor if the first argument + // is the same type as the struct + if (nargs && (sd.hasRegularCtor() || (sd.ctor && (*exp.arguments)[0].type.mutableOf() == sd.type.mutableOf()))) { FuncDeclaration f = resolveFuncCall(exp.loc, sc, sd.ctor, null, tb, exp.arguments, FuncResolveFlag.standard); if (!f || f.errors) @@ -4201,30 +4198,27 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Type tthis = null; Expression e1org = exp.e1; - if (exp.e1.op == EXP.comma) + if (auto ce = exp.e1.isCommaExp()) { /* Rewrite (a,b)(args) as (a,(b(args))) */ - auto ce = cast(CommaExp)exp.e1; exp.e1 = ce.e2; ce.e2 = exp; result = ce.expressionSemantic(sc); return; } - if (exp.e1.op == EXP.delegate_) + if (DelegateExp de = exp.e1.isDelegateExp()) { - DelegateExp de = cast(DelegateExp)exp.e1; exp.e1 = new DotVarExp(de.loc, de.e1, de.func, de.hasOverloads); visit(exp); return; } - if (exp.e1.op == EXP.function_) + if (FuncExp fe = exp.e1.isFuncExp()) { if (arrayExpressionSemantic(exp.arguments, sc) || preFunctionParameters(sc, exp.arguments)) return setError(); // Run e1 semantic even if arguments have any errors - FuncExp fe = cast(FuncExp)exp.e1; exp.e1 = callExpSemantic(fe, sc, exp.arguments); if (exp.e1.op == EXP.error) { @@ -4252,9 +4246,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor /* This recognizes: * foo!(tiargs)(funcargs) */ - if (exp.e1.op == EXP.scope_) + if (ScopeExp se = exp.e1.isScopeExp()) { - ScopeExp se = cast(ScopeExp)exp.e1; TemplateInstance ti = se.sds.isTemplateInstance(); if (ti) { @@ -4300,9 +4293,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor * expr.foo!(tiargs)(funcargs) */ Ldotti: - if (exp.e1.op == EXP.dotTemplateInstance) + if (DotTemplateInstanceExp se = exp.e1.isDotTemplateInstanceExp()) { - DotTemplateInstanceExp se = cast(DotTemplateInstanceExp)exp.e1; TemplateInstance ti = se.ti; { /* Attempt to instantiate ti. If that works, go with it. @@ -4347,9 +4339,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else { - if (exp.e1.op == EXP.dotIdentifier) + if (DotIdExp die = exp.e1.isDotIdExp()) { - DotIdExp die = cast(DotIdExp)exp.e1; exp.e1 = die.expressionSemantic(sc); /* Look for e1 having been rewritten to expr.opDispatch!(string) * We handle such earlier, so go back. @@ -4380,9 +4371,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor /* Look for e1 being a lazy parameter */ - if (exp.e1.op == EXP.variable) + if (VarExp ve = exp.e1.isVarExp()) { - VarExp ve = cast(VarExp)exp.e1; if (ve.var.storage_class & STC.lazy_) { // lazy parameters can be called without violating purity and safety @@ -4404,10 +4394,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.e1 = new VarExp(se.loc, se.var, true); exp.e1 = exp.e1.expressionSemantic(sc); } - else if (exp.e1.op == EXP.dot) + else if (DotExp de = exp.e1.isDotExp()) { - DotExp de = cast(DotExp)exp.e1; - if (de.e2.op == EXP.overloadSet) { ethis = de.e1; @@ -4490,7 +4478,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (sd.ctor) { auto ctor = sd.ctor.isCtorDeclaration(); - if (ctor && ctor.isCpCtor && ctor.generated) + if (ctor && ctor.isCpCtor && ctor.isGenerated()) sd.ctor = null; } @@ -4504,7 +4492,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor If all constructors are copy constructors, then try default construction. */ - if (!sd.hasRegularCtor) + if (!sd.hasRegularCtor && + // https://issues.dlang.org/show_bug.cgi?id=22639 + // we might still have a copy constructor that could be called + (*exp.arguments)[0].type.mutableOf != sd.type.mutableOf()) goto Lx; auto sle = new StructLiteralExp(exp.loc, sd, null, exp.e1.type); @@ -4850,10 +4841,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); } } - else if (exp.e1.op == EXP.overloadSet) + else if (auto oe = exp.e1.isOverExp()) { - auto os = (cast(OverExp)exp.e1).vars; - exp.f = resolveOverloadSet(exp.loc, sc, os, tiargs, tthis, exp.arguments); + exp.f = resolveOverloadSet(exp.loc, sc, oe.vars, tiargs, tthis, exp.arguments); if (!exp.f) return setError(); if (ethis) @@ -4877,11 +4867,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor const(char)* p; Dsymbol s; exp.f = null; - if (exp.e1.op == EXP.function_) + if (auto fe = exp.e1.isFuncExp()) { // function literal that direct called is always inferred. - assert((cast(FuncExp)exp.e1).fd); - exp.f = (cast(FuncExp)exp.e1).fd; + assert(fe.fd); + exp.f = fe.fd; tf = cast(TypeFunction)exp.f.type; p = "function literal"; } @@ -5011,11 +5001,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } t1 = tf; } - else if (exp.e1.op == EXP.variable) + else if (VarExp ve = exp.e1.isVarExp()) { // Do overload resolution - VarExp ve = cast(VarExp)exp.e1; - exp.f = ve.var.isFuncDeclaration(); assert(exp.f); tiargs = null; @@ -5162,7 +5150,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } // declare dual-context container - if (exp.f && exp.f.isThis2 && !sc.intypeof && sc.func) + if (exp.f && exp.f.hasDualContext() && !sc.intypeof && sc.func) { // check access to second `this` if (AggregateDeclaration ad2 = exp.f.isMember2()) @@ -6042,13 +6030,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { auto fileName = FileName(name.toDString); - if (auto fmResult = FileManager.fileManager.lookup(fileName)) + if (auto fmResult = global.fileManager.lookup(fileName)) { se = new StringExp(e.loc, fmResult.data); } else { - auto readResult = File.read(name); + auto readResult = File.read(name.toDString); if (!readResult.success) { e.error("cannot read file `%s`", name); @@ -6060,9 +6048,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor auto data = readResult.extractSlice(); se = new StringExp(e.loc, data); - FileBuffer* fileBuffer = FileBuffer.create(); - fileBuffer.data = data; - FileManager.fileManager.add(fileName, fileBuffer); + FileBuffer* fileBuffer = new FileBuffer(data); + global.fileManager.add(fileName, fileBuffer); } } } @@ -6200,10 +6187,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor const op = exp.e1.op; bool isEqualsCallExpression; - if (op == EXP.call) + if (const callExp = exp.e1.isCallExp()) { - const callExp = cast(CallExp) exp.e1; - // https://issues.dlang.org/show_bug.cgi?id=20331 // callExp.f may be null if the assert contains a call to // a function pointer or literal @@ -6436,7 +6421,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } else if (t) { - result = new IntegerExp(exp.loc, t.alignsize, Type.tsize_t); + // Note similarity to getProperty() implementation of __xalignof + const explicitAlignment = t.alignment(); + const naturalAlignment = t.alignsize(); + const actualAlignment = (explicitAlignment.isDefault() ? naturalAlignment : explicitAlignment.get()); + result = new IntegerExp(exp.loc, actualAlignment, Type.tsize_t); } else if (s) { @@ -6643,7 +6632,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (v && (v.isDataseg() || // fix https://issues.dlang.org/show_bug.cgi?id=8238 - (!v.needThis() && v.semanticRun > PASS.init))) // fix https://issues.dlang.org/show_bug.cgi?id=17258 + (!v.needThis() && v.semanticRun > PASS.initial))) // fix https://issues.dlang.org/show_bug.cgi?id=17258 { // (e1, v) checkAccess(exp.loc, sc, exp.e1, v); @@ -6736,7 +6725,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } result = e; // declare dual-context container - if (f.isThis2 && !sc.intypeof && sc.func) + if (f.hasDualContext() && !sc.intypeof && sc.func) { // check access to second `this` if (AggregateDeclaration ad2 = f.isMember2()) @@ -7311,7 +7300,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (checkNonAssignmentArrayOp(e.e1)) return setError(); - e.type = Type.tbool; + e.type = (sc && sc.flags & SCOPE.Cfile) ? Type.tint32 : Type.tbool; result = e; } @@ -7323,7 +7312,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // 3. Removal of keyword, "delete" can be used for other identities if (!exp.isRAII) { - error(exp.loc, "The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead."); + error(exp.loc, "the `delete` keyword is obsolete"); + errorSupplemental(exp.loc, "use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead"); return setError(); } @@ -7847,9 +7837,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor */ if (VarDeclaration v = expToVariable(exp.e1)) { - if (exp.e1.op == EXP.dotVariable) + if (DotVarExp dve = exp.e1.isDotVarExp()) { - DotVarExp dve = cast(DotVarExp)exp.e1; + if ((dve.e1.op == EXP.this_ || dve.e1.op == EXP.super_) && !(v.storage_class & STC.ref_)) { @@ -8140,10 +8130,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor result = exp.e2; return; } - if (exp.e2.op == EXP.template_) + if (auto te = exp.e2.isTemplateExp()) { - auto td = (cast(TemplateExp)exp.e2).td; - Expression e = new DotTemplateExp(exp.loc, exp.e1, td); + Expression e = new DotTemplateExp(exp.loc, exp.e1, te.td); result = e.expressionSemantic(sc); return; } @@ -8182,11 +8171,15 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor e.e2 = e.e2.arrayFuncConv(sc); e.type = e.e2.type; + result = e; + + if (sc.flags & SCOPE.Cfile) + return; + if (e.type is Type.tvoid) discardValue(e.e1); - else if (!e.allowCommaExp && !e.isGenerated && !(sc.flags & SCOPE.Cfile)) + else if (!e.allowCommaExp && !e.isGenerated) e.error("Using the result of a comma expression is not allowed"); - result = e; } override void visit(IntervalExp e) @@ -8472,6 +8465,19 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // OR it in, because it might already be set for C array indexing exp.indexIsInBounds |= bounds.contains(getIntRange(exp.e2)); } + else if (sc.flags & SCOPE.Cfile && t1b.ty == Tsarray) + { + if (auto ve = exp.e1.isVarExp()) + { + /* Rewrite 0-length C array ve[exp.e2] as *(ve + exp.e2) + */ + auto vp = ve.castTo(sc, t1b.isTypeSArray().next.pointerTo()); + auto e = new AddExp(exp.loc, vp, exp.e2); + auto pe = new PtrExp(exp.loc, e); + result = pe.expressionSemantic(sc).optimize(WANTvalue); + return; + } + } } } @@ -10024,9 +10030,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } - if (exp.e1.op == EXP.slice) + if (SliceExp se = exp.e1.isSliceExp()) { - SliceExp se = cast(SliceExp)exp.e1; if (se.e1.type.toBasetype().ty == Tsarray) { exp.error("cannot append to static array `%s`", se.e1.type.toChars()); @@ -11270,7 +11275,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor e1x = e1x.optimize(WANTvalue); if (e1x.toBool().hasValue(exp.op == EXP.orOr)) { - result = IntegerExp.createBool(exp.op == EXP.orOr); + if (sc.flags & SCOPE.Cfile) + result = new IntegerExp(exp.op == EXP.orOr); + else + result = IntegerExp.createBool(exp.op == EXP.orOr); return; } } @@ -11315,7 +11323,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (e2x.type.ty == Tvoid) exp.type = Type.tvoid; else - exp.type = Type.tbool; + exp.type = (sc && sc.flags & SCOPE.Cfile) ? Type.tint32 : Type.tbool; exp.e1 = e1x; exp.e2 = e2x; @@ -11412,7 +11420,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (f1 || f2) return setError(); - exp.type = Type.tbool; + exp.type = (sc && sc.flags & SCOPE.Cfile) ? Type.tint32 : Type.tbool; // Special handling for array comparisons Expression arrayLowering = null; @@ -11690,7 +11698,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (f1 || f2) return setError(); - exp.type = Type.tbool; + exp.type = (sc && sc.flags & SCOPE.Cfile) ? Type.tint32 : Type.tbool; if (!isArrayComparison) { @@ -11825,8 +11833,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } - if (exp.econd.op == EXP.dotIdentifier) - (cast(DotIdExp)exp.econd).noderef = true; + if (auto die = exp.econd.isDotIdExp()) + die.noderef = true; Expression ec = exp.econd.expressionSemantic(sc); ec = resolveProperties(sc, ec); @@ -12654,9 +12662,8 @@ Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag) if (e.op == EXP.error) return e; - if (e.op == EXP.dotVariable) + if (DotVarExp dve = e.isDotVarExp()) { - DotVarExp dve = cast(DotVarExp)e; if (FuncDeclaration fd = dve.var.isFuncDeclaration()) { if (TemplateDeclaration td = fd.findTemplateDeclRoot()) @@ -12707,9 +12714,8 @@ Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag) } } - if (e.op == EXP.dotTemplateDeclaration) + if (DotTemplateExp dte = e.isDotTemplateExp()) { - DotTemplateExp dte = cast(DotTemplateExp)e; exp.e1 = dte.e1; // pull semantic() result exp.ti.tempdecl = dte.td; @@ -12738,10 +12744,8 @@ Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag) return new ScopeExp(exp.loc, exp.ti) .expressionSemantic(sc); } - else if (e.op == EXP.dot) + else if (DotExp de = e.isDotExp()) { - DotExp de = cast(DotExp)e; - if (de.e2.op == EXP.overloadSet) { if (!exp.findTempDecl(sc) || !exp.ti.semanticTiargs(sc)) @@ -12765,9 +12769,8 @@ Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag) .expressionSemantic(sc); } } - else if (e.op == EXP.overloadSet) + else if (OverExp oe = e.isOverExp()) { - OverExp oe = cast(OverExp)e; exp.ti.tempdecl = oe.vars; return new ScopeExp(exp.loc, exp.ti) .expressionSemantic(sc); @@ -13055,7 +13058,7 @@ Expression getThisSkipNestedFuncs(const ref Loc loc, Scope* sc, Dsymbol s, Aggre { n++; e1 = new VarExp(loc, f.vthis); - if (f.isThis2) + if (f.hasDualContext()) { // (*__this)[i] if (n > 1) @@ -13355,8 +13358,8 @@ Expression toBoolean(Expression exp, Scope* sc) default: // Default is 'yes' - do nothing - Expression e = exp; - Type t = exp.type; + Expression e = arrayFuncConv(exp, sc); + Type t = e.type; Type tb = t.toBasetype(); Type att = null; diff --git a/gcc/d/dmd/file_manager.d b/gcc/d/dmd/file_manager.d index 9ba3807..b86c799 100644 --- a/gcc/d/dmd/file_manager.d +++ b/gcc/d/dmd/file_manager.d @@ -20,10 +20,15 @@ import dmd.identifier; enum package_d = "package." ~ mars_ext; enum package_di = "package." ~ hdr_ext; -struct FileManager +final class FileManager { private StringTable!(FileBuffer*) files; - private __gshared bool initialized = false; + + /// + public this () nothrow + { + this.files._init(); + } nothrow: /******************************************** @@ -143,9 +148,6 @@ nothrow: */ const(FileBuffer)* lookup(FileName filename) { - if (!initialized) - FileManager._init(); - const name = filename.toString; if (auto val = files.lookup(name)) return val.value; @@ -182,9 +184,6 @@ nothrow: */ const(char)[][] getLines(FileName file) { - if (!initialized) - FileManager._init(); - const(char)[][] lines; if (const buffer = lookup(file)) { @@ -241,29 +240,9 @@ nothrow: */ FileBuffer* add(FileName filename, FileBuffer* filebuffer) { - if (!initialized) - FileManager._init(); - auto val = files.insert(filename.toString, filebuffer); return val == null ? null : val.value; } - - __gshared fileManager = FileManager(); - - // Initialize the global FileManager singleton - private void _init() - { - if (!initialized) - { - fileManager.initialize(); - initialized = true; - } - } - - void initialize() - { - files._init(); - } } private FileBuffer readFromStdin() nothrow diff --git a/gcc/d/dmd/foreachvar.d b/gcc/d/dmd/foreachvar.d index b779eaeee..53ed62e 100644 --- a/gcc/d/dmd/foreachvar.d +++ b/gcc/d/dmd/foreachvar.d @@ -320,4 +320,3 @@ void foreachExpAndVar(Statement s, visit(s); } - diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index afc0ebb..8d83951 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -140,7 +140,7 @@ public: override void visit(TryFinallyStatement s) { DtorExpStatement des; - if (fd.nrvo_can && s.finalbody && (des = s.finalbody.isDtorExpStatement()) !is null && + if (fd.isNRVO() && s.finalbody && (des = s.finalbody.isDtorExpStatement()) !is null && fd.nrvo_var == des.var) { if (!(global.params.useExceptions && ClassDeclaration.throwable)) @@ -182,7 +182,7 @@ public: catches.push(ctch); Statement s2 = new TryCatchStatement(Loc.initial, s._body, catches); - fd.eh_none = false; + fd.flags &= ~FUNCFLAG.noEH; replaceCurrent(s2); s2.accept(this); } @@ -205,6 +205,17 @@ enum FUNCFLAG : uint printf = 0x200, /// is a printf-like function scanf = 0x400, /// is a scanf-like function noreturn = 0x800, /// the function does not return + NRVO = 0x1000, /// Support for named return value optimization + naked = 0x2000, /// The function is 'naked' (see inline ASM) + generated = 0x4000, /// The function is compiler generated (e.g. `opCmp`) + introducing = 0x8000, /// If this function introduces the overload set + semantic3Errors = 0x10000, /// If errors in semantic3 this function's frame ptr + noEH = 0x20000, /// No exception unwinding is needed + inferRetType = 0x40000, /// Return type is to be inferred + dualContext = 0x80000, /// has a dual-context 'this' parameter + hasAlwaysInline = 0x100000, /// Contains references to functions that must be inlined + CRTCtor = 0x200000, /// Has attribute pragma(crt_constructor) + CRTDtor = 0x400000, /// Has attribute pragma(crt_destructor) } /*********************************************************** @@ -268,7 +279,6 @@ extern (C++) class FuncDeclaration : Declaration // scopes from having the same name DsymbolTable localsymtab; VarDeclaration vthis; /// 'this' parameter (member and nested) - bool isThis2; /// has a dual-context 'this' parameter VarDeclaration v_arguments; /// '_arguments' parameter VarDeclaration v_argptr; /// '_argptr' variable @@ -278,31 +288,21 @@ extern (C++) class FuncDeclaration : Declaration FuncDeclaration overnext0; /// next in overload list (only used during IFTI) Loc endloc; /// location of closing curly bracket int vtblIndex = -1; /// for member functions, index into vtbl[] - bool naked; /// true if naked - bool generated; /// true if function was generated by the compiler rather than - /// supplied by the user - bool hasAlwaysInlines; /// contains references to functions that must be inlined - ubyte isCrtCtorDtor; /// has attribute pragma(crt_constructor(1)/crt_destructor(2)) - /// not set before the glue layer ILS inlineStatusStmt = ILS.uninitialized; ILS inlineStatusExp = ILS.uninitialized; PINLINE inlining = PINLINE.default_; int inlineNest; /// !=0 if nested inline - bool eh_none; /// true if no exception unwinding is needed - bool semantic3Errors; /// true if errors in semantic3 this function's frame ptr ForeachStatement fes; /// if foreach body, this is the foreach BaseClass* interfaceVirtual; /// if virtual, but only appears in base interface vtbl[] - bool introducing; /// true if 'introducing' function /** if !=NULL, then this is the type of the 'introducing' function this one is overriding */ Type tintro; - bool inferRetType; /// true if return type is to be inferred StorageClass storage_class2; /// storage class for template onemember's // Things that should really go into Scope @@ -314,8 +314,6 @@ extern (C++) class FuncDeclaration : Declaration /// 16 if there are multiple return statements int hasReturnExp; - // Support for NRVO (named return value optimization) - bool nrvo_can = true; /// true means we can do NRVO VarDeclaration nrvo_var; /// variable to replace with shidden Symbol* shidden; /// hidden pointer passed to function @@ -346,7 +344,9 @@ extern (C++) class FuncDeclaration : Declaration FuncDeclarations *inlinedNestedCallees; - uint flags; /// FUNCFLAG.xxxxx + /// Function flags: A collection of boolean packed for memory efficiency + /// See the `FUNCFLAG` enum + uint flags = FUNCFLAG.NRVO; /** * Data for a function declaration that is needed for the Objective-C @@ -374,7 +374,8 @@ extern (C++) class FuncDeclaration : Declaration /* The type given for "infer the return type" is a TypeFunction with * NULL for the return type. */ - inferRetType = (type && type.nextOf() is null); + if (type && type.nextOf() is null) + this.flags |= FUNCFLAG.inferRetType; } static FuncDeclaration create(const ref Loc loc, const ref Loc endloc, Identifier id, StorageClass storage_class, Type type, bool noreturn = false) @@ -480,7 +481,7 @@ extern (C++) class FuncDeclaration : Declaration return false; } - return !errors && !semantic3Errors; + return !errors && !this.hasSemantic3Errors(); } /**************************************************** @@ -515,9 +516,11 @@ extern (C++) class FuncDeclaration : Declaration */ extern (D) final void declareThis(Scope* sc) { - isThis2 = toParent2() != toParentLocal(); + const bool dualCtx = (toParent2() != toParentLocal()); + if (dualCtx) + this.flags |= FUNCFLAG.dualContext; auto ad = isThis(); - if (!isThis2 && !ad && !isNested()) + if (!dualCtx && !ad && !isNested()) { vthis = null; objc.selectorParameter = null; @@ -529,16 +532,16 @@ extern (C++) class FuncDeclaration : Declaration return t.addMod(type.mod).addStorageClass(storage_class); } - if (isThis2 || isNested()) + if (dualCtx || isNested()) { /* The 'this' for a nested function is the link to the * enclosing function's stack frame. * Note that nested functions and member functions are disjoint. */ - Type tthis = addModStc(isThis2 ? + Type tthis = addModStc(dualCtx ? Type.tvoidptr.sarrayOf(2).pointerTo() : Type.tvoid.pointerTo()); - vthis = new VarDeclaration(loc, tthis, isThis2 ? Id.this2 : Id.capture, null); + vthis = new VarDeclaration(loc, tthis, dualCtx ? Id.this2 : Id.capture, null); vthis.storage_class |= STC.parameter | STC.nodtor; } else if (ad) @@ -549,22 +552,6 @@ extern (C++) class FuncDeclaration : Declaration if (thandle.ty == Tstruct) { vthis.storage_class |= STC.ref_; - - /* if member function is marked 'inout', then 'this' is 'return ref' - * The same thing is done for `ref inout` parameters in TypeFunction's semantic routine. - */ - if (auto tf = type.isTypeFunction()) - { - /* This feature was a mistake, but existing code relies on it. - * So only disable it in @safe code and DIP1000 code - */ - if (!(global.params.useDIP1000 == FeatureState.enabled && - tf.trust == TRUST.safe)) - { - if (tf.isInOutQual()) - vthis.storage_class |= STC.return_; - } - } } } @@ -574,19 +561,8 @@ extern (C++) class FuncDeclaration : Declaration vthis.storage_class |= STC.return_; if (tf.isScopeQual) vthis.storage_class |= STC.scope_; - - /* Add STC.returnScope like typesem.d does for TypeFunction parameters, - * at least it should be the same. At the moment, we'll just - * do existing practice. But we should examine how TypeFunction does - * it, for consistency. - */ - if (global.params.useDIP1000 != FeatureState.enabled && - !tf.isref && isRefReturnScope(vthis.storage_class)) - { - /* if `ref return scope`, evaluate to `ref` `return scope` - */ + if (tf.isreturnscope) vthis.storage_class |= STC.returnScope; - } } if (flags & FUNCFLAG.inferScope && !(vthis.storage_class & STC.scope_)) vthis.storage_class |= STC.maybescope; @@ -1369,7 +1345,7 @@ extern (C++) class FuncDeclaration : Declaration if (!tf.isnogc) flags |= FUNCFLAG.nogcInprocess; - if (!isVirtual() || introducing) + if (!isVirtual() || this.isIntroducing()) flags |= FUNCFLAG.returnInprocess; // Initialize for inferring STC.scope_ @@ -1482,6 +1458,73 @@ extern (C++) class FuncDeclaration : Declaration return !(flags & FUNCFLAG.nogcInprocess) && isNogc(); } + final bool isNRVO() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.NRVO); + } + + final void isNRVO(bool v) pure nothrow @safe @nogc + { + if (v) this.flags |= FUNCFLAG.NRVO; + else this.flags &= ~FUNCFLAG.NRVO; + } + + final bool isNaked() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.naked); + } + + final bool isGenerated() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.generated); + } + + final void isGenerated(bool v) pure nothrow @safe @nogc + { + if (v) this.flags |= FUNCFLAG.generated; + else this.flags &= ~FUNCFLAG.generated; + } + + final bool isIntroducing() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.introducing); + } + + final bool hasSemantic3Errors() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.semantic3Errors); + } + + final bool hasNoEH() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.noEH); + } + + final bool inferRetType() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.inferRetType); + } + + final bool hasDualContext() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.dualContext); + } + + final bool hasAlwaysInlines() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.hasAlwaysInline); + } + + final bool isCrtCtor() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.CRTCtor); + } + + final bool isCrtDtor() const scope @safe pure nothrow @nogc + { + return !!(this.flags & FUNCFLAG.CRTDtor); + } + /************************************** * The function is doing something that may allocate with the GC, * so mark it as not nogc (not no-how). @@ -1809,19 +1852,19 @@ extern (C++) class FuncDeclaration : Declaration { auto ad = isThis(); ClassDeclaration cd = ad ? ad.isClassDeclaration() : null; - return (ad && !(cd && cd.isCPPclass()) && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !naked); + return (ad && !(cd && cd.isCPPclass()) && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked()); } bool addPostInvariant() { auto ad = isThis(); ClassDeclaration cd = ad ? ad.isClassDeclaration() : null; - return (ad && !(cd && cd.isCPPclass()) && ad.inv && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !naked); + return (ad && !(cd && cd.isCPPclass()) && ad.inv && global.params.useInvariants == CHECKENABLE.on && (visibility.kind == Visibility.Kind.protected_ || visibility.kind == Visibility.Kind.public_ || visibility.kind == Visibility.Kind.export_) && !this.isNaked()); } override const(char)* kind() const { - return generated ? "generated function" : "function"; + return this.isGenerated() ? "generated function" : "function"; } /******************************************** @@ -2163,7 +2206,7 @@ extern (C++) class FuncDeclaration : Declaration vresult.parent = this; } - if (sc && vresult.semanticRun == PASS.init) + if (sc && vresult.semanticRun == PASS.initial) { TypeFunction tf = type.toTypeFunction(); if (tf.isref) @@ -2609,35 +2652,124 @@ extern (C++) class FuncDeclaration : Declaration return fd; } - /****************** - * Check parameters and return type of D main() function. - * Issue error messages. - */ - extern (D) final void checkDmain() - { + /+ + + Checks the parameter and return types iff this is a `main` function. + + + + The following signatures are allowed for a `D main`: + + - Either no or a single parameter of type `string[]` + + - Return type is either `void`, `int` or `noreturn` + + + + The following signatures are standard C: + + - `int main()` + + - `int main(int, char**)` + + + + This function accepts the following non-standard extensions: + + - `char** envp` as a third parameter + + - `void` / `noreturn` as return type + + + + This function will issue errors for unexpected arguments / return types. + +/ + extern (D) final void checkMain() + { + if (ident != Id.main || isMember() || isNested()) + return; // Not a main function + TypeFunction tf = type.toTypeFunction(); + + Type retType = tf.nextOf(); + if (!retType) + { + // auto main(), check after semantic + assert(this.inferRetType); + return; + } + + /// Checks whether `t` is equivalent to `char**` + /// Ignores qualifiers and treats enums according to their base type + static bool isCharPtrPtr(Type t) + { + auto tp = t.toBasetype().isTypePointer(); + if (!tp) + return false; + + tp = tp.next.toBasetype().isTypePointer(); + if (!tp) + return false; + + return tp.next.toBasetype().ty == Tchar; + } + + // Neither of these qualifiers is allowed because they affect the ABI + enum invalidSTC = STC.out_ | STC.ref_ | STC.lazy_; + const nparams = tf.parameterList.length; bool argerr; - if (nparams == 1) + + if (linkage == LINK.d) { - auto fparam0 = tf.parameterList[0]; - auto t = fparam0.type.toBasetype(); - if (t.ty != Tarray || - t.nextOf().ty != Tarray || - t.nextOf().nextOf().ty != Tchar || - fparam0.storageClass & (STC.out_ | STC.ref_ | STC.lazy_)) + if (nparams == 1) { - argerr = true; + auto fparam0 = tf.parameterList[0]; + auto t = fparam0.type.toBasetype(); + if (t.ty != Tarray || + t.nextOf().ty != Tarray || + t.nextOf().nextOf().ty != Tchar || + fparam0.storageClass & invalidSTC) + { + argerr = true; + } } + + if (tf.parameterList.varargs || nparams >= 2 || argerr) + error("parameter list must be empty or accept one parameter of type `string[]`"); } - if (!tf.nextOf()) - // auto main(), check after semantic - assert(this.inferRetType); - else if (tf.nextOf().ty != Tint32 && tf.nextOf().ty != Tvoid && tf.nextOf().ty != Tnoreturn) + else if (linkage == LINK.c) + { + if (nparams == 2 || nparams == 3) + { + // Argument count must be int + auto argCount = tf.parameterList[0]; + argerr |= !!(argCount.storageClass & invalidSTC); + argerr |= argCount.type.toBasetype().ty != Tint32; + + // Argument pointer must be char** + auto argPtr = tf.parameterList[1]; + argerr |= !!(argPtr.storageClass & invalidSTC); + argerr |= !isCharPtrPtr(argPtr.type); + + // `char** environ` is a common extension, see J.5.1 of the C standard + if (nparams == 3) + { + auto envPtr = tf.parameterList[2]; + argerr |= !!(envPtr.storageClass & invalidSTC); + argerr |= !isCharPtrPtr(envPtr.type); + } + } + else + argerr = nparams != 0; + + // Disallow variadic main() - except for K&R declarations in C files. + // E.g. int main(), int main(argc, argv) int argc, char** argc { ... } + if (tf.parameterList.varargs && (!this.isCsymbol() || (!tf.parameterList.hasIdentifierList && nparams))) + argerr |= true; + + if (argerr) + { + error("parameters must match one of the following signatures"); + loc.errorSupplemental("`main()`"); + loc.errorSupplemental("`main(int argc, char** argv)`"); + loc.errorSupplemental("`main(int argc, char** argv, char** environ)` [POSIX extension]"); + } + } + else + return; // Neither C nor D main, ignore (should probably be an error) + + // Allow enums with appropriate base types (same ABI) + retType = retType.toBasetype(); + + if (retType.ty != Tint32 && retType.ty != Tvoid && retType.ty != Tnoreturn) error("must return `int`, `void` or `noreturn`, not `%s`", tf.nextOf().toChars()); - else if (tf.parameterList.varargs || nparams >= 2 || argerr) - error("parameters must be `main()` or `main(string[] args)`"); } /*********************************************** @@ -2649,7 +2781,7 @@ extern (C++) class FuncDeclaration : Declaration */ final bool checkNRVO() { - if (!nrvo_can || returns is null) + if (!isNRVO() || returns is null) return false; auto tf = type.toTypeFunction(); @@ -2661,7 +2793,7 @@ extern (C++) class FuncDeclaration : Declaration if (auto ve = rs.exp.isVarExp()) { auto v = ve.var.isVarDeclaration(); - if (!v || v.isOut() || v.isRef()) + if (!v || v.isReference()) return false; else if (nrvo_var is null) { @@ -2669,6 +2801,8 @@ extern (C++) class FuncDeclaration : Declaration // parameters and closure variables cannot be NRVOed. if (v.isDataseg() || v.isParameter() || v.toParent2() != this) return false; + if (v.nestedrefs.length && needsClosure()) + return false; // The variable type needs to be equivalent to the return type. if (!v.type.equivalent(tf.next)) return false; diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 6697a05..6b6655c 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -15,6 +15,7 @@ import core.stdc.stdint; import dmd.root.array; import dmd.root.filename; import dmd.common.outbuffer; +import dmd.file_manager; import dmd.identifier; /// Defines a setting for how compiler warnings and deprecations are handled @@ -329,6 +330,9 @@ extern (C++) struct Global bool hasMainFunction; /// Whether a main function has already been compiled in (for -main switch) uint varSequenceNumber = 1; /// Relative lifetime of `VarDeclaration` within a function, used for `scope` checks + /// Cache files read from disk + FileManager fileManager; + enum recursionLimit = 500; /// number of recursive template expansions before abort nothrow: @@ -383,6 +387,7 @@ extern (C++) struct Global extern (C++) void _init() { + this.fileManager = new FileManager(); version (MARS) { vendor = "Digital Mars D"; diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 9bbe0c9..2a33692 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -19,6 +19,8 @@ // Can't include arraytypes.h here, need to declare these directly. template <typename TYPE> struct Array; +class FileManager; + typedef unsigned char Diagnostic; enum { @@ -292,6 +294,8 @@ struct Global bool hasMainFunction; unsigned varSequenceNumber; + FileManager* fileManager; + /* Start gagging. Return the current number of gagged errors */ unsigned startGagging(); diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index f2552d4..a3afbe5 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -1836,25 +1836,12 @@ public: t = te.sym.memtype; goto L1; } + case Tchar: case Twchar: - // BUG: need to cast(wchar) case Tdchar: - // BUG: need to cast(dchar) - if (cast(uinteger_t)v > 0xFF) - { - buf.printf("'\\U%08llx'", cast(long)v); - break; - } - goto case; - case Tchar: { - size_t o = buf.length; - if (v == '\'') - buf.writestring("'\\''"); - else if (isprint(cast(int)v) && v != '\\') - buf.printf("'%c'", cast(int)v); - else - buf.printf("'\\x%02x'", cast(int)v); + const o = buf.length; + writeSingleCharLiteral(*buf, cast(dchar) v); if (hgs.ddoc) escapeDdocString(buf, o); break; @@ -2761,9 +2748,15 @@ bool stcToBuffer(OutBuffer* buf, StorageClass stc) bool result = false; if (stc & STC.scopeinferred) + { + //buf.writestring("scope-inferred "); stc &= ~(STC.scope_ | STC.scopeinferred); + } if (stc & STC.returninferred) + { + //buf.writestring("return-inferred "); stc &= ~(STC.return_ | STC.returninferred); + } /* Put scope ref return into a standard order */ diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d index ec44ee0..bcfbd9a 100644 --- a/gcc/d/dmd/importc.d +++ b/gcc/d/dmd/importc.d @@ -285,7 +285,7 @@ bool cFuncEquivalence(TypeFunction tf1, TypeFunction tf2) if (tf1.parameterList.length == 0 && tf2.parameterList.length == 0) return true; - if (!tf1.nextOf().equals(tf2.nextOf())) + if (!cTypeEquivalence(tf1.next, tf2.next)) return false; // function return types don't match if (tf1.parameterList.length != tf2.parameterList.length) @@ -318,3 +318,40 @@ bool cFuncEquivalence(TypeFunction tf1, TypeFunction tf2) //printf("t2: %s\n", tf2.toChars()); return true; } + +/******************************* + * Types haven't been merged yet, because we haven't done + * semantic() yet. + * But we still need to see if t1 and t2 are the same type. + * Params: + * t1 = first type + * t2 = second type + * Returns: + * true if they are equivalent types + */ +bool cTypeEquivalence(Type t1, Type t2) +{ + if (t1.equals(t2)) + return true; // that was easy + + if (t1.ty != t2.ty || t1.mod != t2.mod) + return false; + + if (auto tp = t1.isTypePointer()) + return cTypeEquivalence(tp.next, t2.nextOf()); + + if (auto ta = t1.isTypeSArray()) + // Bug: should check array dimension + return cTypeEquivalence(ta.next, t2.nextOf()); + + if (auto ts = t1.isTypeStruct()) + return ts.sym is t2.isTypeStruct().sym; + + if (auto te = t1.isTypeEnum()) + return te.sym is t2.isTypeEnum().sym; + + if (auto tf = t1.isTypeFunction()) + return cFuncEquivalence(tf, tf.isTypeFunction()); + + return false; +} diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h index c6c8c62..73dc4bb 100644 --- a/gcc/d/dmd/init.h +++ b/gcc/d/dmd/init.h @@ -114,4 +114,4 @@ public: void accept(Visitor *v) { v->visit(this); } }; -Expression *initializerToExpression(Initializer *init, Type *t = NULL); +Expression *initializerToExpression(Initializer *init, Type *t = NULL, const bool isCfile = false); diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index bc02bf9..649d88e 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -1080,10 +1080,11 @@ Initializer inferType(Initializer init, Scope* sc) * Params: * init = `Initializer` AST node * itype = if not `null`, type to coerce expression to + * isCfile = default initializers are different with C * Returns: * `Expression` created, `null` if cannot, `ErrorExp` for other errors */ -extern (C++) Expression initializerToExpression(Initializer init, Type itype = null) +extern (C++) Expression initializerToExpression(Initializer init, Type itype = null, const bool isCfile = false) { Expression visitVoid(VoidInitializer) { @@ -1204,7 +1205,7 @@ extern (C++) Expression initializerToExpression(Initializer init, Type itype = n if (!init.type) // don't know what type to use return null; if (!defaultInit) - defaultInit = (cast(TypeNext)t).next.defaultInit(Loc.initial); + defaultInit = (cast(TypeNext)t).next.defaultInit(Loc.initial, isCfile); element = defaultInit; } } diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index 3ff2eae..7cd4bfd 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -77,6 +77,7 @@ class Lexer bool doDocComment; // collect doc comment information bool anyToken; // seen at least one token bool commentToken; // comments are TOK.comment's + bool tokenizeNewlines; // newlines are turned into TOK.endOfLine's version (DMDLIB) { @@ -116,6 +117,7 @@ class Lexer line = p; this.doDocComment = doDocComment; this.commentToken = commentToken; + this.tokenizeNewlines = false; this.inTokenStringConstant = 0; this.lastDocLine = 0; //initKeywords(); @@ -227,6 +229,8 @@ class Lexer /**************************** * Turn next token in buffer into a token. + * Params: + * t = the token to set the resulting Token to */ final void scan(Token* t) { @@ -286,7 +290,15 @@ class Lexer case '\r': p++; if (*p != '\n') // if CR stands by itself + { endOfLine(); + if (tokenizeNewlines) + { + t.value = TOK.endOfLine; + tokenizeNewlines = false; + return; + } + } version (DMDLIB) { if (whitespaceToken) @@ -299,6 +311,12 @@ class Lexer case '\n': p++; endOfLine(); + if (tokenizeNewlines) + { + t.value = TOK.endOfLine; + tokenizeNewlines = false; + return; + } version (DMDLIB) { if (whitespaceToken) @@ -1045,6 +1063,10 @@ class Lexer return; case '#': { + // https://issues.dlang.org/show_bug.cgi?id=22825 + // Special token sequences are terminated by newlines, + // and should not be skipped over. + this.tokenizeNewlines = true; p++; if (parseSpecialTokenSequence()) continue; @@ -1064,6 +1086,12 @@ class Lexer { endOfLine(); p++; + if (tokenizeNewlines) + { + t.value = TOK.endOfLine; + tokenizeNewlines = false; + return; + } continue; } } @@ -2607,16 +2635,19 @@ class Lexer { auto linnum = this.scanloc.linnum; const(char)* filespec = null; - const loc = this.loc(); bool flags; if (!linemarker) scan(&tok); if (tok.value == TOK.int32Literal || tok.value == TOK.int64Literal) { - const lin = cast(int)(tok.unsvalue - 1); - if (lin != tok.unsvalue - 1) - error("line number `%lld` out of range", cast(ulong)tok.unsvalue); + const lin = cast(int)(tok.unsvalue); + if (lin != tok.unsvalue) + { + error(tok.loc, "line number `%lld` out of range", cast(ulong)tok.unsvalue); + skipToNextLine(); + return; + } else linnum = lin; } @@ -2624,15 +2655,19 @@ class Lexer { } else - goto Lerr; + { + error(tok.loc, "positive integer argument expected following `#line`"); + if (tok.value != TOK.endOfLine) + skipToNextLine(); + return; + } while (1) { - switch (*p) + scan(&tok); + switch (tok.value) { - case 0: - case 0x1A: - case '\n': - Lnewline: + case TOK.endOfFile: + case TOK.endOfLine: if (!inTokenStringConstant) { this.scanloc.linnum = linnum; @@ -2640,93 +2675,40 @@ class Lexer this.scanloc.filename = filespec; } return; - case '\r': - p++; - if (*p != '\n') - { - p--; - goto Lnewline; - } - continue; - case ' ': - case '\t': - case '\v': - case '\f': - p++; - continue; // skip white space - case '_': + case TOK.file: if (filespec || flags) goto Lerr; - if (memcmp(p, "__FILE__".ptr, 8) == 0) - { - p += 8; - filespec = mem.xstrdup(scanloc.filename); - continue; - } - goto Lerr; - case '"': + filespec = mem.xstrdup(scanloc.filename); + continue; + case TOK.string_: if (filespec || flags) goto Lerr; - stringbuffer.setsize(0); - p++; - while (1) - { - uint c; - c = *p; - switch (c) - { - case '\n': - case '\r': - case 0: - case 0x1A: - goto Lerr; - case '"': - stringbuffer.writeByte(0); - filespec = mem.xstrdup(cast(const(char)*)stringbuffer[].ptr); - p++; - break; - default: - if (c & 0x80) - { - uint u = decodeUTF(); - if (u == PS || u == LS) - goto Lerr; - } - stringbuffer.writeByte(c); - p++; - continue; - } - break; - } - continue; - - case '1': - case '2': - case '3': - case '4': - if (!linemarker) + if (tok.ptr[0] != '"' || tok.postfix != 0) goto Lerr; - flags = true; // linemarker flags seen - ++p; - if ('0' <= *p && *p <= '9') - goto Lerr; // only one digit allowed + filespec = tok.ustring; continue; - - default: - if (*p & 0x80) + case TOK.int32Literal: + if (!filespec) + goto Lerr; + if (linemarker && tok.unsvalue >= 1 && tok.unsvalue <= 4) { - uint u = decodeUTF(); - if (u == PS || u == LS) - goto Lnewline; + flags = true; // linemarker flags seen + continue; } goto Lerr; + default: + goto Lerr; } } Lerr: - if (linemarker) - error(loc, "# integer [\"filespec\"] { 1 | 2 | 3 | 4 }\\n expected"); - else - error(loc, "#line integer [\"filespec\"]\\n expected"); + if (filespec is null) + error(tok.loc, "invalid filename for `#line` directive"); + else if (linemarker) + error(tok.loc, "invalid flag for line marker directive"); + else if (!Ccompile) + error(tok.loc, "found `%s` when expecting new line following `#line` directive", tok.toChars()); + if (tok.value != TOK.endOfLine) + skipToNextLine(); } /*************************************** @@ -2768,6 +2750,7 @@ class Lexer break; } endOfLine(); + tokenizeNewlines = false; } /******************************************** @@ -3004,7 +2987,7 @@ private struct TimeStampInfo if (auto p = getenv("SOURCE_DATE_EPOCH")) { if (!ct.parseDigits(p.toDString())) - error(loc, "Value of environment variable `SOURCE_DATE_EPOCH` should be a valid UNIX timestamp, not: `%s`", p); + error(loc, "value of environment variable `SOURCE_DATE_EPOCH` should be a valid UNIX timestamp, not: `%s`", p); } else .time(&ct); diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 1494044..b2c7aa4 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -4198,6 +4198,8 @@ extern (C++) final class TypeFunction : TypeNext ParameterList parameterList; // function parameters + // These flags can be accessed like `bool` properties, + // getters and setters are generated for them private enum FunctionFlag : uint { none = 0, @@ -4206,13 +4208,13 @@ extern (C++) final class TypeFunction : TypeNext isproperty = 0x0004, // can be called without parentheses isref = 0x0008, // returns a reference isreturn = 0x0010, // 'this' is returned by ref - isscope = 0x0020, // 'this' is scope + isScopeQual = 0x0020, // 'this' is scope isreturninferred= 0x0040, // 'this' is return from inference isscopeinferred = 0x0080, // 'this' is scope from inference islive = 0x0100, // is @live incomplete = 0x0200, // return type or default arguments removed - inoutParam = 0x0400, // inout on the parameters - inoutQual = 0x0800, // inout on the qualifier + isInOutParam = 0x0400, // inout on the parameters + isInOutQual = 0x0800, // inout on the qualifier isctor = 0x1000, // the function is a constructor isreturnscope = 0x2000, // `this` is returned by value } @@ -4480,7 +4482,7 @@ extern (C++) final class TypeFunction : TypeNext { // Check escaping through return value Type tret = nextOf().toBasetype(); - if (isref || tret.hasPointers()) + if (isref || tret.hasPointers() || !isnothrow()) { return stc; } @@ -5084,177 +5086,29 @@ extern (C++) final class TypeFunction : TypeNext return false; } - /// set or get if the function has the `nothrow` attribute - bool isnothrow() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isnothrow) != 0; - } - /// ditto - void isnothrow(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isnothrow; - else funcFlags &= ~FunctionFlag.isnothrow; - } - - /// set or get if the function has the `@nogc` attribute - bool isnogc() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isnogc) != 0; - } - /// ditto - void isnogc(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isnogc; - else funcFlags &= ~FunctionFlag.isnogc; - } - - /// set or get if the function has the `@property` attribute - bool isproperty() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isproperty) != 0; - } - /// ditto - void isproperty(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isproperty; - else funcFlags &= ~FunctionFlag.isproperty; - } - - /// set or get if the function has the `ref` attribute - bool isref() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isref) != 0; - } - /// ditto - void isref(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isref; - else funcFlags &= ~FunctionFlag.isref; - } - - /// set or get if the function has the `return` attribute - bool isreturn() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isreturn) != 0; - } - /// ditto - void isreturn(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isreturn; - else funcFlags &= ~FunctionFlag.isreturn; - } - - /// set or get if the function has the `returnscope` attribute - bool isreturnscope() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isreturnscope) != 0; - } - /// ditto - void isreturnscope(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isreturnscope; - else funcFlags &= ~FunctionFlag.isreturnscope; - } - - /// set or get if the function has the `scope` attribute - bool isScopeQual() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isscope) != 0; - } - /// ditto - void isScopeQual(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isscope; - else funcFlags &= ~FunctionFlag.isscope; - } - - /// set or get if the function has the `return` attribute inferred - bool isreturninferred() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isreturninferred) != 0; - } - /// ditto - void isreturninferred(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isreturninferred; - else funcFlags &= ~FunctionFlag.isreturninferred; - } - - /// set or get if the function has the `scope` attribute inferred - bool isscopeinferred() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isscopeinferred) != 0; - } - /// ditoo - void isscopeinferred(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isscopeinferred; - else funcFlags &= ~FunctionFlag.isscopeinferred; - } - - /// set or get if the function has the `@live` attribute - bool islive() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.islive) != 0; - } - /// ditto - void islive(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.islive; - else funcFlags &= ~FunctionFlag.islive; - } - - /// set or get if the return type or the default arguments are removed - bool incomplete() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.incomplete) != 0; - } - /// ditto - void incomplete(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.incomplete; - else funcFlags &= ~FunctionFlag.incomplete; - } - - /// set or get if the function has the `inout` on the parameters - bool isInOutParam() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.inoutParam) != 0; - } - /// ditto - void isInOutParam(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.inoutParam; - else funcFlags &= ~FunctionFlag.inoutParam; - } + // Generate getter / setter functions for `FunctionFlag` members so they can be + // treated like regular `bool` fields, instead of requiring bit twiddling to read/write + extern (D) mixin(() { + string result = "extern(C++) pure nothrow @safe @nogc {"; + foreach (string mem; __traits(allMembers, FunctionFlag)) + { + result ~= " + /// set or get if the function has the FunctionFlag attribute of the same name + bool "~mem~"() const { return (funcFlags & FunctionFlag."~mem~") != 0; } + /// ditto + void "~mem~"(bool v) + { + if (v) funcFlags |= FunctionFlag."~mem~"; + else funcFlags &= ~FunctionFlag."~mem~"; + }"; + } + return result ~ "}\n"; + }()); - /// set or get if the function has the `inout` on the parameters - bool isInOutQual() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.inoutQual) != 0; - } - /// ditto - void isInOutQual(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.inoutQual; - else funcFlags &= ~FunctionFlag.inoutQual; - } /// Returns: `true` the function is `isInOutQual` or `isInOutParam` ,`false` otherwise. bool iswild() const pure nothrow @safe @nogc { - return (funcFlags & (FunctionFlag.inoutParam | FunctionFlag.inoutQual)) != 0; - } - - /// set or get if the function is a constructor - bool isctor() const pure nothrow @safe @nogc - { - return (funcFlags & FunctionFlag.isctor) != 0; - } - /// ditto - void isctor(bool v) pure nothrow @safe @nogc - { - if (v) funcFlags |= FunctionFlag.isctor; - else funcFlags &= ~FunctionFlag.isctor; + return (funcFlags & (FunctionFlag.isInOutParam | FunctionFlag.isInOutQual)) != 0; } /// Returns: whether `this` function type has the same attributes (`@safe`,...) as `other` @@ -6418,9 +6272,6 @@ extern (C++) final class TypeClass : Type override MOD deduceWild(Type t, bool isRef) { - // If sym is forward referenced: - if (sym.semanticRun < PASS.semanticdone && !sym.isBaseInfoComplete()) - sym.dsymbolSemantic(null); ClassDeclaration cd = t.isClassHandle(); if (cd && (sym == cd || cd.isBaseOf(sym, null))) return Type.deduceWild(t, isRef); @@ -7176,6 +7027,17 @@ extern (C++) final class Parameter : ASTNode extern (D) private static bool isCovariantScope(bool returnByRef, StorageClass from, StorageClass to) pure nothrow @nogc @safe { + // Workaround for failing covariance when finding a common type of delegates, + // some of which have parameters with inferred scope + // https://issues.dlang.org/show_bug.cgi?id=21285 + // The root cause is that scopeinferred is not part of the mangle, and mangle + // is used for type equality checks + if (to & STC.returninferred) + to &= ~STC.return_; + // note: f(return int* x) currently 'infers' scope without inferring `return`, in that case keep STC.scope + if (to & STC.scopeinferred && !(to & STC.return_)) + to &= ~STC.scope_; + if (from == to) return true; diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index d6735d4..2957b3a 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -137,9 +137,9 @@ public: override void visit(DeleteExp e) { - if (e.e1.op == EXP.variable) + if (VarExp ve = e.e1.isVarExp()) { - VarDeclaration v = (cast(VarExp)e.e1).var.isVarDeclaration(); + VarDeclaration v = ve.var.isVarDeclaration(); if (v && v.onstack) return; // delete for scope allocated class object } diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d index c2594fe..121a266 100644 --- a/gcc/d/dmd/ob.d +++ b/gcc/d/dmd/ob.d @@ -1747,7 +1747,7 @@ PtrState toPtrState(VarDeclaration v) */ auto t = v.type; - if (v.isRef()) + if (v.isReference()) { return t.hasMutableFields() ? PtrState.Borrowed : PtrState.Readonly; } @@ -1775,7 +1775,7 @@ bool hasPointersToMutableFields(Type t) { foreach (v; ts.sym.fields) { - if (v.isRef()) + if (v.isReference()) { if (v.type.hasMutableFields()) return true; @@ -1977,7 +1977,12 @@ void checkObErrors(ref ObState obstate) else if (isReadonlyPtr(v)) pvs.state = PtrState.Readonly; else + { + if (pvs.state == PtrState.Owner && v.type.hasPointersToMutableFields()) + v.error(e.loc, "assigning to Owner without disposing of owned value"); + pvs.state = PtrState.Owner; + } pvs.deps.zero(); EscapeByResults er; diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d index fc64377..dbd761f 100644 --- a/gcc/d/dmd/opover.d +++ b/gcc/d/dmd/opover.d @@ -711,7 +711,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (s) { functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, &args2); - if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors)) + if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); } @@ -720,7 +720,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (s_r) { functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, &args1); - if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors)) + if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); } @@ -793,7 +793,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (s_r) { functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, &args2); - if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors)) + if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); } @@ -802,7 +802,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (s) { functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, &args1); - if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors)) + if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); } @@ -1250,7 +1250,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) if (s) { functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, &args2); - if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors)) + if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) { return ErrorExp.get(); } @@ -1344,7 +1344,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop if (s) { functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, &args2); - if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors)) + if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) return ErrorExp.get(); } FuncDeclaration lastf = m.lastf; @@ -1352,7 +1352,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop if (s_r) { functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, &args1); - if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors)) + if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors())) return ErrorExp.get(); } if (m.count > 1) diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index 5a86931..3745a15d 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -504,6 +504,16 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) { eint = ei; } + else if (auto se = ep.e1.isSymOffExp()) + { + if (!se.var.isReference() && + !se.var.isImportedSymbol() && + se.var.isDataseg()) + { + var = se.var.isVarDeclaration(); + offset += se.offset; + } + } } return false; } @@ -531,7 +541,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) if (auto ae = e.e1.isIndexExp()) { // Convert &array[n] to &array+n - if (ae.e2.op == EXP.int64 && ae.e1.isVarExp()) + if (ae.e2.isIntegerExp() && ae.e1.isVarExp()) { sinteger_t index = ae.e2.toInteger(); VarExp ve = ae.e1.isVarExp(); @@ -541,8 +551,13 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) sinteger_t dim = ts.dim.toInteger(); if (index < 0 || index >= dim) { - e.error("array index %lld is out of bounds `[0..%lld]`", index, dim); - return error(); + /* 0 for C static arrays means size is unknown, no need to check + */ + if (!(dim == 0 && ve.var.isCsymbol())) + { + e.error("array index %lld is out of bounds `[0..%lld]`", index, dim); + return error(); + } } import core.checkedint : mulu; @@ -559,6 +574,33 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) return; } } + // Convert &((a.b)[n]) to (&a.b)+n + else if (ae.e2.isIntegerExp() && ae.e1.isDotVarExp()) + { + sinteger_t index = ae.e2.toInteger(); + DotVarExp ve = ae.e1.isDotVarExp(); + if (ve.type.isTypeSArray() && ve.var.isField() && ve.e1.isPtrExp()) + { + TypeSArray ts = ve.type.isTypeSArray(); + sinteger_t dim = ts.dim.toInteger(); + if (index < 0 || index >= dim) + { + /* 0 for C static arrays means size is unknown, no need to check + */ + if (!(dim == 0 && ve.var.isCsymbol())) + { + e.error("array index %lld is out of bounds `[0..%lld]`", index, dim); + return error(); + } + } + + auto pe = new AddrExp(e.loc, ve); + pe.type = e.type; + ret = new AddExp(e.loc, pe, ae.e2); + ret.type = e.type; + return; + } + } } } diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index f6472bf..7b1b63c 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -3651,7 +3651,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.traits: if (AST.TraitsExp te = cast(AST.TraitsExp) parsePrimaryExp()) - if (te.ident && te.args) + if (te.ident) { t = new AST.TypeTraits(token.loc, te); break; diff --git a/gcc/d/dmd/printast.d b/gcc/d/dmd/printast.d index 571c3fc..bba3481 100644 --- a/gcc/d/dmd/printast.d +++ b/gcc/d/dmd/printast.d @@ -209,5 +209,3 @@ extern (C++) final class PrintASTVisitor : Visitor putc(' ', stdout); } } - - diff --git a/gcc/d/dmd/root/aav.d b/gcc/d/dmd/root/aav.d index 5b8cc82..ba5d331 100644 --- a/gcc/d/dmd/root/aav.d +++ b/gcc/d/dmd/root/aav.d @@ -20,7 +20,7 @@ private size_t hash(size_t a) pure nothrow @nogc @safe return a ^ (a >> 7) ^ (a >> 4); } -struct KeyValueTemplate(K,V) +private struct KeyValueTemplate(K,V) { K key; V value; @@ -31,15 +31,17 @@ alias Value = void*; alias KeyValue = KeyValueTemplate!(Key, Value); -struct aaA +private struct aaA { +private: aaA* next; KeyValue keyValue; alias keyValue this; } -struct AA +private struct AA { +private: aaA** b; size_t b_length; size_t nodes; // total number of aaA nodes diff --git a/gcc/d/dmd/root/array.h b/gcc/d/dmd/root/array.h index 866b952..52bed5e 100644 --- a/gcc/d/dmd/root/array.h +++ b/gcc/d/dmd/root/array.h @@ -205,4 +205,3 @@ struct Array return data.ptr[--length]; } }; - diff --git a/gcc/d/dmd/root/bitarray.d b/gcc/d/dmd/root/bitarray.d index 42c09fa..90cbaed 100644 --- a/gcc/d/dmd/root/bitarray.d +++ b/gcc/d/dmd/root/bitarray.d @@ -187,6 +187,3 @@ nothrow pure unittest a = b; assert(a == b); } - - - diff --git a/gcc/d/dmd/root/file.d b/gcc/d/dmd/root/file.d index 1f33c18..a01cfdc 100644 --- a/gcc/d/dmd/root/file.d +++ b/gcc/d/dmd/root/file.d @@ -45,11 +45,6 @@ struct FileBuffer data = null; return result; } - - extern (C++) static FileBuffer* create() pure nothrow @safe - { - return new FileBuffer(); - } } /// @@ -78,12 +73,6 @@ struct File nothrow: /// Read the full content of a file. - extern (C++) static ReadResult read(const(char)* name) - { - return read(name.toDString()); - } - - /// Ditto static ReadResult read(const(char)[] name) { ReadResult result; @@ -179,24 +168,18 @@ nothrow: } /// Write a file, returning `true` on success. - extern (D) static bool write(const(char)* name, const void[] data) + static bool write(const(char)* name, const void[] data) { import dmd.common.file : writeFile; return writeFile(name, data); } ///ditto - extern(D) static bool write(const(char)[] name, const void[] data) + static bool write(const(char)[] name, const void[] data) { return name.toCStringThen!((fname) => write(fname.ptr, data)); } - /// ditto - extern (C++) static bool write(const(char)* name, const(void)* data, size_t size) - { - return write(name, data[0 .. size]); - } - /// Delete a file. extern (C++) static void remove(const(char)* name) { @@ -229,7 +212,7 @@ nothrow: * Returns: * `true` on success */ - extern (D) static bool update(const(char)* namez, const void[] data) + static bool update(const(char)* namez, const void[] data) { enum log = false; if (log) printf("update %s\n", namez); @@ -252,17 +235,11 @@ nothrow: } ///ditto - extern(D) static bool update(const(char)[] name, const void[] data) + static bool update(const(char)[] name, const void[] data) { return name.toCStringThen!(fname => update(fname.ptr, data)); } - /// ditto - extern (C++) static bool update(const(char)* name, const(void)* data, size_t size) - { - return update(name, data[0 .. size]); - } - /// Size of a file in bytes. /// Params: namez = null-terminated filename /// Returns: `ulong.max` on any error, the length otherwise. diff --git a/gcc/d/dmd/root/stringtable.d b/gcc/d/dmd/root/stringtable.d index 884a9f1..20316fa 100644 --- a/gcc/d/dmd/root/stringtable.d +++ b/gcc/d/dmd/root/stringtable.d @@ -224,7 +224,7 @@ public: } /// ditto - extern(D) int opApply(scope int delegate(const(StringValue!T)*) nothrow dg) nothrow + int opApply(scope int delegate(const(StringValue!T)*) nothrow dg) nothrow { foreach (const se; table) { diff --git a/gcc/d/dmd/sapply.d b/gcc/d/dmd/sapply.d index 7314d5b..26fba8f 100644 --- a/gcc/d/dmd/sapply.d +++ b/gcc/d/dmd/sapply.d @@ -177,4 +177,3 @@ public: doCond(s.statement) || applyTo(s); } } - diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index d237caf..5119576 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -275,7 +275,7 @@ private extern(C++) final class Semantic3Visitor : Visitor // Disable generated opAssign, because some members forbid identity assignment. funcdecl.storage_class |= STC.disable; funcdecl.fbody = null; // remove fbody which contains the error - funcdecl.semantic3Errors = false; + funcdecl.flags &= ~FUNCFLAG.semantic3Errors; } return; } @@ -285,7 +285,7 @@ private extern(C++) final class Semantic3Visitor : Visitor if (funcdecl.semanticRun >= PASS.semantic3) return; funcdecl.semanticRun = PASS.semantic3; - funcdecl.semantic3Errors = false; + funcdecl.flags &= ~FUNCFLAG.semantic3Errors; if (!funcdecl.type || funcdecl.type.ty != Tfunction) return; @@ -386,7 +386,7 @@ private extern(C++) final class Semantic3Visitor : Visitor // functions may be widely used by dmd-compiled projects. // It also gives more time for the implementation of dual-context // functions to be reworked as a frontend-only feature. - if (funcdecl.isThis2) + if (funcdecl.hasDualContext()) { funcdecl.deprecation("function requires a dual-context, which is deprecated"); if (auto ti = sc2.parent ? sc2.parent.isInstantiated() : null) @@ -603,7 +603,7 @@ private extern(C++) final class Semantic3Visitor : Visitor if (!funcdecl.fbody) funcdecl.fbody = new CompoundStatement(Loc.initial, new Statements()); - if (funcdecl.naked) + if (funcdecl.isNaked()) { fpreinv = null; // can't accommodate with no stack frame fpostinv = null; @@ -619,8 +619,8 @@ private extern(C++) final class Semantic3Visitor : Visitor f.next = Type.tvoid; if (f.checkRetType(funcdecl.loc)) funcdecl.fbody = new ErrorStatement(); - else if (funcdecl.isMain()) - funcdecl.checkDmain(); // Check main() parameters and return type + else + funcdecl.checkMain(); // Check main() parameters and return type } if (f.next !is null) @@ -654,7 +654,7 @@ private extern(C++) final class Semantic3Visitor : Visitor // handle NRVO if (!target.isReturnOnStack(f, funcdecl.needThis()) || !funcdecl.checkNRVO()) - funcdecl.nrvo_can = 0; + funcdecl.flags &= ~FUNCFLAG.NRVO; if (funcdecl.fbody.isErrorStatement()) { @@ -762,7 +762,7 @@ private extern(C++) final class Semantic3Visitor : Visitor /* Don't generate unwind tables for this function * https://issues.dlang.org/show_bug.cgi?id=17997 */ - funcdecl.eh_none = true; + funcdecl.flags |= FUNCFLAG.noEH; } if (funcdecl.flags & FUNCFLAG.nothrowInprocess) @@ -927,7 +927,7 @@ private extern(C++) final class Semantic3Visitor : Visitor /* https://issues.dlang.org/show_bug.cgi?id=10789 * If NRVO is not possible, all returned lvalues should call their postblits. */ - if (!funcdecl.nrvo_can) + if (!funcdecl.isNRVO()) exp = doCopyOrMove(sc2, exp, f.next); if (tret.hasPointers()) @@ -996,7 +996,7 @@ private extern(C++) final class Semantic3Visitor : Visitor freq = freq.statementSemantic(sc2); freq.blockExit(funcdecl, false); - funcdecl.eh_none = false; + funcdecl.flags &= ~FUNCFLAG.noEH; sc2 = sc2.pop(); @@ -1030,7 +1030,7 @@ private extern(C++) final class Semantic3Visitor : Visitor fens = fens.statementSemantic(sc2); fens.blockExit(funcdecl, false); - funcdecl.eh_none = false; + funcdecl.flags &= ~FUNCFLAG.noEH; sc2 = sc2.pop(); @@ -1159,7 +1159,7 @@ private extern(C++) final class Semantic3Visitor : Visitor const blockexit = s.blockExit(funcdecl, isnothrow); if (blockexit & BE.throw_) { - funcdecl.eh_none = false; + funcdecl.flags &= ~FUNCFLAG.noEH; if (isnothrow) error(funcdecl.loc, "%s `%s` may throw but is marked as `nothrow`", funcdecl.kind(), funcdecl.toPrettyChars()); else if (funcdecl.flags & FUNCFLAG.nothrowInprocess) @@ -1195,7 +1195,7 @@ private extern(C++) final class Semantic3Visitor : Visitor { // 'this' is the monitor vsync = new VarExp(funcdecl.loc, funcdecl.vthis); - if (funcdecl.isThis2) + if (funcdecl.hasDualContext()) { vsync = new PtrExp(funcdecl.loc, vsync); vsync = new IndexExp(funcdecl.loc, vsync, IntegerExp.literal!0); @@ -1230,7 +1230,7 @@ private extern(C++) final class Semantic3Visitor : Visitor } // Fix up forward-referenced gotos - if (funcdecl.gotos) + if (funcdecl.gotos && !funcdecl.isCsymbol()) { for (size_t i = 0; i < funcdecl.gotos.dim; ++i) { @@ -1238,7 +1238,7 @@ private extern(C++) final class Semantic3Visitor : Visitor } } - if (funcdecl.naked && (funcdecl.fensures || funcdecl.frequires)) + if (funcdecl.isNaked() && (funcdecl.fensures || funcdecl.frequires)) funcdecl.error("naked assembly functions with contracts are not supported"); sc2.ctorflow.callSuper = CSX.none; @@ -1370,7 +1370,10 @@ private extern(C++) final class Semantic3Visitor : Visitor * Otherwise, error gagging should be temporarily ungagged by functionSemantic3. */ funcdecl.semanticRun = PASS.semantic3done; - funcdecl.semantic3Errors = (global.errors != oldErrors) || (funcdecl.fbody && funcdecl.fbody.isErrorStatement()); + if ((global.errors != oldErrors) || (funcdecl.fbody && funcdecl.fbody.isErrorStatement())) + funcdecl.flags |= FUNCFLAG.semantic3Errors; + else + funcdecl.flags &= ~FUNCFLAG.semantic3Errors; if (funcdecl.type.ty == Terror) funcdecl.errors = true; //printf("-FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent.toChars(), toChars(), sc, loc.toChars()); diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d index 8b271f8..ae03b8a 100644 --- a/gcc/d/dmd/statement.d +++ b/gcc/d/dmd/statement.d @@ -1761,6 +1761,9 @@ extern (C++) final class GotoStatement : Statement return new GotoStatement(loc, ident); } + /************** + * Returns: true for error + */ extern (D) bool checkLabel() { if (!label.statement) diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index 6ffba68..c2967d6 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -211,7 +211,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor if (f.checkForwardRef(s.exp.loc)) s.exp = ErrorExp.get(); } - if (discardValue(s.exp)) + + if (!(sc.flags & SCOPE.Cfile) && discardValue(s.exp)) s.exp = ErrorExp.get(); s.exp = s.exp.optimize(WANTvalue); @@ -728,12 +729,12 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor Dsymbol sapply = null; // the inferred opApply() or front() function if (!inferForeachAggregate(sc, fs.op == TOK.foreach_, fs.aggr, sapply)) { - const(char)* msg = ""; - if (fs.aggr.type && isAggregate(fs.aggr.type)) - { - msg = ", define `opApply()`, range primitives, or use `.tupleof`"; - } - fs.error("invalid `foreach` aggregate `%s`%s", oaggr.toChars(), msg); + assert(oaggr.type); + + fs.error("invalid `foreach` aggregate `%s` of type `%s`", oaggr.toChars(), oaggr.type.toPrettyChars()); + if (isAggregate(fs.aggr.type)) + fs.loc.errorSupplemental("maybe define `opApply()`, range primitives, or use `.tupleof`"); + return setError(); } @@ -2310,12 +2311,12 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor needswitcherror = true; } - if (!sc.sw.sdefault && !(sc.flags & SCOPE.Cfile) && + if (!sc.sw.sdefault && (!ss.isFinal || needswitcherror || global.params.useAssert == CHECKENABLE.on)) { ss.hasNoDefault = 1; - if (!ss.isFinal && (!ss._body || !ss._body.isErrorStatement())) + if (!ss.isFinal && (!ss._body || !ss._body.isErrorStatement()) && !(sc.flags & SCOPE.Cfile)) ss.error("`switch` statement without a `default`; use `final switch` or add `default: assert(0);` or add `default: break;`"); // Generate runtime error if the default is hit @@ -2323,7 +2324,11 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor CompoundStatement cs; Statement s; - if (global.params.useSwitchError == CHECKENABLE.on && + if (sc.flags & SCOPE.Cfile) + { + s = new BreakStatement(ss.loc, null); // default for C is `default: break;` + } + else if (global.params.useSwitchError == CHECKENABLE.on && global.params.checkAction != CHECKACTION.halt) { if (global.params.checkAction == CHECKACTION.C) @@ -2365,7 +2370,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor ss._body = cs; } - if (ss.checkLabel()) + if (!(sc.flags & SCOPE.Cfile) && ss.checkLabel()) { sc.pop(); return setError(); @@ -3840,7 +3845,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor fd.gotos = new GotoStatements(); fd.gotos.push(gs); } - else if (gs.checkLabel()) + else if (!(sc.flags & SCOPE.Cfile) && gs.checkLabel()) return setError(); result = gs; @@ -3916,12 +3921,10 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } assert(sc.func); - // use setImpure/setGC when the deprecation cycle is over - PURE purity; - if (!(cas.stc & STC.pure_) && (purity = sc.func.isPureBypassingInference()) != PURE.impure && purity != PURE.fwdref) - cas.deprecation("`asm` statement is assumed to be impure - mark it with `pure` if it is not"); - if (!(cas.stc & STC.nogc) && sc.func.isNogcBypassingInference()) - cas.deprecation("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not"); + if (!(cas.stc & STC.pure_) && sc.func.setImpure()) + cas.error("`asm` statement is assumed to be impure - mark it with `pure` if it is not"); + if (!(cas.stc & STC.nogc) && sc.func.setGC()) + cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not"); if (!(cas.stc & (STC.trusted | STC.safe)) && sc.func.setUnsafe()) cas.error("`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not"); diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d index 1790996..43feab1 100644 --- a/gcc/d/dmd/tokens.d +++ b/gcc/d/dmd/tokens.d @@ -245,6 +245,7 @@ enum TOK : ubyte arrow, // -> colonColon, // :: wchar_tLiteral, + endOfLine, // \n, \r, \u2028, \u2029 whitespace, // C only keywords @@ -851,6 +852,7 @@ extern (C++) struct Token TOK.wcharLiteral: "wcharv", TOK.dcharLiteral: "dcharv", TOK.wchar_tLiteral: "wchar_tv", + TOK.endOfLine: "\\n", TOK.whitespace: "whitespace", // C only keywords @@ -945,20 +947,19 @@ nothrow: sprintf(&buffer[0], "%d", cast(int)intvalue); break; case TOK.uns32Literal: - case TOK.wcharLiteral: - case TOK.dcharLiteral: case TOK.wchar_tLiteral: sprintf(&buffer[0], "%uU", cast(uint)unsvalue); break; + case TOK.wcharLiteral: + case TOK.dcharLiteral: case TOK.charLiteral: - { - const v = cast(int)intvalue; - if (v >= ' ' && v <= '~') - sprintf(&buffer[0], "'%c'", v); - else - sprintf(&buffer[0], "'\\x%02x'", v); + { + OutBuffer buf; + buf.writeSingleCharLiteral(cast(dchar) intvalue); + buf.writeByte('\0'); + p = buf.extractSlice().ptr; + } break; - } case TOK.int64Literal: sprintf(&buffer[0], "%lldL", cast(long)intvalue); break; @@ -1090,7 +1091,7 @@ void writeCharLiteral(ref OutBuffer buf, dchar c) buf.writeByte('\\'); goto default; default: - if (c <= 0x7F) + if (c <= 0xFF) { if (isprint(c)) buf.writeByte(c); @@ -1114,3 +1115,40 @@ unittest } assert(buf.extractSlice() == `a\n\r\t\b\f\0\x11\u7233\U00017233`); } + +/** + * Write a single-quoted character literal + * + * Useful for printing '' char literals in e.g. error messages, ddoc, or the `.stringof` property + * + * Params: + * buf = buffer to append character in + * c = code point to write + */ +nothrow +void writeSingleCharLiteral(ref OutBuffer buf, dchar c) +{ + buf.writeByte('\''); + if (c == '\'') + buf.writeByte('\\'); + + if (c == '"') + buf.writeByte('"'); + else + writeCharLiteral(buf, c); + + buf.writeByte('\''); +} + +unittest +{ + OutBuffer buf; + writeSingleCharLiteral(buf, '\''); + assert(buf.extractSlice() == `'\''`); + buf.reset(); + writeSingleCharLiteral(buf, '"'); + assert(buf.extractSlice() == `'"'`); + buf.reset(); + writeSingleCharLiteral(buf, '\n'); + assert(buf.extractSlice() == `'\n'`); +} diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h index c404cab..f9b6062 100644 --- a/gcc/d/dmd/tokens.h +++ b/gcc/d/dmd/tokens.h @@ -254,6 +254,7 @@ enum class TOK : unsigned char arrow, // -> colonColon, // :: wchar_tLiteral, + endOfLine, // \n, \r, \u2028, \u2029 whitespace, // C only keywords diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index dbdcfd4..4b15e8c 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -80,10 +80,10 @@ private Dsymbol getDsymbolWithoutExpCtx(RootObject oarg) { if (auto e = isExpression(oarg)) { - if (e.op == EXP.dotVariable) - return (cast(DotVarExp)e).var; - if (e.op == EXP.dotTemplateDeclaration) - return (cast(DotTemplateExp)e).td; + if (auto dve = e.isDotVarExp()) + return dve.var; + if (auto dte = e.isDotTemplateExp()) + return dte.td; } return getDsymbol(oarg); } @@ -833,7 +833,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) e.error("argument `%s` has no visibility", o.toChars()); return ErrorExp.get(); } - if (s.semanticRun == PASS.init) + if (s.semanticRun == PASS.initial) s.dsymbolSemantic(null); auto protName = visibilityToString(s.visible().kind); // TODO: How about package(names) @@ -1053,9 +1053,9 @@ Expression semanticTraits(TraitsExp e, Scope* sc) } else if (e.ident == Id.getMember) { - if (ex.op == EXP.dotIdentifier) + if (auto die = ex.isDotIdExp()) // Prevent semantic() from replacing Symbol with its initializer - (cast(DotIdExp)ex).wantsym = true; + die.wantsym = true; ex = ex.expressionSemantic(scx); return ex; } @@ -2101,13 +2101,14 @@ Expression semanticTraits(TraitsExp e, Scope* sc) return ErrorExp.get(); } - if (sc.func is null) + auto fd = sc.getEnclosingFunction(); + if (!fd) { e.error("`__traits(parameters)` may only be used inside a function"); return ErrorExp.get(); } - assert(sc.func && sc.parent.isFuncDeclaration()); - auto tf = sc.parent.isFuncDeclaration.type.isTypeFunction(); + + auto tf = fd.type.isTypeFunction(); assert(tf); auto exps = new Expressions(0); int addParameterDG(size_t idx, Parameter x) @@ -2162,7 +2163,7 @@ private bool isSame(RootObject o1, RootObject o2, Scope* sc) { if (ea.op == EXP.function_) { - if (auto fe = cast(FuncExp)ea) + if (auto fe = ea.isFuncExp()) return fe.fd; } } diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index e5f839b..bcdbec5 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -978,7 +978,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) // duplicate a part of StructDeclaration::semanticTypeInfoMembers //printf("AA = %s, key: xeq = %p, xerreq = %p xhash = %p\n", toChars(), sd.xeq, sd.xerreq, sd.xhash); - if (sd.xeq && sd.xeq.generated && sd.xeq._scope && sd.xeq.semanticRun < PASS.semantic3done) + if (sd.xeq && sd.xeq.isGenerated() && sd.xeq._scope && sd.xeq.semanticRun < PASS.semantic3done) { uint errors = global.startGagging(); sd.xeq.semantic3(sd.xeq._scope); @@ -1431,12 +1431,6 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) errors = true; } - if ((fparam.storageClass & (STC.ref_ | STC.wild)) == (STC.ref_ | STC.wild)) - { - // 'ref inout' implies 'return' - fparam.storageClass |= STC.return_; - } - if (fparam.storageClass & STC.return_) { if (fparam.isReference()) @@ -1799,6 +1793,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) mtype.exp.ident != Id.derivedMembers && mtype.exp.ident != Id.getMember && mtype.exp.ident != Id.parent && + mtype.exp.ident != Id.parameters && mtype.exp.ident != Id.child && mtype.exp.ident != Id.toType && mtype.exp.ident != Id.getOverloads && @@ -3088,7 +3083,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type //static int nest; if (++nest == 50) *(char*)0=0; if (sc is null) { - error(loc, "Invalid scope."); + error(loc, "invalid scope"); return returnError(); } if (mt.inuse) @@ -4076,7 +4071,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) return e.expressionSemantic(sc); } } - if (d.semanticRun == PASS.init) + if (d.semanticRun == PASS.initial) d.dsymbolSemantic(null); checkAccess(e.loc, sc, e, d); auto ve = new VarExp(e.loc, d); @@ -4307,7 +4302,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) if (ident == Id.outer && mt.sym.vthis) { - if (mt.sym.vthis.semanticRun == PASS.init) + if (mt.sym.vthis.semanticRun == PASS.initial) mt.sym.vthis.dsymbolSemantic(null); if (auto cdp = mt.sym.toParentLocal().isClassDeclaration()) @@ -4503,7 +4498,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) Expression e1; Type t; /* returns: true to continue, false to return */ - if (f.isThis2) + if (f.hasDualContext()) { if (f.followInstantiationContext(ad)) { @@ -4560,7 +4555,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) } } //printf("e = %s, d = %s\n", e.toChars(), d.toChars()); - if (d.semanticRun == PASS.init) + if (d.semanticRun == PASS.initial) d.dsymbolSemantic(null); // If static function, get the most visible overload. diff --git a/gcc/d/dmd/utils.d b/gcc/d/dmd/utils.d index f8e7e48..67e4d86 100644 --- a/gcc/d/dmd/utils.d +++ b/gcc/d/dmd/utils.d @@ -63,7 +63,7 @@ FileBuffer readFile(Loc loc, const(char)[] filename) auto result = File.read(filename); if (!result.success) { - error(loc, "Error reading file `%.*s`", cast(int)filename.length, filename.ptr); + error(loc, "error reading file `%.*s`", cast(int)filename.length, filename.ptr); fatal(); } return FileBuffer(result.extractSlice()); diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 2a7fb69..61a2b50 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -1441,7 +1441,7 @@ public: gcc_assert (e->e1->op == EXP::variable); VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration (); - gcc_assert (v && v->onstack); + gcc_assert (v && v->onstack ()); libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration () ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER; diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc index 899648f..edc7912 100644 --- a/gcc/d/modules.cc +++ b/gcc/d/modules.cc @@ -141,7 +141,7 @@ get_internal_fn (tree ident, const Visibility &visibility) FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid, Identifier::idPool (name)); - fd->generated = true; + fd->isGenerated (true); fd->loc = Loc (mod->srcfile.toChars (), 1, 0); fd->parent = mod; fd->visibility = visibility; diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc index a25f7a5..d20c5c3 100644 --- a/gcc/d/toir.cc +++ b/gcc/d/toir.cc @@ -958,7 +958,7 @@ public: /* If returning via NRVO, just refer to the DECL_RESULT; this differs from using NULL_TREE in that it indicates that we care about the value of the DECL_RESULT. */ - if (this->func_->nrvo_can && this->func_->nrvo_var) + if (this->func_->isNRVO () && this->func_->nrvo_var) { add_stmt (return_expr (decl)); return; diff --git a/gcc/testsuite/gdc.dg/nrvo1.d b/gcc/testsuite/gdc.dg/nrvo1.d new file mode 100644 index 0000000..d93edfb --- /dev/null +++ b/gcc/testsuite/gdc.dg/nrvo1.d @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-additional-options "-fpreview=dip1000" } +ThreadInfo* ptr; + +ThreadInfo receiveOnly() +{ + ThreadInfo ret; + + get({ptr = &ret;}); + return ret; +} + +struct ThreadInfo +{ + ThreadInfo* next; +} + +bool get(T)(T) +{ + return false; +} + +void main() +{ + auto t = receiveOnly(); + assert(&t == ptr); +} diff --git a/gcc/testsuite/gdc.test/compilable/Test16206.d b/gcc/testsuite/gdc.test/compilable/Test16206.d index 0b9ccf3..c52c710 100644 --- a/gcc/testsuite/gdc.test/compilable/Test16206.d +++ b/gcc/testsuite/gdc.test/compilable/Test16206.d @@ -25,4 +25,4 @@ static assert(S.foo!([]) == 0); alias fooFuns = AliasSeq!(__traits(getOverloads, S, "foo")); static assert(fooFuns.length == 1); -static assert(fooFuns[0]("") == 2);
\ No newline at end of file +static assert(fooFuns[0]("") == 2); diff --git a/gcc/testsuite/gdc.test/compilable/aliasassign.d b/gcc/testsuite/gdc.test/compilable/aliasassign.d index e355e49..a29836e 100644 --- a/gcc/testsuite/gdc.test/compilable/aliasassign.d +++ b/gcc/testsuite/gdc.test/compilable/aliasassign.d @@ -38,4 +38,3 @@ alias TK2 = reverse!(int, const uint, X2); static assert(TK2[0] == 3); static assert(is(TK2[1] == const(uint))); static assert(is(TK2[2] == int)); - diff --git a/gcc/testsuite/gdc.test/compilable/art4769.d b/gcc/testsuite/gdc.test/compilable/art4769.d index dfffe77..0629606 100644 --- a/gcc/testsuite/gdc.test/compilable/art4769.d +++ b/gcc/testsuite/gdc.test/compilable/art4769.d @@ -16,4 +16,3 @@ struct Vector(T) { } } - diff --git a/gcc/testsuite/gdc.test/compilable/b21285.d b/gcc/testsuite/gdc.test/compilable/b21285.d index 482faa7..fb14fee 100644 --- a/gcc/testsuite/gdc.test/compilable/b21285.d +++ b/gcc/testsuite/gdc.test/compilable/b21285.d @@ -1,4 +1,5 @@ // REQUIRED_ARGS: -unittest +// PERMUTE_ARGS: -preview=dip1000 // Issue 21285 - Delegate covariance broken between 2.092 and 2.094 (git master). unittest { @@ -25,3 +26,36 @@ unittest static assert(is(typeof(a[0]) == dg)); static assert(is(typeof(ab[0]) == fn)); } + +int f(string s) { throw new Exception(""); } +void main() +{ + string path; + int bank, preset; + void delegate(string value)[string] aa = [ + "path": (string arg) { + path = arg; + }, + "bank": (string arg) { + bank = f(arg); + }, + "preset": (string arg) { + preset = f(arg); + }, + ]; + + string delegate(string value)[string] aa2 = [ + "path": (string arg) { + path = arg; + return arg; + }, + "bank": (string arg) { + bank = f(arg); + return arg; + }, + "preset": (string arg) { + preset = f(arg); + return arg; + }, + ]; +} diff --git a/gcc/testsuite/gdc.test/compilable/b33.d b/gcc/testsuite/gdc.test/compilable/b33.d index cba6fe2..72452b6 100644 --- a/gcc/testsuite/gdc.test/compilable/b33.d +++ b/gcc/testsuite/gdc.test/compilable/b33.d @@ -9,4 +9,3 @@ size_t fn() { return find( "123" ); } - diff --git a/gcc/testsuite/gdc.test/compilable/b6395.d b/gcc/testsuite/gdc.test/compilable/b6395.d index 94f4bc3..3910ffa 100644 --- a/gcc/testsuite/gdc.test/compilable/b6395.d +++ b/gcc/testsuite/gdc.test/compilable/b6395.d @@ -22,4 +22,3 @@ void applyNoRemoveRegex() auto a = find!((a){return match(e);})(map!regex(noRemoveStr)); } } - diff --git a/gcc/testsuite/gdc.test/compilable/b9490.d b/gcc/testsuite/gdc.test/compilable/b9490.d index d0148b1..433163d 100644 --- a/gcc/testsuite/gdc.test/compilable/b9490.d +++ b/gcc/testsuite/gdc.test/compilable/b9490.d @@ -36,4 +36,3 @@ void main() f(s1.s.tupleof); // OK f((s1.s).tupleof); // Error: need 'this' to access member s } - diff --git a/gcc/testsuite/gdc.test/compilable/betterCarray.d b/gcc/testsuite/gdc.test/compilable/betterCarray.d index 3f48b04..3e9a881 100644 --- a/gcc/testsuite/gdc.test/compilable/betterCarray.d +++ b/gcc/testsuite/gdc.test/compilable/betterCarray.d @@ -4,7 +4,8 @@ import core.stdc.stdio; -extern (C) int main(char** argv, int argc) { +extern (C) int main() +{ printf("hello world\n"); int[3] a; foo(a[], 3); diff --git a/gcc/testsuite/gdc.test/compilable/betterCswitch.d b/gcc/testsuite/gdc.test/compilable/betterCswitch.d index ab0fb0a..a140ea9 100644 --- a/gcc/testsuite/gdc.test/compilable/betterCswitch.d +++ b/gcc/testsuite/gdc.test/compilable/betterCswitch.d @@ -1,6 +1,7 @@ import core.stdc.stdio; -extern (C) int main(char** argv, int argc) { +extern (C) int main() +{ printf("hello world\n"); foo(3); return 0; diff --git a/gcc/testsuite/gdc.test/compilable/ccompile.d b/gcc/testsuite/gdc.test/compilable/ccompile.d index 22c749c..cb6e3de 100644 --- a/gcc/testsuite/gdc.test/compilable/ccompile.d +++ b/gcc/testsuite/gdc.test/compilable/ccompile.d @@ -32,5 +32,3 @@ void funchds(char *p_adults) } } } - - diff --git a/gcc/testsuite/gdc.test/compilable/cdcmp.d b/gcc/testsuite/gdc.test/compilable/cdcmp.d index 4248818..305f097b 100644 --- a/gcc/testsuite/gdc.test/compilable/cdcmp.d +++ b/gcc/testsuite/gdc.test/compilable/cdcmp.d @@ -145,4 +145,3 @@ bool test_eq(double x, double y) { return x == y; } bool test_ne(double x, double y) { return x != y; } bool test_ge(double x, double y) { return x >= y; } bool test_gt(double x, double y) { return x > y; } - diff --git a/gcc/testsuite/gdc.test/compilable/const.d b/gcc/testsuite/gdc.test/compilable/const.d index 9b97037..dc3d471 100644 --- a/gcc/testsuite/gdc.test/compilable/const.d +++ b/gcc/testsuite/gdc.test/compilable/const.d @@ -37,5 +37,3 @@ static assert(6.0 % 4.0 == 2); static assert(6.0i % 2.0i == 0); static assert(6.0i % 3.0i == 0); static assert(6.0i % 4.0i == 2i); - - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc1.d b/gcc/testsuite/gdc.test/compilable/ddoc1.d index 23e721d..0a27eda 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc1.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc1.d @@ -47,7 +47,7 @@ wchar YY; /// ditto * argulid = the argument * u = the other argument */ -int foo(char c, int argulid, char u); +int foo(char c, int argulid, char u = '\'', wchar v = '\u7233', dchar y = '\U00017233'); int barr() { return 3; } /// doc for barr() diff --git a/gcc/testsuite/gdc.test/compilable/ddoc11.d b/gcc/testsuite/gdc.test/compilable/ddoc11.d index 0082455..683cd5f 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc11.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc11.d @@ -62,8 +62,3 @@ private: void test1() { } - - - - - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc12706.d b/gcc/testsuite/gdc.test/compilable/ddoc12706.d index a19ba21..a0c9b3f 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc12706.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc12706.d @@ -6,4 +6,3 @@ void test()(string[] args) if (args[$]) { } - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc12745.d b/gcc/testsuite/gdc.test/compilable/ddoc12745.d index a2cf74b..c4bd7fb 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc12745.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc12745.d @@ -22,4 +22,4 @@ $(BR) 1__a $(BR) 2__b */ -int i;
\ No newline at end of file +int i; diff --git a/gcc/testsuite/gdc.test/compilable/ddoc13.d b/gcc/testsuite/gdc.test/compilable/ddoc13.d index 9985bb0..cc69a25 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc13.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc13.d @@ -23,4 +23,3 @@ struct Bug4107b(T) { } } } - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc14.d b/gcc/testsuite/gdc.test/compilable/ddoc14.d index fae99d4..ed71d05 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc14.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc14.d @@ -92,6 +92,3 @@ pure nothrow auto mAutoPrefix(ref P p) { return p; } /// 7 auto mAutoTemplateSuffix(alias T)(ref T t) pure nothrow { return p; } /// 9 pure nothrow: V mColon(lazy P p) {} /// 10 - - - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc2.d b/gcc/testsuite/gdc.test/compilable/ddoc2.d index 2a7e457..5a56141 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc2.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc2.d @@ -39,4 +39,3 @@ class StreamException: Exception { /********** stars ***************/ int stars; } - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc2273.d b/gcc/testsuite/gdc.test/compilable/ddoc2273.d index ec3b74a..4a1b075 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc2273.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc2273.d @@ -34,4 +34,3 @@ template staticIndexOf(T, TList...) { alias int staticIndexOf; } alias staticIndexOf IndexOf; void main() { } - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc3.d b/gcc/testsuite/gdc.test/compilable/ddoc3.d index 3b47497..ad4c214 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc3.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc3.d @@ -68,4 +68,3 @@ class StreamException: Exception { /********** stars ***************/ int stars; } - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc5.d b/gcc/testsuite/gdc.test/compilable/ddoc5.d index 5a964f3..d0b5655 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc5.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc5.d @@ -28,4 +28,3 @@ class TestMembers(TemplateArg) void main() { } - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc6.d b/gcc/testsuite/gdc.test/compilable/ddoc6.d index 69bd64a..a229dc5 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc6.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc6.d @@ -22,4 +22,3 @@ void main() C:\code\d\bugs>dmd -D -o- 148_1.d 148_1.d(6): Error: static if conditional cannot be at global scope +/ - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc6491.d b/gcc/testsuite/gdc.test/compilable/ddoc6491.d index 5fe37a3..cf93399 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc6491.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc6491.d @@ -10,5 +10,3 @@ enum int c6491 = 4; /// test void bug6491a(int a = ddoc6491.c6491, string b = core.cpuid.vendor); - - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc7.d b/gcc/testsuite/gdc.test/compilable/ddoc7.d index 9c28d1b..eba3680 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc7.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc7.d @@ -56,4 +56,3 @@ class C /// Some doc abstract void foo(); } - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc9369.d b/gcc/testsuite/gdc.test/compilable/ddoc9369.d index ba44891..30b4c11 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc9369.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc9369.d @@ -13,6 +13,3 @@ writeln(&a); --- */ void foo() { } - - - diff --git a/gcc/testsuite/gdc.test/compilable/ddoc9475.d b/gcc/testsuite/gdc.test/compilable/ddoc9475.d index 262fa7d..396bdb1 100644 --- a/gcc/testsuite/gdc.test/compilable/ddoc9475.d +++ b/gcc/testsuite/gdc.test/compilable/ddoc9475.d @@ -26,4 +26,3 @@ unittest { // bar comment } - diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_AnonDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_AnonDeclaration.d index bcf5558..9d68631 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_AnonDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_AnonDeclaration.d @@ -50,7 +50,6 @@ struct S final { int32_t y; double z; - extern "C" void foo(); void bar(); }; struct diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d index 6274e9f..4f13d2b 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d @@ -82,7 +82,9 @@ public: int32_t a; C* c; virtual void foo(); - extern "C" virtual void bar(); +private: + virtual void __vtable_slot_0(); +public: virtual void baz(int32_t x = 42); struct { @@ -116,7 +118,7 @@ public: { public: int32_t x; - A* this; + A* outer; }; typedef Inner I; @@ -146,8 +148,8 @@ public: class Parent { - virtual void __vtable_slot_0(); virtual void __vtable_slot_1(); + virtual void __vtable_slot_2(); public: virtual void foo(); }; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_StructDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_StructDeclaration.d index 2d48999..4d56c7c 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_StructDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_StructDeclaration.d @@ -45,6 +45,9 @@ struct S final int32_t b; int64_t c; _d_dynamicArray< int32_t > arr; +private: + ~S(); +public: S() : a(), b(), @@ -81,7 +84,6 @@ struct S3 final int32_t a; int32_t b; int64_t c; - extern "C" S3(int32_t a); S3() : a(42), b(), @@ -143,7 +145,6 @@ struct A final { int32_t a; S s; - extern "C" void bar(); void baz(int32_t x = 42); struct { @@ -232,6 +233,7 @@ extern (C++) struct S int b; long c; int[] arr; + extern(D) ~this() {} } extern (C++) struct S2 diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_VarDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_VarDeclaration.d index f9e57f9..7356ba3 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_VarDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_VarDeclaration.d @@ -39,7 +39,7 @@ struct _d_dynamicArray final }; #endif #if !defined(_d_real) -# define _d_real long double +#define _d_real long double #endif extern "C" int32_t z; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_extern_type.d b/gcc/testsuite/gdc.test/compilable/dtoh_extern_type.d index 91641a6..0426a5e 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_extern_type.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_extern_type.d @@ -40,7 +40,7 @@ struct _d_dynamicArray final }; #endif #if !defined(_d_real) -# define _d_real long double +#define _d_real long double #endif class ClassFromStruct final diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_ignored.d b/gcc/testsuite/gdc.test/compilable/dtoh_ignored.d index 1e1b887..d687673 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_ignored.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_ignored.d @@ -39,7 +39,7 @@ struct _d_dynamicArray final }; #endif #if !defined(_d_real) -# define _d_real long double +#define _d_real long double #endif class WithImaginary diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_mangling.d b/gcc/testsuite/gdc.test/compilable/dtoh_mangling.d new file mode 100644 index 0000000..44d0dd5 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/dtoh_mangling.d @@ -0,0 +1,118 @@ +/++ +REQUIRED_ARGS: -HC=verbose +TEST_OUTPUT: +--- +// Automatically generated by Digital Mars D Compiler v$n$ + +#pragma once + +#include <assert.h> +#include <stddef.h> +#include <stdint.h> +#include <math.h> + +#ifdef CUSTOM_D_ARRAY_TYPE +#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE +#else +/// Represents a D [] array +template<typename T> +struct _d_dynamicArray final +{ + size_t length; + T *ptr; + + _d_dynamicArray() : length(0), ptr(NULL) { } + + _d_dynamicArray(size_t length_in, T *ptr_in) + : length(length_in), ptr(ptr_in) { } + + T& operator[](const size_t idx) { + assert(idx < length); + return ptr[idx]; + } + + const T& operator[](const size_t idx) const { + assert(idx < length); + return ptr[idx]; + } +}; +#endif + +extern "C" int32_t freeC(); + +// Ignored function dtoh_mangling.bar because C++ doesn't support explicit mangling +struct Data final +{ + // Ignored function dtoh_mangling.Data.foo because of linkage + // Ignored function dtoh_mangling.Data.bar because C++ doesn't support explicit mangling + Data() + { + } +}; + +extern void accept(Data data); + +extern "C" void hasDefault(int32_t i = freeC()); + +extern "C" void hasDefaultMember(int32_t i = memberC()); + +extern "C" int32_t someVarC; + +// Ignored variable dtoh_mangling.var2 because C++ doesn't support explicit mangling +struct HasMangleMember final +{ + int32_t someAttrC; + int32_t someAttrCpp; + void hasDefaultVar(int32_t i = someAttrC); + HasMangleMember() + { + } +}; + +extern "C" void hasDefaultVar(int32_t i = someVarC); +--- +++/ + +extern(C): + +pragma(mangle, "freeC") +int foo() { return 0; } + +pragma(mangle, "freeCpp") +extern (C++) void bar() {} + +pragma(mangle, "Aggregate") +struct Data +{ + pragma(mangle, "memberC") + static int foo() { return 0; } + + pragma(mangle, "memberCpp") + extern (C++) void bar() {} +} + +extern(C++) +void accept(Data data) {} + +void hasDefault(int i = foo()) {} + +void hasDefaultMember(int i = Data.foo()) {} + +pragma(mangle, "someVarC") +__gshared int var; + +pragma(mangle, "someVarCpp") +extern(C++) __gshared int var2; + +struct HasMangleMember +{ + pragma(mangle, "someAttrC") + int var; + + pragma(mangle, "someAttrCpp") + extern(C++) int var2; + + extern(C++) void hasDefaultVar(int i = var) {} +} + +void hasDefaultVar(int i = var) {} diff --git a/gcc/testsuite/gdc.test/compilable/extra-files/header1.d b/gcc/testsuite/gdc.test/compilable/extra-files/header1.d index 01cf889..3c2e90a 100644 --- a/gcc/testsuite/gdc.test/compilable/extra-files/header1.d +++ b/gcc/testsuite/gdc.test/compilable/extra-files/header1.d @@ -577,7 +577,8 @@ struct SafeS ref SafeS foo3() return scope { - return this; + static SafeS s; + return s; } int* p; diff --git a/gcc/testsuite/gdc.test/compilable/fail137.d b/gcc/testsuite/gdc.test/compilable/fail137.d index c6876d1..1d49be6 100644 --- a/gcc/testsuite/gdc.test/compilable/fail137.d +++ b/gcc/testsuite/gdc.test/compilable/fail137.d @@ -23,4 +23,3 @@ void main() TypeTuple!(int, long) T; printf( "%u\n", cast(uint)IndexOf!(long, T) ); } - diff --git a/gcc/testsuite/gdc.test/compilable/fix17686.d b/gcc/testsuite/gdc.test/compilable/fix17686.d index db82252..76730ed 100644 --- a/gcc/testsuite/gdc.test/compilable/fix17686.d +++ b/gcc/testsuite/gdc.test/compilable/fix17686.d @@ -42,4 +42,3 @@ void main() { alias aaa = DOMImplementation!string; } - diff --git a/gcc/testsuite/gdc.test/compilable/fix20416.d b/gcc/testsuite/gdc.test/compilable/fix20416.d index 19ad74d..341eec3 100644 --- a/gcc/testsuite/gdc.test/compilable/fix20416.d +++ b/gcc/testsuite/gdc.test/compilable/fix20416.d @@ -33,4 +33,3 @@ S bar2() S result; return result.foo(); } - diff --git a/gcc/testsuite/gdc.test/compilable/fix21647.d b/gcc/testsuite/gdc.test/compilable/fix21647.d index c1e1c48..58f1440 100644 --- a/gcc/testsuite/gdc.test/compilable/fix21647.d +++ b/gcc/testsuite/gdc.test/compilable/fix21647.d @@ -35,4 +35,3 @@ pragma(msg, V); struct G {} struct F(T) { void f(ref T) {} } pragma(msg, F!G().f(G.init)); - diff --git a/gcc/testsuite/gdc.test/compilable/fix22291.d b/gcc/testsuite/gdc.test/compilable/fix22291.d index 4090c5e..36baef5 100644 --- a/gcc/testsuite/gdc.test/compilable/fix22291.d +++ b/gcc/testsuite/gdc.test/compilable/fix22291.d @@ -20,6 +20,33 @@ int echoPlusOne(int x) return x; } static assert(echoPlusOne(1) == 2); + +void nesting(double d, int i) +{ + alias EXP = AliasSeq!(d, i); + + if (d) + { + static assert(__traits(isSame, __traits(parameters), EXP)); + + while (d) + { + static assert(__traits(isSame, __traits(parameters), EXP)); + switch (i) + { + static assert(__traits(isSame, __traits(parameters), EXP)); + case 1: + static assert(__traits(isSame, __traits(parameters), EXP)); + break; + + default: + static assert(__traits(isSame, __traits(parameters), EXP)); + break; + } + } + } +} + class Tree { int opApply(int delegate(size_t, Tree) dg) { if (dg(0, this)) return 1; @@ -34,7 +61,22 @@ void useOpApply(Tree top, int x) } foreach(idx, elem; top) { - static assert(is(typeof(__traits(parameters)) == AliasSeq!(size_t, Tree))); + static assert(is(typeof(__traits(parameters)) == AliasSeq!(Tree, int))); + } + + foreach(idx, elem; top) + { + foreach (idx2, elem2; elem) + static assert(is(typeof(__traits(parameters)) == AliasSeq!(Tree, int))); + } + + foreach(idx, elem; top) + { + static void foo(char[] text) + { + foreach (const char c; text) + static assert(is(typeof(__traits(parameters)) == AliasSeq!(char[]))); + } } } class Test @@ -132,3 +174,64 @@ T testTemplate(T)(scope T input) static assert(testTemplate!long(420) == 0); +void qualifiers(immutable int a, const bool b) +{ + static assert(is(typeof(__traits(parameters)) == AliasSeq!(immutable int, const bool))); +} + +int makeAggregate(int a, bool b) +{ + struct S + { + typeof(__traits(parameters)) members; + } + + S s = S(__traits(parameters)); + assert(s.members[0] == a); + assert(s.members[1] == b); + return 1; +} + +static assert(makeAggregate(5, true)); + +int makeAlias(int a, bool b) +{ + alias Params = __traits(parameters); + assert(Params[0] == 3); + assert(Params[1] == true); + return 1; +} + +static assert(makeAlias(3, true)); + + +mixin template nestedCheckParameters(int unique) +{ + alias NestedNames = __traits(parameters); + version (Fixed) + alias Types = typeof(Names); +} + +mixin template checkParameters(int unique) +{ + mixin nestedCheckParameters!unique; + + alias Names = __traits(parameters); + alias Types = typeof(Names); +} + +int makeAggregateMixin(immutable int a, const bool b) +{ + mixin checkParameters!0; + + struct S + { + mixin checkParameters!1; + typeof(Names) members; + } + + S s = S(Names); + assert(s.members[0] == a); + assert(s.members[1] == b); + return 1; +} diff --git a/gcc/testsuite/gdc.test/compilable/ice20092.d b/gcc/testsuite/gdc.test/compilable/ice20092.d index ff2be37..5deef96 100644 --- a/gcc/testsuite/gdc.test/compilable/ice20092.d +++ b/gcc/testsuite/gdc.test/compilable/ice20092.d @@ -7,4 +7,3 @@ void front(T)(T[] a) { static assert(is(T == void)); } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/art4769a.d b/gcc/testsuite/gdc.test/compilable/imports/art4769a.d index 7c994e6..e7f59ec 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/art4769a.d +++ b/gcc/testsuite/gdc.test/compilable/imports/art4769a.d @@ -12,4 +12,3 @@ template DataStreamability(T) printf("hallo\n"); } } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/art4769b.d b/gcc/testsuite/gdc.test/compilable/imports/art4769b.d index e43b2f2..a94f837 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/art4769b.d +++ b/gcc/testsuite/gdc.test/compilable/imports/art4769b.d @@ -6,4 +6,3 @@ int main(char [][] args) Vector!(wchar) str; return 0; } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/b33a.d b/gcc/testsuite/gdc.test/compilable/imports/b33a.d index bd8fd0c..dc5f094 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/b33a.d +++ b/gcc/testsuite/gdc.test/compilable/imports/b33a.d @@ -23,6 +23,3 @@ template find() return find_!(char).fn( buf ); } } - - - diff --git a/gcc/testsuite/gdc.test/compilable/imports/b3682.d b/gcc/testsuite/gdc.test/compilable/imports/b3682.d index f554e12..ab0a09a 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/b3682.d +++ b/gcc/testsuite/gdc.test/compilable/imports/b3682.d @@ -2,4 +2,3 @@ module imports.b3682; import a3682; alias Tuple!(int) tint; - diff --git a/gcc/testsuite/gdc.test/compilable/imports/defaa.d b/gcc/testsuite/gdc.test/compilable/imports/defaa.d index c35167c..e0be575 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/defaa.d +++ b/gcc/testsuite/gdc.test/compilable/imports/defaa.d @@ -10,6 +10,3 @@ class Display this() { } } - - - diff --git a/gcc/testsuite/gdc.test/compilable/imports/defab.d b/gcc/testsuite/gdc.test/compilable/imports/defab.d index 84b9209..901dbd2 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/defab.d +++ b/gcc/testsuite/gdc.test/compilable/imports/defab.d @@ -12,4 +12,3 @@ public class B : A this() {} } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/imp16080.d b/gcc/testsuite/gdc.test/compilable/imports/imp16080.d index 1afd9b5..9a8ca47 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/imp16080.d +++ b/gcc/testsuite/gdc.test/compilable/imports/imp16080.d @@ -1,4 +1,3 @@ struct A() { static immutable A a; } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/plainpackage/plainmodule.d b/gcc/testsuite/gdc.test/compilable/imports/plainpackage/plainmodule.d index 9e9933b..3befca4 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/plainpackage/plainmodule.d +++ b/gcc/testsuite/gdc.test/compilable/imports/plainpackage/plainmodule.d @@ -1,4 +1,3 @@ /// Used to test is(x == module) module imports.plainpackage.plainmodule; - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test11563std_traits.d b/gcc/testsuite/gdc.test/compilable/imports/test11563std_traits.d index 0ee4643..807c6e7 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test11563std_traits.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test11563std_traits.d @@ -19,4 +19,3 @@ template moduleName(alias T) enum moduleName = "--error--"; } } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test16709c.d b/gcc/testsuite/gdc.test/compilable/imports/test16709c.d index 1b45163..c5599fd 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test16709c.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test16709c.d @@ -1,2 +1 @@ void to(string units, D)(D td) { } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test16709d.d b/gcc/testsuite/gdc.test/compilable/imports/test16709d.d index 9f928af..922f59e 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test16709d.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test16709d.d @@ -1,2 +1 @@ void to(T, D)(D td) { } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test4003a.d b/gcc/testsuite/gdc.test/compilable/imports/test4003a.d index a05a16d..827a56e7 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test4003a.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test4003a.d @@ -3,4 +3,3 @@ module imports.test4003a; import imports.typecons4003; Tuple!(string) t; - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test50a.d b/gcc/testsuite/gdc.test/compilable/imports/test50a.d index da5bf36..9ec43dd 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test50a.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test50a.d @@ -3,4 +3,3 @@ module imports.test50a; class Foo { protected int a; } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test55a.d b/gcc/testsuite/gdc.test/compilable/imports/test55a.d index e6fa224..399e850 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test55a.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test55a.d @@ -11,4 +11,3 @@ class Arm2 { alias int ListHead; Queue2.ListHead mqueue; } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test62a.d b/gcc/testsuite/gdc.test/compilable/imports/test62a.d index 7179f3a..36c838d 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test62a.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test62a.d @@ -11,5 +11,3 @@ struct T() } alias T!() instance; - - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test63a.d b/gcc/testsuite/gdc.test/compilable/imports/test63a.d index d53b034..c60d8b4 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test63a.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test63a.d @@ -7,4 +7,3 @@ struct s { char[SIZE] a; } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test67a.d b/gcc/testsuite/gdc.test/compilable/imports/test67a.d index 796ab80..15fd644 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test67a.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test67a.d @@ -15,5 +15,3 @@ class Derived : Base return null; } } - - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test68a.d b/gcc/testsuite/gdc.test/compilable/imports/test68a.d index 7e44f3e..c7176f0 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test68a.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test68a.d @@ -6,4 +6,3 @@ class OtherModuleClass { } } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test9276decl.d b/gcc/testsuite/gdc.test/compilable/imports/test9276decl.d index 0f507bc..c774616 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test9276decl.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test9276decl.d @@ -11,4 +11,3 @@ class TemplateDecl : OverloadableDecl { mixin Visitors; } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test9276expr.d b/gcc/testsuite/gdc.test/compilable/imports/test9276expr.d index 376d6a4..72e5e2e 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test9276expr.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test9276expr.d @@ -12,4 +12,3 @@ class Node class Expression : Node { } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test9276parser.d b/gcc/testsuite/gdc.test/compilable/imports/test9276parser.d index 5e307ee..8b9473e 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test9276parser.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test9276parser.d @@ -1,4 +1,3 @@ module imports.test9276parser; public import imports.test9276expr, imports.test9276decl; - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test9276sem.d b/gcc/testsuite/gdc.test/compilable/imports/test9276sem.d index 3b660f4..0631683 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test9276sem.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test9276sem.d @@ -22,4 +22,3 @@ import imports.test9276visitors; class OverloadableDecl : Declaration { } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test9276type.d b/gcc/testsuite/gdc.test/compilable/imports/test9276type.d index 8a2cb3c..ede9261 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test9276type.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test9276type.d @@ -9,4 +9,3 @@ class Type : Expression // <- note to Walter. class BasicType : Type { } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test9276util.d b/gcc/testsuite/gdc.test/compilable/imports/test9276util.d index f3a95d9..22acb3e 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test9276util.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test9276util.d @@ -10,4 +10,3 @@ template DownCastMethods(T...) { enum x = _dgliteral!T; } - diff --git a/gcc/testsuite/gdc.test/compilable/imports/test9276visitors.d b/gcc/testsuite/gdc.test/compilable/imports/test9276visitors.d index e2d507c..8165104 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/test9276visitors.d +++ b/gcc/testsuite/gdc.test/compilable/imports/test9276visitors.d @@ -13,4 +13,3 @@ template DeepDup(T) if (is(T : BasicType)) template DeepDup(T) {} - diff --git a/gcc/testsuite/gdc.test/compilable/imports/wax16798.d b/gcc/testsuite/gdc.test/compilable/imports/wax16798.d index af98706..268038c 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/wax16798.d +++ b/gcc/testsuite/gdc.test/compilable/imports/wax16798.d @@ -1,4 +1,3 @@ module its.a.floorwax.wax16798; pragma(msg, "it's a floor wax"); - diff --git a/gcc/testsuite/gdc.test/compilable/isreturnonstack.d b/gcc/testsuite/gdc.test/compilable/isreturnonstack.d index 920f0ec..d41f123 100644 --- a/gcc/testsuite/gdc.test/compilable/isreturnonstack.d +++ b/gcc/testsuite/gdc.test/compilable/isreturnonstack.d @@ -5,4 +5,3 @@ S test2(); static assert(__traits(isReturnOnStack, test1) == false); static assert(__traits(isReturnOnStack, test2) == true); - diff --git a/gcc/testsuite/gdc.test/compilable/issue15478.d b/gcc/testsuite/gdc.test/compilable/issue15478.d index ad24e7f..7bc16c8 100644 --- a/gcc/testsuite/gdc.test/compilable/issue15478.d +++ b/gcc/testsuite/gdc.test/compilable/issue15478.d @@ -52,4 +52,3 @@ void test15478_3() enum foo_bug = foo.bug; Foo15478!int[foo_bug] baz; // OK } - diff --git a/gcc/testsuite/gdc.test/compilable/issue21813b.d b/gcc/testsuite/gdc.test/compilable/issue21813b.d index 0af986b..cdc9077 100644 --- a/gcc/testsuite/gdc.test/compilable/issue21813b.d +++ b/gcc/testsuite/gdc.test/compilable/issue21813b.d @@ -10,4 +10,3 @@ struct Target OS os = defaultTargetOS(); @property isPOSIX() scope @nogc { } } - diff --git a/gcc/testsuite/gdc.test/compilable/json.d b/gcc/testsuite/gdc.test/compilable/json.d index f79639d..73d3101 100644 --- a/gcc/testsuite/gdc.test/compilable/json.d +++ b/gcc/testsuite/gdc.test/compilable/json.d @@ -191,7 +191,7 @@ struct SafeS ref SafeS foo3() return scope { - return this; + static SafeS s; return s; } int* p; diff --git a/gcc/testsuite/gdc.test/compilable/line.d b/gcc/testsuite/gdc.test/compilable/line.d index 14e1789..419447d 100644 --- a/gcc/testsuite/gdc.test/compilable/line.d +++ b/gcc/testsuite/gdc.test/compilable/line.d @@ -26,5 +26,3 @@ static assert(__FILE_FULL_PATH__[$ - 9 .. $] == "newfile.d"); static assert(__LINE__ == 201); static assert(__FILE__ == "newfile.d"); static assert(__FILE_FULL_PATH__[$ - 9 .. $] == "newfile.d"); - - diff --git a/gcc/testsuite/gdc.test/compilable/mixintype.d b/gcc/testsuite/gdc.test/compilable/mixintype.d index abbf85a..a53805b 100644 --- a/gcc/testsuite/gdc.test/compilable/mixintype.d +++ b/gcc/testsuite/gdc.test/compilable/mixintype.d @@ -52,4 +52,3 @@ void test4() enum getStuff = q{ __traits(getMember,sb,"fieldb") }; auto b = Foo4!(mixin(getStuff)); } - diff --git a/gcc/testsuite/gdc.test/compilable/test10073.d b/gcc/testsuite/gdc.test/compilable/test10073.d index 1faf6bf..1e0c546 100644 --- a/gcc/testsuite/gdc.test/compilable/test10073.d +++ b/gcc/testsuite/gdc.test/compilable/test10073.d @@ -21,4 +21,3 @@ class Bar } class Foo {} // NG - diff --git a/gcc/testsuite/gdc.test/compilable/test1238.d b/gcc/testsuite/gdc.test/compilable/test1238.d index 0cbd84d..46a41b2 100644 --- a/gcc/testsuite/gdc.test/compilable/test1238.d +++ b/gcc/testsuite/gdc.test/compilable/test1238.d @@ -8,4 +8,3 @@ void foo() { int qwert = zuiop; } - diff --git a/gcc/testsuite/gdc.test/compilable/test12527.d b/gcc/testsuite/gdc.test/compilable/test12527.d index b476c17..d99c69b 100644 --- a/gcc/testsuite/gdc.test/compilable/test12527.d +++ b/gcc/testsuite/gdc.test/compilable/test12527.d @@ -5,4 +5,3 @@ static assert(Fun.stringof == "void function() @safe"); alias Del = void delegate() @safe; static assert(Del.stringof == "void delegate() @safe"); - diff --git a/gcc/testsuite/gdc.test/compilable/test13193.d b/gcc/testsuite/gdc.test/compilable/test13193.d index 58cb617..e4451b8 100644 --- a/gcc/testsuite/gdc.test/compilable/test13193.d +++ b/gcc/testsuite/gdc.test/compilable/test13193.d @@ -123,4 +123,3 @@ void bindFunc() {ssllib.getSymbol();} bindFunc(); bindFunc(); /* 100 */ } - diff --git a/gcc/testsuite/gdc.test/compilable/test13194.d b/gcc/testsuite/gdc.test/compilable/test13194.d index cefa7ba..47c8a83 100644 --- a/gcc/testsuite/gdc.test/compilable/test13194.d +++ b/gcc/testsuite/gdc.test/compilable/test13194.d @@ -14,4 +14,3 @@ union U13194 { static Object o = void; } - diff --git a/gcc/testsuite/gdc.test/compilable/test13600.d b/gcc/testsuite/gdc.test/compilable/test13600.d index a16b39c..9b09aac 100644 --- a/gcc/testsuite/gdc.test/compilable/test13600.d +++ b/gcc/testsuite/gdc.test/compilable/test13600.d @@ -10,4 +10,3 @@ class Retry { } } - diff --git a/gcc/testsuite/gdc.test/compilable/test13858.d b/gcc/testsuite/gdc.test/compilable/test13858.d index 98b0796..557cec8 100644 --- a/gcc/testsuite/gdc.test/compilable/test13858.d +++ b/gcc/testsuite/gdc.test/compilable/test13858.d @@ -17,4 +17,3 @@ void main() foo(); } - diff --git a/gcc/testsuite/gdc.test/compilable/test15019.d b/gcc/testsuite/gdc.test/compilable/test15019.d index 41444ce..d676d61 100644 --- a/gcc/testsuite/gdc.test/compilable/test15019.d +++ b/gcc/testsuite/gdc.test/compilable/test15019.d @@ -72,4 +72,3 @@ struct Vector(T, int N) assert(false); } } - diff --git a/gcc/testsuite/gdc.test/compilable/test15389_y.d b/gcc/testsuite/gdc.test/compilable/test15389_y.d index 78f4779..d546ad8 100644 --- a/gcc/testsuite/gdc.test/compilable/test15389_y.d +++ b/gcc/testsuite/gdc.test/compilable/test15389_y.d @@ -6,4 +6,3 @@ extern (C++, ns) { class Y { test15389_x.ns.X b; } } - diff --git a/gcc/testsuite/gdc.test/compilable/test15464.d b/gcc/testsuite/gdc.test/compilable/test15464.d index b8c3e9b..46d6e66 100644 --- a/gcc/testsuite/gdc.test/compilable/test15464.d +++ b/gcc/testsuite/gdc.test/compilable/test15464.d @@ -18,5 +18,3 @@ void main() { issue15464!C15464(); } - - diff --git a/gcc/testsuite/gdc.test/compilable/test15565.d b/gcc/testsuite/gdc.test/compilable/test15565.d index 4beb900..211a595 100644 --- a/gcc/testsuite/gdc.test/compilable/test15565.d +++ b/gcc/testsuite/gdc.test/compilable/test15565.d @@ -1,3 +1,2 @@ alias X2 = X; extern (C++, ns) struct X {} - diff --git a/gcc/testsuite/gdc.test/compilable/test15578.d b/gcc/testsuite/gdc.test/compilable/test15578.d index 81dd76a..78cb420 100644 --- a/gcc/testsuite/gdc.test/compilable/test15578.d +++ b/gcc/testsuite/gdc.test/compilable/test15578.d @@ -7,4 +7,3 @@ void f() j = 0; // works as expected k = 0; // Error: variable foo.ns.k is private } - diff --git a/gcc/testsuite/gdc.test/compilable/test15762.d b/gcc/testsuite/gdc.test/compilable/test15762.d index 0fb0293..0271c0f 100644 --- a/gcc/testsuite/gdc.test/compilable/test15762.d +++ b/gcc/testsuite/gdc.test/compilable/test15762.d @@ -10,4 +10,3 @@ void main() @safe { auto d = cast(const(ubyte)[]) c; auto e = cast(const(Windows1252Char)[]) c; } - diff --git a/gcc/testsuite/gdc.test/compilable/test15898.d b/gcc/testsuite/gdc.test/compilable/test15898.d index 01c325e..8649efa 100644 --- a/gcc/testsuite/gdc.test/compilable/test15898.d +++ b/gcc/testsuite/gdc.test/compilable/test15898.d @@ -24,4 +24,3 @@ void mulKaratsuba(int[] result, const(int)[] x, const(int)[] y, int[] ) addAssignSimple(resultHigh[1..$], newscratchbuff[0..y1.length]); } - diff --git a/gcc/testsuite/gdc.test/compilable/test16037.d b/gcc/testsuite/gdc.test/compilable/test16037.d index 12c672a..2b0ebc9 100644 --- a/gcc/testsuite/gdc.test/compilable/test16037.d +++ b/gcc/testsuite/gdc.test/compilable/test16037.d @@ -19,5 +19,3 @@ auto f() @nogc scope h=&g; h(); } - - diff --git a/gcc/testsuite/gdc.test/compilable/test16080.d b/gcc/testsuite/gdc.test/compilable/test16080.d index e9c6066..6520127 100644 --- a/gcc/testsuite/gdc.test/compilable/test16080.d +++ b/gcc/testsuite/gdc.test/compilable/test16080.d @@ -4,4 +4,3 @@ // https://issues.dlang.org/show_bug.cgi?id=16080 import imp16080; - diff --git a/gcc/testsuite/gdc.test/compilable/test16225.d b/gcc/testsuite/gdc.test/compilable/test16225.d index 6600842..777dcee 100644 --- a/gcc/testsuite/gdc.test/compilable/test16225.d +++ b/gcc/testsuite/gdc.test/compilable/test16225.d @@ -11,4 +11,3 @@ struct C return ((cast(ubyte*)&y)[1]); } } - diff --git a/gcc/testsuite/gdc.test/compilable/test16798.d b/gcc/testsuite/gdc.test/compilable/test16798.d index fe0f128..5d5d4da 100644 --- a/gcc/testsuite/gdc.test/compilable/test16798.d +++ b/gcc/testsuite/gdc.test/compilable/test16798.d @@ -11,4 +11,3 @@ it's a dessert topping import its.a.floorwax.wax16798; import its.a.dessert.topping; - diff --git a/gcc/testsuite/gdc.test/compilable/test17057.d b/gcc/testsuite/gdc.test/compilable/test17057.d index 677fe38..0e615c8 100644 --- a/gcc/testsuite/gdc.test/compilable/test17057.d +++ b/gcc/testsuite/gdc.test/compilable/test17057.d @@ -9,4 +9,3 @@ void main() { static assert([__traits(allMembers, LeClass)] == ["toString", "toHash", "opCmp", "opEquals", "Monitor", "factory"]); } - diff --git a/gcc/testsuite/gdc.test/compilable/test17421.d b/gcc/testsuite/gdc.test/compilable/test17421.d index e5075fb..8188422 100644 --- a/gcc/testsuite/gdc.test/compilable/test17421.d +++ b/gcc/testsuite/gdc.test/compilable/test17421.d @@ -16,4 +16,3 @@ static assert(__traits(getFunctionVariadicStyle, typesafe) == "typesafe"); static assert(__traits(getFunctionVariadicStyle, (int[] a...) {}) == "typesafe"); static assert(__traits(getFunctionVariadicStyle, typeof(cstyle)) == "stdarg"); - diff --git a/gcc/testsuite/gdc.test/compilable/test17468.d b/gcc/testsuite/gdc.test/compilable/test17468.d index 840de21..14aceaa 100644 --- a/gcc/testsuite/gdc.test/compilable/test17468.d +++ b/gcc/testsuite/gdc.test/compilable/test17468.d @@ -9,4 +9,3 @@ struct S } } const S CONST_S = S("/tmp".ptr); - diff --git a/gcc/testsuite/gdc.test/compilable/test17512.d b/gcc/testsuite/gdc.test/compilable/test17512.d index 4bf96b7..6419436 100644 --- a/gcc/testsuite/gdc.test/compilable/test17512.d +++ b/gcc/testsuite/gdc.test/compilable/test17512.d @@ -23,4 +23,3 @@ struct S0(T) } alias B = S0!int; - diff --git a/gcc/testsuite/gdc.test/compilable/test17942.d b/gcc/testsuite/gdc.test/compilable/test17942.d index 8fbc169..8d7ec39 100644 --- a/gcc/testsuite/gdc.test/compilable/test17942.d +++ b/gcc/testsuite/gdc.test/compilable/test17942.d @@ -12,4 +12,3 @@ void test() enum B = AliasSeq!(2); enum C = AliasSeq!(); - diff --git a/gcc/testsuite/gdc.test/compilable/test18020.d b/gcc/testsuite/gdc.test/compilable/test18020.d index d599920..6a7a36a 100644 --- a/gcc/testsuite/gdc.test/compilable/test18020.d +++ b/gcc/testsuite/gdc.test/compilable/test18020.d @@ -5,4 +5,4 @@ void bug(T)(T t) t.opCmp(t); } -alias bugi = bug!(typeof(new class{}));
\ No newline at end of file +alias bugi = bug!(typeof(new class{})); diff --git a/gcc/testsuite/gdc.test/compilable/test18584.d b/gcc/testsuite/gdc.test/compilable/test18584.d index e447cc2..2007c83 100644 --- a/gcc/testsuite/gdc.test/compilable/test18584.d +++ b/gcc/testsuite/gdc.test/compilable/test18584.d @@ -8,4 +8,3 @@ struct S { struct tmp(alias fns) { alias fun = fns!int; } - diff --git a/gcc/testsuite/gdc.test/compilable/test18936.d b/gcc/testsuite/gdc.test/compilable/test18936.d index 12f4b4b..82dff1b 100644 --- a/gcc/testsuite/gdc.test/compilable/test18936.d +++ b/gcc/testsuite/gdc.test/compilable/test18936.d @@ -28,4 +28,3 @@ struct S return c; } } - diff --git a/gcc/testsuite/gdc.test/compilable/test19203.d b/gcc/testsuite/gdc.test/compilable/test19203.d index 206d662..4cbe6b8 100644 --- a/gcc/testsuite/gdc.test/compilable/test19203.d +++ b/gcc/testsuite/gdc.test/compilable/test19203.d @@ -24,4 +24,3 @@ void test() static assert(!hasPopBack!Bar); static assert( hasPopBack!Foo && !hasPopBack!Bar); } - diff --git a/gcc/testsuite/gdc.test/compilable/test19227.d b/gcc/testsuite/gdc.test/compilable/test19227.d index 27dab9e..6ff5349 100644 --- a/gcc/testsuite/gdc.test/compilable/test19227.d +++ b/gcc/testsuite/gdc.test/compilable/test19227.d @@ -26,4 +26,3 @@ void main() static assert(T.init is T.init); static assert(T.init != T.init); } - diff --git a/gcc/testsuite/gdc.test/compilable/test20596.d b/gcc/testsuite/gdc.test/compilable/test20596.d index cd059c9..4d7854e 100644 --- a/gcc/testsuite/gdc.test/compilable/test20596.d +++ b/gcc/testsuite/gdc.test/compilable/test20596.d @@ -27,5 +27,3 @@ void test3032() @nogc scope fp = (){ n = 10; }; // no closure fp(); } - - diff --git a/gcc/testsuite/gdc.test/compilable/test20653.d b/gcc/testsuite/gdc.test/compilable/test20653.d index c7f329d..0e9b8f3 100644 --- a/gcc/testsuite/gdc.test/compilable/test20653.d +++ b/gcc/testsuite/gdc.test/compilable/test20653.d @@ -17,4 +17,3 @@ void main () { assert(myFunc!int() == 0); } - diff --git a/gcc/testsuite/gdc.test/compilable/test20717.d b/gcc/testsuite/gdc.test/compilable/test20717.d new file mode 100644 index 0000000..d45801e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test20717.d @@ -0,0 +1,17 @@ +// https://issues.dlang.org/show_bug.cgi?id=20717 + +/* +TEST_OUTPUT: +--- +false +--- +*/ + +pragma(msg, is(typeof({ + struct S + { + struct Foo {} + struct Bar() {} + alias Bar = Foo; + } +}))); diff --git a/gcc/testsuite/gdc.test/compilable/test20906.d b/gcc/testsuite/gdc.test/compilable/test20906.d index 86ffeda..e542631 100644 --- a/gcc/testsuite/gdc.test/compilable/test20906.d +++ b/gcc/testsuite/gdc.test/compilable/test20906.d @@ -12,4 +12,3 @@ int test12() int d = !x ? 1 : 1 / x; return a | b | c; } - diff --git a/gcc/testsuite/gdc.test/compilable/test20990.d b/gcc/testsuite/gdc.test/compilable/test20990.d index aeae11d..0036e14 100644 --- a/gcc/testsuite/gdc.test/compilable/test20990.d +++ b/gcc/testsuite/gdc.test/compilable/test20990.d @@ -16,4 +16,3 @@ void bar(int* ptr) assert(ptr); *ptr = 42; } - diff --git a/gcc/testsuite/gdc.test/compilable/test22639.d b/gcc/testsuite/gdc.test/compilable/test22639.d new file mode 100644 index 0000000..a889aa9 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22639.d @@ -0,0 +1,26 @@ +// https://issues.dlang.org/show_bug.cgi?id=22639 + +struct A +{ + this(ref return scope A rhs) inout {} + this(ref return scope const A rhs, int b = 7) inout + { + if (b != 7) { + this.b = b; + } + } + + this(this) @disable; + + int a=4; + int b=3; +} + +void main() +{ + A a = A(); + A c = A(a, 10); + A d = void; + d.__ctor(a, 200); + A* b = new A(a, 10); +} diff --git a/gcc/testsuite/gdc.test/compilable/test22665.d b/gcc/testsuite/gdc.test/compilable/test22665.d index 9d55dbb..4da6fd1 100644 --- a/gcc/testsuite/gdc.test/compilable/test22665.d +++ b/gcc/testsuite/gdc.test/compilable/test22665.d @@ -18,5 +18,3 @@ E foo3(E e) { return E.A; // with qualification, it is an enum } - - diff --git a/gcc/testsuite/gdc.test/compilable/test22825.d b/gcc/testsuite/gdc.test/compilable/test22825.d new file mode 100644 index 0000000..7820eae --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22825.d @@ -0,0 +1,4 @@ +// https://issues.dlang.org/show_bug.cgi?id=22825 +#line /* + multi-line comment +*/ 42 diff --git a/gcc/testsuite/gdc.test/compilable/test22859.d b/gcc/testsuite/gdc.test/compilable/test22859.d new file mode 100644 index 0000000..b5b318c --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22859.d @@ -0,0 +1,40 @@ +// https://issues.dlang.org/show_bug.cgi?id=22859 +private struct __InoutWorkaroundStruct {} +@property T rvalueOf(T)(T val) { return val; } +@property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init); +@property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init); + +// taken from std.traits.isAssignable +template isAssignable(Lhs, Rhs = Lhs) +{ + enum isAssignable = __traits(compiles, lvalueOf!Lhs = rvalueOf!Rhs) && __traits(compiles, lvalueOf!Lhs = lvalueOf!Rhs); +} + +// taken from std.meta.allSatisfy +template allSatisfy(alias F, T...) +{ + static foreach (Ti; T) + { + static if (!is(typeof(allSatisfy) == bool) && // not yet defined + !F!(Ti)) + { + enum allSatisfy = false; + } + } + static if (!is(typeof(allSatisfy) == bool)) // if not yet defined + { + enum allSatisfy = true; + } +} + +struct None{} + +class C1 +{ + static if(allSatisfy!(isAssignable, None, C2)) {} +} + +class C2 +{ + static if(allSatisfy!(isAssignable, None, C1, C2)) {} +} diff --git a/gcc/testsuite/gdc.test/compilable/test22860.d b/gcc/testsuite/gdc.test/compilable/test22860.d new file mode 100644 index 0000000..543dd88 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22860.d @@ -0,0 +1,62 @@ +// https://issues.dlang.org/show_bug.cgi?id=22860 +class C1 +{ + SumType!(C1, C2) field; +} + +class C2 +{ + SumType!(SumType!(C1, C2)) field; +} + +alias AliasSeq(TList...) = TList; + +template allSatisfy(alias F, T...) +{ + static foreach (Ti; T) + { + static if (!F!Ti) + enum allSatisfy = false; + } +} + +struct This {} + +enum isAssignableTo(T) = isAssignable!T; +enum isHashable(T) = __traits(compiles, { T.init; }); + +struct SumType(Types...) +{ + alias Types = AliasSeq!(ReplaceTypeUnless!(isSumTypeInstance, This, typeof(this), TemplateArgsOf!SumType)); + + static foreach (T; Types) + { + static if (isAssignableTo!T) + { + } + } + + static if (allSatisfy!(isAssignableTo, Types)) + { + } + + static if (allSatisfy!(isHashable, Types)) + size_t toHash; +} + +bool isSumTypeInstance; + +alias TemplateArgsOf(T : Base!Args, alias Base, Args...) = Args; +enum isAssignable(Lhs, Rhs = Lhs) = isRvalueAssignable!(Lhs, Rhs) ; +enum isRvalueAssignable(Lhs, Rhs ) = __traits(compiles, { lvalueOf!Lhs = Rhs; }); + +struct __InoutWorkaroundStruct{} +T lvalueOf(T)(__InoutWorkaroundStruct ); + +template ReplaceTypeUnless(alias pred, From, To, T...) +{ + static if (T.length == 1) + alias ReplaceTypeUnless = T; + static if (T.length > 1) + alias ReplaceTypeUnless = AliasSeq!(ReplaceTypeUnless!(pred, From, To, T[1 ])); +} diff --git a/gcc/testsuite/gdc.test/compilable/test22919.d b/gcc/testsuite/gdc.test/compilable/test22919.d new file mode 100644 index 0000000..8844ed0 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22919.d @@ -0,0 +1,17 @@ +// REQUIRED_ARGS: -checkaction=context -preview=dip1000 + +// Issue 22919 - [dip1000] -checkaction=context gives "assigned to `__assertOp2` with longer lifetime" ( +// https://issues.dlang.org/show_bug.cgi?id=22919 + +@safe: +struct S +{ + int* p; + ref S get() scope return {return this;} +} + +void main() +{ + scope S arr = S(); + assert(arr == arr.get()); +} diff --git a/gcc/testsuite/gdc.test/compilable/test3775.d b/gcc/testsuite/gdc.test/compilable/test3775.d index a34b329..da05dc5 100644 --- a/gcc/testsuite/gdc.test/compilable/test3775.d +++ b/gcc/testsuite/gdc.test/compilable/test3775.d @@ -5,5 +5,3 @@ struct Bug3775 { } static assert(cast(int)Bug3775.byLine == 1); - - diff --git a/gcc/testsuite/gdc.test/compilable/test4003.d b/gcc/testsuite/gdc.test/compilable/test4003.d index f51310e..08bf7b3 100644 --- a/gcc/testsuite/gdc.test/compilable/test4003.d +++ b/gcc/testsuite/gdc.test/compilable/test4003.d @@ -4,4 +4,3 @@ import imports.stdio4003; void main(){} - diff --git a/gcc/testsuite/gdc.test/compilable/test4375.d b/gcc/testsuite/gdc.test/compilable/test4375.d index 1cc7a3a..2a132fb 100644 --- a/gcc/testsuite/gdc.test/compilable/test4375.d +++ b/gcc/testsuite/gdc.test/compilable/test4375.d @@ -471,4 +471,3 @@ void f() { else x = null; } - diff --git a/gcc/testsuite/gdc.test/compilable/test50.d b/gcc/testsuite/gdc.test/compilable/test50.d index a5dfac0..356b353 100644 --- a/gcc/testsuite/gdc.test/compilable/test50.d +++ b/gcc/testsuite/gdc.test/compilable/test50.d @@ -6,5 +6,3 @@ import imports.test50a; class Bar : Foo { alias typeof(Foo.tupleof) Bleh; } - - diff --git a/gcc/testsuite/gdc.test/compilable/test5227.d b/gcc/testsuite/gdc.test/compilable/test5227.d index b713191..befb947 100644 --- a/gcc/testsuite/gdc.test/compilable/test5227.d +++ b/gcc/testsuite/gdc.test/compilable/test5227.d @@ -128,5 +128,3 @@ pragma(msg, "fma()"); enum fmaf = fma(-3.2f, 5.2f, 3.8f); //pragma(msg, fmaf); enum fmad = fma(-3.2 , 5.2 , 3.8 ); //pragma(msg, fmad); enum fmar = fma(-3.2L, 5.2L, 3.8L); pragma(msg, fmar); - - diff --git a/gcc/testsuite/gdc.test/compilable/test602.d b/gcc/testsuite/gdc.test/compilable/test602.d index a17aa16..c87f883 100644 --- a/gcc/testsuite/gdc.test/compilable/test602.d +++ b/gcc/testsuite/gdc.test/compilable/test602.d @@ -409,4 +409,3 @@ void test13321(bool b) x = Foo(1); EXIT: } - diff --git a/gcc/testsuite/gdc.test/compilable/test6089.d b/gcc/testsuite/gdc.test/compilable/test6089.d index b1fa2cf..603348c 100644 --- a/gcc/testsuite/gdc.test/compilable/test6089.d +++ b/gcc/testsuite/gdc.test/compilable/test6089.d @@ -3,4 +3,3 @@ void main() { extern int[1][1] foo; } - diff --git a/gcc/testsuite/gdc.test/compilable/test63.d b/gcc/testsuite/gdc.test/compilable/test63.d index 9cf986d..55b2e47 100644 --- a/gcc/testsuite/gdc.test/compilable/test63.d +++ b/gcc/testsuite/gdc.test/compilable/test63.d @@ -4,4 +4,3 @@ private import imports.test63a; const int SIZE = 7; - diff --git a/gcc/testsuite/gdc.test/compilable/test6395.d b/gcc/testsuite/gdc.test/compilable/test6395.d index 3b80203..6504097 100644 --- a/gcc/testsuite/gdc.test/compilable/test6395.d +++ b/gcc/testsuite/gdc.test/compilable/test6395.d @@ -5,4 +5,3 @@ // https://issues.dlang.org/show_bug.cgi?id=6395 import c6395; - diff --git a/gcc/testsuite/gdc.test/compilable/test66.d b/gcc/testsuite/gdc.test/compilable/test66.d index 9db082e..bedbd26 100644 --- a/gcc/testsuite/gdc.test/compilable/test66.d +++ b/gcc/testsuite/gdc.test/compilable/test66.d @@ -18,4 +18,3 @@ class Lexer { Token token; } - diff --git a/gcc/testsuite/gdc.test/compilable/test67.d b/gcc/testsuite/gdc.test/compilable/test67.d index 9f45c64..bafc567 100644 --- a/gcc/testsuite/gdc.test/compilable/test67.d +++ b/gcc/testsuite/gdc.test/compilable/test67.d @@ -9,4 +9,3 @@ interface I interface SubI : I { } - diff --git a/gcc/testsuite/gdc.test/compilable/test68.d b/gcc/testsuite/gdc.test/compilable/test68.d index 55a7995..1631642 100644 --- a/gcc/testsuite/gdc.test/compilable/test68.d +++ b/gcc/testsuite/gdc.test/compilable/test68.d @@ -16,4 +16,3 @@ void main() { new Foo(); } - diff --git a/gcc/testsuite/gdc.test/compilable/test7399.d b/gcc/testsuite/gdc.test/compilable/test7399.d index dba0741..8961ba1 100644 --- a/gcc/testsuite/gdc.test/compilable/test7399.d +++ b/gcc/testsuite/gdc.test/compilable/test7399.d @@ -3,4 +3,3 @@ static assert(!__traits(compiles, { import non.existing.file; })); // https://issues.dlang.org/show_bug.cgi?id=7400 static assert(!is(typeof({import non_existing_file;}))); - diff --git a/gcc/testsuite/gdc.test/compilable/test8296.d b/gcc/testsuite/gdc.test/compilable/test8296.d index cd175b5..d29c9ed 100644 --- a/gcc/testsuite/gdc.test/compilable/test8296.d +++ b/gcc/testsuite/gdc.test/compilable/test8296.d @@ -30,4 +30,4 @@ class Foo void main(string[] args) { auto foo = new Foo(); -}
\ No newline at end of file +} diff --git a/gcc/testsuite/gdc.test/compilable/test8922b.d b/gcc/testsuite/gdc.test/compilable/test8922b.d index 007f9b6..408c6e9 100644 --- a/gcc/testsuite/gdc.test/compilable/test8922b.d +++ b/gcc/testsuite/gdc.test/compilable/test8922b.d @@ -7,4 +7,3 @@ void test() enum x = __traits(parent, imports.bug8922).stringof; static assert(x == "package imports"); } - diff --git a/gcc/testsuite/gdc.test/compilable/test8922d.d b/gcc/testsuite/gdc.test/compilable/test8922d.d index 4898cf6..87ec51a 100644 --- a/gcc/testsuite/gdc.test/compilable/test8922d.d +++ b/gcc/testsuite/gdc.test/compilable/test8922d.d @@ -8,4 +8,3 @@ void test() enum x = __traits(parent, imports.bug8922).stringof; static assert(x == "package imports"); } - diff --git a/gcc/testsuite/gdc.test/compilable/test9057.d b/gcc/testsuite/gdc.test/compilable/test9057.d index 3594a04..ca2acb6 100644 --- a/gcc/testsuite/gdc.test/compilable/test9057.d +++ b/gcc/testsuite/gdc.test/compilable/test9057.d @@ -16,5 +16,3 @@ void test9507_2() { import imp9057_2; Bug9057!(BugInt) xxx; } - - diff --git a/gcc/testsuite/gdc.test/compilable/test9436.d b/gcc/testsuite/gdc.test/compilable/test9436.d index 5b650bd..2b3f8dc 100644 --- a/gcc/testsuite/gdc.test/compilable/test9436.d +++ b/gcc/testsuite/gdc.test/compilable/test9436.d @@ -1,4 +1,3 @@ // EXTRA_SOURCES: imports/test9436interp.d // EXTRA_FILES: imports/test9436aggr.d imports/test9436node.d imports/test9436type.d // this is a dummy module for test 9436. - diff --git a/gcc/testsuite/gdc.test/compilable/testAliasLookup.d b/gcc/testsuite/gdc.test/compilable/testAliasLookup.d index 786c2f4..a7f698d 100644 --- a/gcc/testsuite/gdc.test/compilable/testAliasLookup.d +++ b/gcc/testsuite/gdc.test/compilable/testAliasLookup.d @@ -57,4 +57,3 @@ struct S16082 return aliasthis; // Line 20 } } - diff --git a/gcc/testsuite/gdc.test/compilable/testInference.d b/gcc/testsuite/gdc.test/compilable/testInference.d index 9ffecc1..31b1049 100644 --- a/gcc/testsuite/gdc.test/compilable/testInference.d +++ b/gcc/testsuite/gdc.test/compilable/testInference.d @@ -818,4 +818,3 @@ void test13840() nothrow } // Add more tests regarding inferences later. - diff --git a/gcc/testsuite/gdc.test/compilable/testprofile.d b/gcc/testsuite/gdc.test/compilable/testprofile.d index 2f7beeb..6b0f775 100644 --- a/gcc/testsuite/gdc.test/compilable/testprofile.d +++ b/gcc/testsuite/gdc.test/compilable/testprofile.d @@ -20,4 +20,3 @@ void main() { "lala", "lala", "lala", "lala"); } - diff --git a/gcc/testsuite/gdc.test/compilable/testsctreturn.d b/gcc/testsuite/gdc.test/compilable/testsctreturn.d index 7826cd4..0d0af2e 100644 --- a/gcc/testsuite/gdc.test/compilable/testsctreturn.d +++ b/gcc/testsuite/gdc.test/compilable/testsctreturn.d @@ -32,4 +32,3 @@ struct S return &i; } } - diff --git a/gcc/testsuite/gdc.test/compilable/typeid_name.d b/gcc/testsuite/gdc.test/compilable/typeid_name.d index b2292bf..a0aa052 100644 --- a/gcc/testsuite/gdc.test/compilable/typeid_name.d +++ b/gcc/testsuite/gdc.test/compilable/typeid_name.d @@ -11,4 +11,3 @@ class Tiger : Panzer {} static assert (() { Panzer p = new Tiger(); return classname(p); } () == "Tiger"); - diff --git a/gcc/testsuite/gdc.test/compilable/vcg-ast.d b/gcc/testsuite/gdc.test/compilable/vcg-ast.d index 61767cc..4673677 100644 --- a/gcc/testsuite/gdc.test/compilable/vcg-ast.d +++ b/gcc/testsuite/gdc.test/compilable/vcg-ast.d @@ -61,4 +61,3 @@ void main() { values!wchar_t; } - diff --git a/gcc/testsuite/gdc.test/compilable/version.d b/gcc/testsuite/gdc.test/compilable/version.d index 00c5c80..86d06cb 100644 --- a/gcc/testsuite/gdc.test/compilable/version.d +++ b/gcc/testsuite/gdc.test/compilable/version.d @@ -20,4 +20,4 @@ version (D_TypeInfo) else { static assert(0); -}
\ No newline at end of file +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug5.d b/gcc/testsuite/gdc.test/fail_compilation/bug5.d index b2f7d1d..44e4c80 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/bug5.d +++ b/gcc/testsuite/gdc.test/fail_compilation/bug5.d @@ -10,4 +10,3 @@ int test1() if (false) return 0; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug5b.d b/gcc/testsuite/gdc.test/fail_compilation/bug5b.d index 8ba5717..487f22e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/bug5b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/bug5b.d @@ -8,4 +8,3 @@ fail_compilation/bug5b.d(8): Error: function `bug5b.test1` has no `return` state int test1() { } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d index 0edd5e9..f456454 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d +++ b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d @@ -108,4 +108,3 @@ void targ() void ft2(T)(S, T){} ft2(y, 1); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/circ10280.d b/gcc/testsuite/gdc.test/fail_compilation/circ10280.d index 76a7764..176295f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/circ10280.d +++ b/gcc/testsuite/gdc.test/fail_compilation/circ10280.d @@ -9,4 +9,3 @@ fail_compilation/circ10280.d(10): called from here: `foo10280()` const int q10280 = foo10280(); int foo10280() { return q10280; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/ctfe11467.d b/gcc/testsuite/gdc.test/fail_compilation/ctfe11467.d index dcde98f..aa61e2b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ctfe11467.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ctfe11467.d @@ -49,4 +49,3 @@ int test11467d() } static assert(test11467c()); static assert(test11467d()); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/dephexstrings.d b/gcc/testsuite/gdc.test/fail_compilation/dephexstrings.d index 2ce3795..553a0c6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/dephexstrings.d +++ b/gcc/testsuite/gdc.test/fail_compilation/dephexstrings.d @@ -7,4 +7,3 @@ fail_compilation/dephexstrings.d(9): Error: declaration expected, not `"60"` --- */ enum xstr = x"60"; - diff --git a/gcc/testsuite/gdc.test/fail_compilation/deprecated6760.d b/gcc/testsuite/gdc.test/fail_compilation/deprecated6760.d index 8faa88b..7b219cb 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/deprecated6760.d +++ b/gcc/testsuite/gdc.test/fail_compilation/deprecated6760.d @@ -17,4 +17,3 @@ class Bar { deprecated override bool opEquals(Object); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag12640.d b/gcc/testsuite/gdc.test/fail_compilation/diag12640.d index fc1a197..526e185 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag12640.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag12640.d @@ -27,4 +27,3 @@ void main() } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14145.d b/gcc/testsuite/gdc.test/fail_compilation/diag14145.d index d292f76..6447f5e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag14145.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag14145.d @@ -34,5 +34,3 @@ struct Capture(alias c) return *ptr; } } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16271.d b/gcc/testsuite/gdc.test/fail_compilation/diag16271.d index e209593..1677faf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag16271.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag16271.d @@ -9,4 +9,3 @@ void main() { auto fun = ref x; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag1730.d b/gcc/testsuite/gdc.test/fail_compilation/diag1730.d index a17479c..0ab5142 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag1730.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag1730.d @@ -100,4 +100,3 @@ void main() scObj.scFunc(); scObj.wFunc(); // ng } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag18574.d b/gcc/testsuite/gdc.test/fail_compilation/diag18574.d index fef9829..f051d07 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag18574.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag18574.d @@ -14,4 +14,3 @@ class Bar {} class Baz { int a; } class Test : Foo, Bar, Baz, int {} - diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8510.d b/gcc/testsuite/gdc.test/fail_compilation/diag8510.d index 77660d0..de99471 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag8510.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag8510.d @@ -14,4 +14,3 @@ struct S { alias g a; alias g a; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/dip25.d b/gcc/testsuite/gdc.test/fail_compilation/dip25.d index 4e803be..4f8ea23 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/dip25.d +++ b/gcc/testsuite/gdc.test/fail_compilation/dip25.d @@ -3,8 +3,8 @@ REQUIRED_ARGS: -de TEST_OUTPUT: --- fail_compilation/dip25.d(17): Deprecation: returning `this.buffer[]` escapes a reference to parameter `this` -fail_compilation/dip25.d(17): perhaps annotate the function with `return` -fail_compilation/dip25.d(22): Error: returning `identity(x)` escapes a reference to local variable `x` +fail_compilation/dip25.d(15): perhaps annotate the function with `return` +fail_compilation/dip25.d(22): Error: returning `identity(x)` escapes a reference to parameter `x` fail_compilation/dip25.d(23): Deprecation: returning `identity(x)` escapes a reference to parameter `x` fail_compilation/dip25.d(23): perhaps annotate the parameter with `return` --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10905.d b/gcc/testsuite/gdc.test/fail_compilation/fail10905.d index 4f243ff..52b5285 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail10905.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail10905.d @@ -20,4 +20,3 @@ struct Bar return x == Foo.y; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail11163.d b/gcc/testsuite/gdc.test/fail_compilation/fail11163.d index d886740..41cddbf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail11163.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail11163.d @@ -12,4 +12,3 @@ void main() { immutable a = foo(); pragma(msg, a); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail118.d b/gcc/testsuite/gdc.test/fail_compilation/fail118.d index 263570a..3df797d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail118.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail118.d @@ -1,8 +1,15 @@ /* TEST_OUTPUT: --- -fail_compilation/fail118.d(26): Error: invalid `foreach` aggregate `Iter`, define `opApply()`, range primitives, or use `.tupleof` -fail_compilation/fail118.d(27): Error: invalid `foreach` aggregate `Iter`, define `opApply()`, range primitives, or use `.tupleof` +fail_compilation/fail118.d(43): Error: invalid `foreach` aggregate `Iter` of type `Iter` +fail_compilation/fail118.d(43): maybe define `opApply()`, range primitives, or use `.tupleof` +fail_compilation/fail118.d(44): Error: invalid `foreach` aggregate `Iter` of type `Iter` +fail_compilation/fail118.d(44): maybe define `opApply()`, range primitives, or use `.tupleof` +fail_compilation/fail118.d(47): Error: invalid `foreach` aggregate `s` of type `S*` +fail_compilation/fail118.d(49): Error: undefined identifier `unknown` +fail_compilation/fail118.d(37): Error: undefined identifier `doesNotExist` +fail_compilation/fail118.d(51): Error: template instance `fail118.error!()` error instantiating +fail_compilation/fail118.d(51): Error: invalid `foreach` aggregate `error()` of type `void` --- */ @@ -20,9 +27,26 @@ class Foo mixin opHackedApply!() oldIterMix; } +struct S +{ + int opApply(scope int delegate(const int) dg); +} + +auto error()() +{ + doesNotExist(); +} + void main() { Foo f = new Foo; foreach (int i; f.oldIterMix.Iter) {} foreach ( i; f.oldIterMix.Iter) {} + + S* s; + foreach (const i; s) {} + + foreach(const i; unknown) {} + + foreach (const i; error()) {} } diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12.d b/gcc/testsuite/gdc.test/fail_compilation/fail12.d index aa060e6..d752d38 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail12.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail12.d @@ -16,4 +16,3 @@ void main() mixin Foo!(y); assert(abc() == 8); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail131.d b/gcc/testsuite/gdc.test/fail_compilation/fail131.d index 15b6dc9..78176e8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail131.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail131.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail131.d(8): Error: function `D main` parameters must be `main()` or `main(string[] args)` +fail_compilation/fail131.d(8): Error: function `D main` parameter list must be empty or accept one parameter of type `string[]` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13902.d b/gcc/testsuite/gdc.test/fail_compilation/fail13902.d index 5e3b637..12a6b6e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail13902.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail13902.d @@ -54,14 +54,14 @@ int* testEscape1() TEST_OUTPUT: --- fail_compilation/fail13902.d(88): Error: Using the result of a comma expression is not allowed -fail_compilation/fail13902.d(75): Error: returning `& x` escapes a reference to local variable `x` -fail_compilation/fail13902.d(76): Error: returning `&s1.v` escapes a reference to local variable `s1` -fail_compilation/fail13902.d(81): Error: returning `& sa1` escapes a reference to local variable `sa1` -fail_compilation/fail13902.d(82): Error: returning `&sa2[0][0]` escapes a reference to local variable `sa2` -fail_compilation/fail13902.d(83): Error: returning `& x` escapes a reference to local variable `x` -fail_compilation/fail13902.d(84): Error: returning `(& x+4)` escapes a reference to local variable `x` -fail_compilation/fail13902.d(85): Error: returning `& x + cast(long)x * 4L` escapes a reference to local variable `x` -fail_compilation/fail13902.d(88): Error: returning `& y` escapes a reference to local variable `y` +fail_compilation/fail13902.d(75): Error: returning `& x` escapes a reference to parameter `x` +fail_compilation/fail13902.d(76): Error: returning `&s1.v` escapes a reference to parameter `s1` +fail_compilation/fail13902.d(81): Error: returning `& sa1` escapes a reference to parameter `sa1` +fail_compilation/fail13902.d(82): Error: returning `&sa2[0][0]` escapes a reference to parameter `sa2` +fail_compilation/fail13902.d(83): Error: returning `& x` escapes a reference to parameter `x` +fail_compilation/fail13902.d(84): Error: returning `(& x+4)` escapes a reference to parameter `x` +fail_compilation/fail13902.d(85): Error: returning `& x + cast(long)x * 4L` escapes a reference to parameter `x` +fail_compilation/fail13902.d(88): Error: returning `& y` escapes a reference to parameter `y` --- */ int* testEscape2( @@ -134,9 +134,9 @@ int* testEscape3( /* TEST_OUTPUT: --- -fail_compilation/fail13902.d(150): Error: returning `cast(int[])sa1` escapes a reference to local variable `sa1` -fail_compilation/fail13902.d(151): Error: returning `cast(int[])sa1` escapes a reference to local variable `sa1` -fail_compilation/fail13902.d(152): Error: returning `sa1[]` escapes a reference to local variable `sa1` +fail_compilation/fail13902.d(150): Error: returning `cast(int[])sa1` escapes a reference to parameter `sa1` +fail_compilation/fail13902.d(151): Error: returning `cast(int[])sa1` escapes a reference to parameter `sa1` +fail_compilation/fail13902.d(152): Error: returning `sa1[]` escapes a reference to parameter `sa1` fail_compilation/fail13902.d(155): Error: returning `cast(int[])sa2` escapes a reference to local variable `sa2` fail_compilation/fail13902.d(156): Error: returning `cast(int[])sa2` escapes a reference to local variable `sa2` fail_compilation/fail13902.d(157): Error: returning `sa2[]` escapes a reference to local variable `sa2` @@ -223,14 +223,14 @@ ref int testEscapeRef1() /* TEST_OUTPUT: --- -fail_compilation/fail13902.d(240): Error: returning `x` escapes a reference to local variable `x` -fail_compilation/fail13902.d(241): Error: returning `s1.v` escapes a reference to local variable `s1` -fail_compilation/fail13902.d(245): Error: returning `sa1[0]` escapes a reference to local variable `sa1` -fail_compilation/fail13902.d(246): Error: returning `sa2[0][0]` escapes a reference to local variable `sa2` -fail_compilation/fail13902.d(247): Error: returning `x = 1` escapes a reference to local variable `x` -fail_compilation/fail13902.d(248): Error: returning `x += 1` escapes a reference to local variable `x` -fail_compilation/fail13902.d(249): Error: returning `s1.v = 1` escapes a reference to local variable `s1` -fail_compilation/fail13902.d(250): Error: returning `s1.v += 1` escapes a reference to local variable `s1` +fail_compilation/fail13902.d(240): Error: returning `x` escapes a reference to parameter `x` +fail_compilation/fail13902.d(241): Error: returning `s1.v` escapes a reference to parameter `s1` +fail_compilation/fail13902.d(245): Error: returning `sa1[0]` escapes a reference to parameter `sa1` +fail_compilation/fail13902.d(246): Error: returning `sa2[0][0]` escapes a reference to parameter `sa2` +fail_compilation/fail13902.d(247): Error: returning `x = 1` escapes a reference to parameter `x` +fail_compilation/fail13902.d(248): Error: returning `x += 1` escapes a reference to parameter `x` +fail_compilation/fail13902.d(249): Error: returning `s1.v = 1` escapes a reference to parameter `s1` +fail_compilation/fail13902.d(250): Error: returning `s1.v += 1` escapes a reference to parameter `s1` --- */ ref int testEscapeRef2( @@ -324,8 +324,8 @@ int[] testSlice2() { int[3] sa; int n; return sa[n..2][1..2]; } TEST_OUTPUT: --- fail_compilation/fail13902.d(324): Error: returning `vda[0]` escapes a reference to parameter `vda` -fail_compilation/fail13902.d(324): perhaps annotate the parameter with `return` --- + */ ref int testDynamicArrayVariadic1(int[] vda...) { return vda[0]; } @safe int[] testDynamicArrayVariadic2(int[] vda...) { return vda[]; } @@ -334,7 +334,7 @@ int[3] testDynamicArrayVariadic3(int[] vda...) { return vda[0..3]; } // no er /* TEST_OUTPUT: --- -fail_compilation/fail13902.d(335): Error: returning `vsa[0]` escapes a reference to local variable `vsa` +fail_compilation/fail13902.d(335): Error: returning `vsa[0]` escapes a reference to parameter `vsa` fail_compilation/fail13902.d(336): Error: returning `vsa[]` escapes a reference to variadic parameter `vsa` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail14486.d b/gcc/testsuite/gdc.test/fail_compilation/fail14486.d index c7a2b89..35312454 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail14486.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail14486.d @@ -3,18 +3,30 @@ /* TEST_OUTPUT: --- -fail_compilation/fail14486.d(35): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(36): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(41): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(42): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(47): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(48): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(53): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(54): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(59): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(60): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(65): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/fail14486.d(66): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. +fail_compilation/fail14486.d(47): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(47): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(48): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(48): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(53): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(53): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(54): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(54): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(59): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(59): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(60): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(60): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(65): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(65): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(66): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(66): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(71): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(71): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(72): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(72): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(77): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(77): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/fail14486.d(78): Error: the `delete` keyword is obsolete +fail_compilation/fail14486.d(78): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15.d b/gcc/testsuite/gdc.test/fail_compilation/fail15.d index cd18485..9d226de 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail15.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail15.d @@ -23,5 +23,3 @@ void main() mixin Test!() xs; bool x = xs[false]; } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15691.d b/gcc/testsuite/gdc.test/fail_compilation/fail15691.d index a20e1b5..10033ed 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail15691.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail15691.d @@ -20,5 +20,3 @@ void main() bc: 4, // line 20 }; } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail16.d b/gcc/testsuite/gdc.test/fail_compilation/fail16.d index 6c7a90a..f462a13 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail16.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail16.d @@ -24,4 +24,3 @@ void main() { foo!(i); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail160.d b/gcc/testsuite/gdc.test/fail_compilation/fail160.d index 0c8a937..9abe59f8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail160.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail160.d @@ -23,4 +23,3 @@ int main(char[][] args) return 0; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail16001.d b/gcc/testsuite/gdc.test/fail_compilation/fail16001.d index ef5fc7b..dc480cf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail16001.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail16001.d @@ -10,4 +10,3 @@ void main() { auto fail = () => {}; auto ok = () => () {}; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail16600.d b/gcc/testsuite/gdc.test/fail_compilation/fail16600.d index a4bc739..eb341c6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail16600.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail16600.d @@ -22,5 +22,3 @@ void main() auto a = const(S)("abc"); assert(a.i == 2); } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17.d b/gcc/testsuite/gdc.test/fail_compilation/fail17.d index 2c73d30..daec0f2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17.d @@ -12,5 +12,3 @@ struct A(T) } A!(int) x; - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17275.d b/gcc/testsuite/gdc.test/fail_compilation/fail17275.d index fd7623f..6ab31ef 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17275.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17275.d @@ -17,4 +17,3 @@ struct ThreadDSO DSO* _pdso; void[] _tlsRange; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17419.d b/gcc/testsuite/gdc.test/fail_compilation/fail17419.d index 82d4160..97ee362 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17419.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17419.d @@ -9,4 +9,3 @@ fail_compilation/fail17419.d(11): Error: expected 1 arguments for `getLinkage` b enum s = __traits(getLinkage, 8 * 8); enum t = __traits(getLinkage, 8, 8); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17421.d b/gcc/testsuite/gdc.test/fail_compilation/fail17421.d index c308ad5..f181937 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17421.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17421.d @@ -13,4 +13,3 @@ alias int* x; static assert(__traits(getFunctionVariadicStyle, 1) == "none"); static assert(__traits(getFunctionVariadicStyle, x) == "none"); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17842.d b/gcc/testsuite/gdc.test/fail_compilation/fail17842.d index ef66858..734f8d7 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17842.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17842.d @@ -25,5 +25,3 @@ Object testobj(scope Object obj) @safe array ~= arr; return array[0]; } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17906.d b/gcc/testsuite/gdc.test/fail_compilation/fail17906.d index 689dd48..41f7465 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17906.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17906.d @@ -1,7 +1,8 @@ // REQUIRED_ARGS: -de /* TEST_OUTPUT: --- -fail_compilation/fail17906.d(11): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. +fail_compilation/fail17906.d(12): Error: the `delete` keyword is obsolete +fail_compilation/fail17906.d(12): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead --- */ // https://issues.dlang.org/show_bug.cgi?id=18647 diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17927.d b/gcc/testsuite/gdc.test/fail_compilation/fail17927.d index 5f371da..410f307 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17927.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17927.d @@ -11,8 +11,8 @@ fail_compilation/fail17927.d(23): Error: scope variable `ptr` may not be returne struct String { const(char)* mem1() const scope @safe { return ptr; } - - inout(char)* mem2() inout scope @safe { return ptr; } // no error because `ref inout` implies `return` + // https://issues.dlang.org/show_bug.cgi?id=22027 + inout(char)* mem2() inout scope @safe { return ptr; } char* ptr; } @@ -21,4 +21,3 @@ struct String { const(char)* foo1(scope const(char)* ptr) @safe { return ptr; } inout(char)* foo2(scope inout(char)* ptr) @safe { return ptr; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19441.d b/gcc/testsuite/gdc.test/fail_compilation/fail19441.d index 520eb76..36611bb 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19441.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19441.d @@ -46,4 +46,3 @@ void main() assert(wrap[0].s.test()); // failure } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19744.d b/gcc/testsuite/gdc.test/fail_compilation/fail19744.d index 9115b4e..abc4fea 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19744.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19744.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail19744.d(8): Error: Top-level function `test` has no `this` to which `return` can apply +fail_compilation/fail19744.d(8): Error: top-level function `test` has no `this` to which `return` can apply --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d b/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d index f4aa848..ccdbb57 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d @@ -10,4 +10,3 @@ void f (__vector(int[4]) n) foreach (i; 0 .. n) cast(void)n; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d b/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d index 82d92eb..254c2ca 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d @@ -17,4 +17,3 @@ void f (__vector(int[4]) n, S m) foreach (i; m .. n) cast(void)n; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19922.d b/gcc/testsuite/gdc.test/fail_compilation/fail19922.d index 1476666..a7309fe 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19922.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19922.d @@ -15,4 +15,3 @@ void test() Object o; auto ti = typeid(o); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19923.d b/gcc/testsuite/gdc.test/fail_compilation/fail19923.d index d98dd03..e118d3d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19923.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19923.d @@ -15,4 +15,3 @@ void test() Object o; auto ti = o.classinfo; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20084.d b/gcc/testsuite/gdc.test/fail_compilation/fail20084.d index dcc73a9..22f6433 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail20084.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail20084.d @@ -1,7 +1,7 @@ /* REQUIRED_ARGS: -preview=dip1000 TEST_OUTPUT: --- -fail_compilation/fail20084.d(109): Error: returning `v.front()` escapes a reference to local variable `v` +fail_compilation/fail20084.d(109): Error: returning `v.front()` escapes a reference to parameter `v` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail201.d b/gcc/testsuite/gdc.test/fail_compilation/fail201.d index 6c4d923..6e51706 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail201.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail201.d @@ -9,4 +9,3 @@ void main() { int c; c = c >>> 33; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail202.d b/gcc/testsuite/gdc.test/fail_compilation/fail202.d index 57009ed..ebd8060 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail202.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail202.d @@ -9,4 +9,3 @@ void main() { int c; c = c >> 33; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail203.d b/gcc/testsuite/gdc.test/fail_compilation/fail203.d index 51accf5..ecbe595 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail203.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail203.d @@ -9,4 +9,3 @@ void main() { int c; c = c << 33; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail204.d b/gcc/testsuite/gdc.test/fail_compilation/fail204.d index e6f2faa..79a8206 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail204.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail204.d @@ -8,4 +8,3 @@ void main() { long c; c >>= 65; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20448.d b/gcc/testsuite/gdc.test/fail_compilation/fail20448.d index 6ef3a4a..916ee8b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail20448.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail20448.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail20448.d(16): Error: returning `p.x` escapes a reference to local variable `p` +fail_compilation/fail20448.d(16): Error: returning `p.x` escapes a reference to parameter `p` fail_compilation/fail20448.d(22): Error: template instance `fail20448.member!"x"` error instantiating --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail205.d b/gcc/testsuite/gdc.test/fail_compilation/fail205.d index 89ddc93..2e8a626 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail205.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail205.d @@ -8,4 +8,3 @@ void main() { long c; c <<= 65; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail206.d b/gcc/testsuite/gdc.test/fail_compilation/fail206.d index e3b2dce..88c90cb 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail206.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail206.d @@ -8,4 +8,3 @@ void main() { long c; c >>>= 65; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20800.d b/gcc/testsuite/gdc.test/fail_compilation/fail20800.d index 185baec..026b7c2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail20800.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail20800.d @@ -21,4 +21,3 @@ void initCommands() { fun(m.index); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail217.d b/gcc/testsuite/gdc.test/fail_compilation/fail217.d index 63ed0a0..11ad76f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail217.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail217.d @@ -22,4 +22,3 @@ main() auto m2 = new immutable(Message)(2); m2.notifier = 3; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21868b.d b/gcc/testsuite/gdc.test/fail_compilation/fail21868b.d index 6f34029..687a727 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail21868b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail21868b.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/fail21868b.d(19): Error: returning `&s.x` escapes a reference to parameter `s` -fail_compilation/fail21868b.d(19): perhaps remove `scope` parameter annotation so `return` applies to `ref` +fail_compilation/fail21868b.d(17): perhaps change the `return scope` into `scope return` --- */ @@ -18,5 +18,3 @@ int* test(ref return scope S s) { return &s.x; } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22118.d b/gcc/testsuite/gdc.test/fail_compilation/fail22118.d index 7408661..bd34c56 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail22118.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22118.d @@ -33,4 +33,3 @@ struct S v.a = arg; // this should not } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22825a.d b/gcc/testsuite/gdc.test/fail_compilation/fail22825a.d new file mode 100644 index 0000000..d8d1093 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22825a.d @@ -0,0 +1,11 @@ +// https://issues.dlang.org/show_bug.cgi?id=22825 +/* TEST_OUTPUT: +--- +fail_compilation/fail22825a.d(10): Error: positive integer argument expected following `#line` +fail_compilation/fail22825a.d(11): Error: declaration expected, not `42` +--- +*/ +#line /* + multi-line comment +*/ +42 diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22825b.d b/gcc/testsuite/gdc.test/fail_compilation/fail22825b.d new file mode 100644 index 0000000..faac8b4 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22825b.d @@ -0,0 +1,13 @@ +// https://issues.dlang.org/show_bug.cgi?id=22825 +/* TEST_OUTPUT: +--- +fail_compilation/fail22825b.d(7): Error: declaration expected, not `#` +--- +*/ +# + line + + + + +12 diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail2361.d b/gcc/testsuite/gdc.test/fail_compilation/fail2361.d index 57edd3a..ffc12f1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail2361.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail2361.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail2361.d(13): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. +fail_compilation/fail2361.d(14): Error: the `delete` keyword is obsolete +fail_compilation/fail2361.d(14): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail249.d b/gcc/testsuite/gdc.test/fail_compilation/fail249.d index 82b291f..a0d1940 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail249.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail249.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail249.d(16): Error: invalid `foreach` aggregate `bar()` +fail_compilation/fail249.d(16): Error: invalid `foreach` aggregate `bar()` of type `void` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail258.d b/gcc/testsuite/gdc.test/fail_compilation/fail258.d index 63cbfd4..dd1d2f3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail258.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail258.d @@ -14,4 +14,3 @@ q" X X" - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail259.d b/gcc/testsuite/gdc.test/fail_compilation/fail259.d index 0c31b23..cbada7c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail259.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail259.d @@ -10,4 +10,3 @@ class C final override void foo(){} } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail261.d b/gcc/testsuite/gdc.test/fail_compilation/fail261.d index 73e062c..85da957 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail261.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail261.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail261.d(18): Error: invalid `foreach` aggregate `range`, define `opApply()`, range primitives, or use `.tupleof` +fail_compilation/fail261.d(19): Error: invalid `foreach` aggregate `range` of type `MyRange` +fail_compilation/fail261.d(19): maybe define `opApply()`, range primitives, or use `.tupleof` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail346.d b/gcc/testsuite/gdc.test/fail_compilation/fail346.d index af491bd..77042cc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail346.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail346.d @@ -21,4 +21,3 @@ template V(R,int val){ } const S x = V!(S,0); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail359.d b/gcc/testsuite/gdc.test/fail_compilation/fail359.d index c6a23ad..71e9143 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail359.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail359.d @@ -1,10 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail359.d(8): Error: #line integer ["filespec"]\n expected -fail_compilation/fail359.d(9): Error: no identifier for declarator `_BOOM` +fail_compilation/fail359.d(7): Error: invalid filename for `#line` directive --- */ #line 5 _BOOM void main() { } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail3895.d b/gcc/testsuite/gdc.test/fail_compilation/fail3895.d index 3879ef5..1aafd96 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail3895.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail3895.d @@ -11,4 +11,3 @@ void main() { float[] otherStuff; otherStuff ~= stuff; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4269a.d b/gcc/testsuite/gdc.test/fail_compilation/fail4269a.d index 69b142e..be59e1f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4269a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4269a.d @@ -12,4 +12,3 @@ interface A { B blah; void foo(B b){} } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4269b.d b/gcc/testsuite/gdc.test/fail_compilation/fail4269b.d index e0ebd2f..7c371d1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4269b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4269b.d @@ -11,4 +11,3 @@ struct A { B blah; void foo(B b){} } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4269c.d b/gcc/testsuite/gdc.test/fail_compilation/fail4269c.d index 5bba42e..c12f9b6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4269c.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4269c.d @@ -11,4 +11,3 @@ class A { B blah; void foo(B b){} } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375a.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375a.d index a07f78f..322bcb3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375a.d @@ -16,4 +16,3 @@ void main() { else assert(4); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375b.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375b.d index dbc299f..6e6b9b0 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375b.d @@ -18,4 +18,3 @@ void main() { else assert(6); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375c.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375c.d index 230c656..ef7a792 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375c.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375c.d @@ -18,4 +18,3 @@ void main() { assert(6.2); } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375d.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375d.d index 9c6aaed..7b2740a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375d.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375d.d @@ -17,4 +17,3 @@ label2: else assert(16); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375e.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375e.d index 3ccd4fb..1b7f7d2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375e.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375e.d @@ -16,4 +16,3 @@ void main() { else assert(25); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375f.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375f.d index 867fbff..c603bfa 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375f.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375f.d @@ -16,4 +16,3 @@ void main() { else assert(25.2); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375g.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375g.d index 6f452f53..a3d7c85 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375g.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375g.d @@ -16,4 +16,3 @@ void main() { else assert(34); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375h.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375h.d index c0f1c5b..04833b1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375h.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375h.d @@ -20,4 +20,3 @@ void main() { break; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375i.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375i.d index b13c9e4..2fe2bb7 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375i.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375i.d @@ -18,4 +18,3 @@ void main() { else assert(116); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375j.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375j.d index 8f24700..89ad096 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375j.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375j.d @@ -18,4 +18,3 @@ void main() { else assert(120); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375k.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375k.d index 8c21fea..05ceb06 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375k.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375k.d @@ -18,4 +18,3 @@ void main() { assert(55); }); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375l.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375l.d index 1c815ea..731ead6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375l.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375l.d @@ -17,4 +17,3 @@ void main() { else assert(71); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375m.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375m.d index 7cbf20f..b5d1c16 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375m.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375m.d @@ -18,4 +18,3 @@ void main() { assert(77); while (false); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375o.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375o.d index fbfde4e..3112de7 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375o.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375o.d @@ -17,4 +17,3 @@ void main() { else assert(83); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375p.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375p.d index 52a6e65..62c61a4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375p.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375p.d @@ -19,4 +19,3 @@ void main() { else assert(89); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375q.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375q.d index f445eab..b02fbb1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375q.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375q.d @@ -17,4 +17,3 @@ void main() { else assert(91); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375r.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375r.d index dfa7731..865bd6d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375r.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375r.d @@ -19,4 +19,3 @@ void main() { else assert(105); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375s.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375s.d index f85a1db..972f2764 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375s.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375s.d @@ -19,4 +19,3 @@ void main() { else assert(108); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375t.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375t.d index 0fd1f4d..07a79e5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375t.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375t.d @@ -16,4 +16,3 @@ unittest { // disallowed else assert(53); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375u.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375u.d index 8e2ea13..a3b22e9 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375u.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375u.d @@ -14,4 +14,3 @@ static if (true) struct G1 {} else struct G2 {} - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375v.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375v.d index 8b99a9c..2be98a6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375v.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375v.d @@ -14,4 +14,3 @@ version (A) struct G3 {} else struct G4 {} - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375w.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375w.d index ecfffb6..eb0779f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375w.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375w.d @@ -14,4 +14,3 @@ static if (true) struct G1 {} else struct G2 {} - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375x.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375x.d index f29a6e3..6a5f9db 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375x.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375x.d @@ -15,4 +15,3 @@ abstract: class G5 {} else class G6 {} - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4375y.d b/gcc/testsuite/gdc.test/fail_compilation/fail4375y.d index 3111623..28dc991 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4375y.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail4375y.d @@ -17,4 +17,3 @@ static if (true) void G10(){} else void G11(){} - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail44.d b/gcc/testsuite/gdc.test/fail_compilation/fail44.d index e2ea40b..826bdba 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail44.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail44.d @@ -18,4 +18,3 @@ void Foo() foo[i] = bar[i]; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail47.d b/gcc/testsuite/gdc.test/fail_compilation/fail47.d index 9da0c09..c45a990 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail47.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail47.d @@ -12,4 +12,3 @@ void main() { foo = 1; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail58.d b/gcc/testsuite/gdc.test/fail_compilation/fail58.d index 29d9e58..1557055 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail58.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail58.d @@ -33,4 +33,3 @@ int main(char[][] pArgs) assert(sp == -1); return 0; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail60.d b/gcc/testsuite/gdc.test/fail_compilation/fail60.d index 137dfa9..42fb4ac 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail60.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail60.d @@ -13,4 +13,3 @@ class A B b=new B; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail6107.d b/gcc/testsuite/gdc.test/fail_compilation/fail6107.d index 656b3cf..a21fbb7 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail6107.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail6107.d @@ -13,4 +13,3 @@ class Bar { int __ctor = 4; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7178.d b/gcc/testsuite/gdc.test/fail_compilation/fail7178.d index 8540249..38c4b00 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7178.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7178.d @@ -10,4 +10,3 @@ template populate(overloads...) mixin populate!(.contents); } public mixin populate!int; - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail72.d b/gcc/testsuite/gdc.test/fail_compilation/fail72.d index e6d8b8d..919baec 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail72.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail72.d @@ -12,4 +12,3 @@ void main() } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7234.d b/gcc/testsuite/gdc.test/fail_compilation/fail7234.d index f38308d..eb5ec7a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7234.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7234.d @@ -13,4 +13,3 @@ void foo() { Contract* r; if (r.empty) {} } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail73.d b/gcc/testsuite/gdc.test/fail_compilation/fail73.d index 0242201..d9dd8a3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail73.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail73.d @@ -26,4 +26,3 @@ void main() break; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7369.d b/gcc/testsuite/gdc.test/fail_compilation/fail7369.d index f17dc96..4ba11e4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7369.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7369.d @@ -8,4 +8,3 @@ struct S7369 { int a; invariant() { a += 5; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d index 220c995..f13ba14 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d @@ -9,4 +9,3 @@ struct S7424c @property int g()() { return 0; } void test() immutable { int f = g; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d index 669c9ff..38f47ba 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d @@ -9,4 +9,3 @@ struct S7424d @property int g()() immutable { return 0; } void test() const { int f = g; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d index 18bf414..e92b469 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d @@ -9,4 +9,3 @@ struct S7424e @property int g()() immutable { return 0; } void test() { int f = g; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d index 29e0ecc..1af14f8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d @@ -9,4 +9,3 @@ struct S7424f @property int g()() shared { return 0; } void test() { int f = g; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d index b4670de..4499b97 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d @@ -9,4 +9,3 @@ struct S7424g @property int g()() { return 0; } void test() shared { int f = g; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d index b76f5b3..e48408c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d @@ -9,4 +9,3 @@ struct S7424g @property int g()() { return 0; } void test() inout { int f = g; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d index 887c859..6352166 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d @@ -9,4 +9,3 @@ struct S7424g @property int g()() immutable { return 0; } void test() inout { int f = g; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7524a.d b/gcc/testsuite/gdc.test/fail_compilation/fail7524a.d index 834c315..237b313 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7524a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7524a.d @@ -2,8 +2,7 @@ REQUIRED_ARGS: -o- TEST_OUTPUT: ---- -fail_compilation/fail7524a.d(10): Error: #line integer ["filespec"]\n expected -fail_compilation/fail7524a.d(10): Error: declaration expected, not `"$r:\w+ +\d+ \d+$"` +fail_compilation/fail7524a.d(9): Error: invalid filename for `#line` directive ---- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7524b.d b/gcc/testsuite/gdc.test/fail_compilation/fail7524b.d index f462746..feee61b8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7524b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7524b.d @@ -2,8 +2,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7524b.d(10): Error: #line integer ["filespec"]\n expected -fail_compilation/fail7524b.d(10): Error: declaration expected, not `$n$L` +fail_compilation/fail7524b.d(9): Error: invalid filename for `#line` directive --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail77.d b/gcc/testsuite/gdc.test/fail_compilation/fail77.d index 687b0ad..2d291fc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail77.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail77.d @@ -11,4 +11,3 @@ void test() ub[] = cast(ubyte[4]) &i; //ub[] = (cast(ubyte*) &i)[0..4]; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail78.d b/gcc/testsuite/gdc.test/fail_compilation/fail78.d index 1fb2424..99572c4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail78.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail78.d @@ -7,4 +7,3 @@ fail_compilation/fail78.d(9): Error: undefined identifier `inch` auto yd = ft * 3; auto ft = inch * 12; - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7851.d b/gcc/testsuite/gdc.test/fail_compilation/fail7851.d index f5d9ea3..399192d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7851.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7851.d @@ -38,4 +38,3 @@ void main() { foreach (i; TL) { } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7859.d b/gcc/testsuite/gdc.test/fail_compilation/fail7859.d index ef8b770..c3d437c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7859.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7859.d @@ -11,4 +11,3 @@ mixin template C(alias B = cast(NonExistent)null) { } mixin C!(); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7861.d b/gcc/testsuite/gdc.test/fail_compilation/fail7861.d index e3a2d08..c7018c9 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7861.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7861.d @@ -15,4 +15,3 @@ mixin A!(); } enum C = B.nonexistent; - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7862.d b/gcc/testsuite/gdc.test/fail_compilation/fail7862.d index b408b44..08e6f69 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7862.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7862.d @@ -27,4 +27,3 @@ struct A { } auto d = A.init.c; - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail79.d b/gcc/testsuite/gdc.test/fail_compilation/fail79.d index 93fb7cb..affda79 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail79.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail79.d @@ -12,4 +12,3 @@ void main() p = &a + &b; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d index 235e480..96489d9 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d @@ -7,4 +7,3 @@ fail_compilation/fail8009.d(8): Candidate is: `filter(R)(scope bool deleg */ void filter(R)(scope bool delegate(ref BAD!R) func) { } void main() { filter(r => r); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail8179b.d b/gcc/testsuite/gdc.test/fail_compilation/fail8179b.d index 59fd231..e59648f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail8179b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail8179b.d @@ -9,4 +9,3 @@ void foo(int[2][1]) {} void main() { foo(cast(int[2][1])[1, 2]); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail8373.d b/gcc/testsuite/gdc.test/fail_compilation/fail8373.d index 2fb478d..6f6337d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail8373.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail8373.d @@ -20,4 +20,3 @@ template fun2(a...) { auto fun2(T...)(T args){ return 1; } } enum x1 = fun1(0); enum x2 = fun2(0); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail9199.d b/gcc/testsuite/gdc.test/fail_compilation/fail9199.d index 2a5cd01..6f181ed 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail9199.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail9199.d @@ -37,4 +37,3 @@ class C static void fsc() shared const {} static void fsw() shared inout {} } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail92.d b/gcc/testsuite/gdc.test/fail_compilation/fail92.d index 8e34199..ba4655e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail92.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail92.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail92.d(15): Error: invalid `foreach` aggregate `t` +fail_compilation/fail92.d(15): Error: invalid `foreach` aggregate `t` of type `typeof(null)` fail_compilation/fail92.d(23): Error: template instance `fail92.crash!(typeof(null))` error instantiating --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail95.d b/gcc/testsuite/gdc.test/fail_compilation/fail95.d index 7057a01..a1b3906 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail95.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail95.d @@ -19,4 +19,3 @@ void main() A(i); assert(i == 2); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail9665a.d b/gcc/testsuite/gdc.test/fail_compilation/fail9665a.d index abfe914..3d1b07e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail9665a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail9665a.d @@ -148,4 +148,3 @@ struct S4 static assert(__traits(compiles, v = 1)); // multiple initialization } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail9735.d b/gcc/testsuite/gdc.test/fail_compilation/fail9735.d index 42dbfdc..631468b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail9735.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail9735.d @@ -9,4 +9,3 @@ fail_compilation/fail9735.d(10): Deprecation: casting from void delegate() to vo void* dg2ptr(void delegate() dg) { return cast(void*) dg; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d index 7087b0c..e76a779 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d @@ -209,7 +209,8 @@ fail_compilation/fail_arrayop2.d(269): Error: array operation `"abc"[] + '\x01'` fail_compilation/fail_arrayop2.d(272): Error: array operation `[1] * 6` without destination memory not allowed fail_compilation/fail_arrayop2.d(275): Error: `([1] * 6)[0..2]` is not an lvalue and cannot be modified fail_compilation/fail_arrayop2.d(278): Error: can only `*` a pointer, not a `int[]` -fail_compilation/fail_arrayop2.d(281): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. +fail_compilation/fail_arrayop2.d(281): Error: the `delete` keyword is obsolete +fail_compilation/fail_arrayop2.d(281): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead fail_compilation/fail_arrayop2.d(284): Error: array operation `da[] * 6` without destination memory not allowed fail_compilation/fail_arrayop2.d(287): Error: array operation `da[] * 6` without destination memory not allowed fail_compilation/fail_arrayop2.d(290): Error: `[1] * 6` is not an lvalue and cannot be modified @@ -234,7 +235,6 @@ fail_compilation/fail_arrayop2.d(321): Error: array operation `[1] * 6` without fail_compilation/fail_arrayop2.d(321): Error: array operation `[1] * 6` without destination memory not allowed --- */ - // Test all expressions, which can take arrays as their operands but cannot be a part of array operation. void test15407exp() { diff --git a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d index 2355aa3..6612a67 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d +++ b/gcc/testsuite/gdc.test/fail_compilation/failcontracts.d @@ -21,4 +21,3 @@ void test() enum : int (int function() bode T); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/faildeleteaa.d b/gcc/testsuite/gdc.test/fail_compilation/faildeleteaa.d index 0a29997..ed640fb 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/faildeleteaa.d +++ b/gcc/testsuite/gdc.test/fail_compilation/faildeleteaa.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/faildeleteaa.d(11): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. +fail_compilation/faildeleteaa.d(12): Error: the `delete` keyword is obsolete +fail_compilation/faildeleteaa.d(12): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/failsafec.d b/gcc/testsuite/gdc.test/fail_compilation/failsafec.d index 4446e76..979f46c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/failsafec.d +++ b/gcc/testsuite/gdc.test/fail_compilation/failsafec.d @@ -12,4 +12,3 @@ void callingsystem() { sysdelegate(); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix18575.d b/gcc/testsuite/gdc.test/fail_compilation/fix18575.d index 7b8f287..49c0707 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fix18575.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fix18575.d @@ -1,10 +1,10 @@ /* REQUIRED_ARGS: -preview=dip1000 TEST_OUTPUT: --- -fail_compilation/fix18575.d(27): Error: returning `s.foo()` escapes a reference to local variable `s` -fail_compilation/fix18575.d(31): Error: returning `s.foo()` escapes a reference to local variable `s` -fail_compilation/fix18575.d(35): Error: returning `s.abc()` escapes a reference to local variable `s` -fail_compilation/fix18575.d(39): Error: returning `s.ghi(t)` escapes a reference to local variable `t` +fail_compilation/fix18575.d(27): Error: returning `s.foo()` escapes a reference to parameter `s` +fail_compilation/fix18575.d(31): Error: returning `s.foo()` escapes a reference to parameter `s` +fail_compilation/fix18575.d(35): Error: returning `s.abc()` escapes a reference to parameter `s` +fail_compilation/fix18575.d(39): Error: returning `s.ghi(t)` escapes a reference to parameter `t` --- */ @@ -38,4 +38,3 @@ auto h(S s) { auto j(S s, S t) { return s.ghi(t); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix21585.d b/gcc/testsuite/gdc.test/fail_compilation/fix21585.d index 48c74cb..7000f39 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fix21585.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fix21585.d @@ -16,4 +16,3 @@ alias T1 = Type!(__traits(toType)); alias T2 = Type!(__traits(toType, int)); alias T3 = Type!(__traits(toType, 1)); alias T4 = Type!(__traits(toType, "hello betty")); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix5212.d b/gcc/testsuite/gdc.test/fail_compilation/fix5212.d index faf2e29..0b804dc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fix5212.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fix5212.d @@ -14,4 +14,3 @@ class Foo { args = args_; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/fob1.d b/gcc/testsuite/gdc.test/fail_compilation/fob1.d index 1f23122..9dfcc4d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fob1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fob1.d @@ -17,6 +17,7 @@ fail_compilation/fob1.d(104): Error: variable `fob1.foo1.p` is returned but is U /* TEST_OUTPUT: --- +fail_compilation/fob1.d(204): Error: variable `fob1.foo2.p` assigning to Owner without disposing of owned value fail_compilation/fob1.d(203): Error: variable `fob1.foo2.p` is left dangling at return --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fob2.d b/gcc/testsuite/gdc.test/fail_compilation/fob2.d index 175ade3..6f100ee 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fob2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fob2.d @@ -176,3 +176,20 @@ void free7(int*); free7(p); } +/* TEST_OUTPUT: +--- +fail_compilation/fob2.d(807): Error: variable `fob2.test8.p` assigning to Owner without disposing of owned value +--- +*/ + +#line 800 + +int* malloc8(); +void free8(int*); + +@live void test8() +{ + int* p = malloc8(); + p = malloc8(); // error here + free8(p); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/format.d b/gcc/testsuite/gdc.test/fail_compilation/format.d index 3a24227..bc40d9a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/format.d +++ b/gcc/testsuite/gdc.test/fail_compilation/format.d @@ -41,4 +41,3 @@ pragma(printf) extern (C) int vprintf4(const(char)*, int, va_list); pragma(printf) extern (C) int vprintf5(const(char)*, va_list); pragma(printf) extern (C) int vprintf6(immutable(char)*, va_list); pragma(printf) extern (C) int vprintf7(char*, va_list); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/goto1.d b/gcc/testsuite/gdc.test/fail_compilation/goto1.d index b35a1c3..c4b807c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/goto1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/goto1.d @@ -23,4 +23,3 @@ void test2() return; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/goto3.d b/gcc/testsuite/gdc.test/fail_compilation/goto3.d index 4b811fa..ef3b5f7 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/goto3.d +++ b/gcc/testsuite/gdc.test/fail_compilation/goto3.d @@ -33,5 +33,3 @@ void test1() break; } } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10283.d b/gcc/testsuite/gdc.test/fail_compilation/ice10283.d index f52b8a2..489c45e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice10283.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice10283.d @@ -13,4 +13,3 @@ struct S10283 { string source = 7; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d b/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d index 6d3b223..ebefe33 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d @@ -4,8 +4,6 @@ TEST_OUTPUT: --- fail_compilation/imports/foo10727a.d(34): Error: undefined identifier `Frop` -fail_compilation/imports/foo10727a.d(26): Error: template instance `foo10727a.CirBuff!(Foo)` error instantiating -fail_compilation/imports/foo10727a.d(31): instantiated from here: `Bar!(Foo)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d b/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d index 4a59d5c..125ac12 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d @@ -4,8 +4,6 @@ TEST_OUTPUT: --- fail_compilation/imports/foo10727b.d(25): Error: undefined identifier `Frop` -fail_compilation/imports/foo10727b.d(17): Error: template instance `foo10727b.CirBuff!(Foo)` error instantiating -fail_compilation/imports/foo10727b.d(22): instantiated from here: `Bar!(Foo)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11968.d b/gcc/testsuite/gdc.test/fail_compilation/ice11968.d index ea44eae..1d50b66 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice11968.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice11968.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: ---- -fail_compilation/ice11968.d(8): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. +fail_compilation/ice11968.d(9): Error: the `delete` keyword is obsolete +fail_compilation/ice11968.d(9): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead ---- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice13027.d b/gcc/testsuite/gdc.test/fail_compilation/ice13027.d index 03c6820..5eafe61 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice13027.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice13027.d @@ -8,4 +8,3 @@ void main() { scope a = b!"c"; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d index f7c639d..1c6cf4b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d @@ -27,4 +27,3 @@ void test9361b() auto d = new D(); d.foo(); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9254a.d b/gcc/testsuite/gdc.test/fail_compilation/ice9254a.d index 6b8f2f3..d7086b4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice9254a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice9254a.d @@ -6,7 +6,7 @@ fail_compilation/ice9254a.d(15): Error: Using the result of a comma expression i fail_compilation/ice9254a.d(15): Error: Using the result of a comma expression is not allowed fail_compilation/ice9254a.d(15): Error: Using the result of a comma expression is not allowed fail_compilation/ice9254a.d(15): Error: Using the result of a comma expression is not allowed -fail_compilation/ice9254a.d(15): Error: invalid `foreach` aggregate `false` +fail_compilation/ice9254a.d(15): Error: invalid `foreach` aggregate `false` of type `bool` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9254b.d b/gcc/testsuite/gdc.test/fail_compilation/ice9254b.d index a430fbf..5484abd 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice9254b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice9254b.d @@ -6,7 +6,7 @@ fail_compilation/ice9254b.d(17): Error: Using the result of a comma expression i fail_compilation/ice9254b.d(17): Error: Using the result of a comma expression is not allowed fail_compilation/ice9254b.d(17): Error: Using the result of a comma expression is not allowed fail_compilation/ice9254b.d(17): Error: Using the result of a comma expression is not allowed -fail_compilation/ice9254b.d(17): Error: invalid `foreach` aggregate `false` +fail_compilation/ice9254b.d(17): Error: invalid `foreach` aggregate `false` of type `bool` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9254c.d b/gcc/testsuite/gdc.test/fail_compilation/ice9254c.d index b58cfe5..23eeecc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice9254c.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice9254c.d @@ -6,7 +6,7 @@ fail_compilation/ice9254c.d(15): Error: Using the result of a comma expression i fail_compilation/ice9254c.d(15): Error: Using the result of a comma expression is not allowed fail_compilation/ice9254c.d(15): Error: Using the result of a comma expression is not allowed fail_compilation/ice9254c.d(15): Error: Using the result of a comma expression is not allowed -fail_compilation/ice9254c.d(15): Error: invalid `foreach` aggregate `false` +fail_compilation/ice9254c.d(15): Error: invalid `foreach` aggregate `false` of type `bool` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/a10528.d b/gcc/testsuite/gdc.test/fail_compilation/imports/a10528.d index 8d2e1db..a12ef10 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/a10528.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/a10528.d @@ -3,4 +3,3 @@ private enum { b = "asdfgh" } struct S { private enum string c = "qwerty"; } class C { private enum string d = "qwerty"; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/a11850.d b/gcc/testsuite/gdc.test/fail_compilation/imports/a11850.d index c9a7682..1270584 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/a11850.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/a11850.d @@ -47,5 +47,3 @@ private struct FilterResult(alias pred, Range) return _input[0]; } } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/a14235.d b/gcc/testsuite/gdc.test/fail_compilation/imports/a14235.d index d2b6cb9..2ab5a12 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/a14235.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/a14235.d @@ -4,4 +4,4 @@ struct SomeThing(T...) { } -class SomeClass {}
\ No newline at end of file +class SomeClass {} diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/diag10141b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/diag10141b.d index 72ebce7..915aade 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/diag10141b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/diag10141b.d @@ -52,4 +52,3 @@ void put(R, E)(ref R r, E e) "Cannot put a "~E.stringof~" into a "~R.stringof); } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/diag9210stdcomplex.d b/gcc/testsuite/gdc.test/fail_compilation/imports/diag9210stdcomplex.d index 76a2cee..0afd990 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/diag9210stdcomplex.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/diag9210stdcomplex.d @@ -14,4 +14,3 @@ Complex!real expi(real y) { return Complex!real(0, 0); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test18480a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test18480a.d index f20cf8a..d046374 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/test18480a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test18480a.d @@ -1,3 +1,2 @@ public import imports.test18480b : TestTemplate; alias TestTemplate = TestTemplate; - diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164a.d index e5fcd43..1d0e41f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164a.d @@ -6,4 +6,3 @@ struct D(E) } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164b.d index ece5476..f04e5d4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164b.d @@ -1,4 +1,3 @@ import imports.test21164c; enum N = O(); alias Q = R!(N, S); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164c.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164c.d index 21a252f..9ff764b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164c.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164c.d @@ -7,4 +7,3 @@ struct O struct R(O U, int W) { } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164d.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164d.d index 08f83ea..7dbb60b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164d.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164d.d @@ -6,4 +6,3 @@ auto I() { AB; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test64a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test64a.d index cb87b95..9705c65 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/test64a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test64a.d @@ -1,4 +1,3 @@ module imports; const char[] file1 = "File1"; - diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue22820.d b/gcc/testsuite/gdc.test/fail_compilation/issue22820.d index af42b46..58397f35 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/issue22820.d +++ b/gcc/testsuite/gdc.test/fail_compilation/issue22820.d @@ -65,4 +65,3 @@ void main() { p = (*cp)[].ptr; p = (*e)[].ptr; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue22826.d b/gcc/testsuite/gdc.test/fail_compilation/issue22826.d index ee1802a..eb49d23 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/issue22826.d +++ b/gcc/testsuite/gdc.test/fail_compilation/issue22826.d @@ -1,7 +1,6 @@ /* TEST_OUTPUT: --- -fail_compilation/issue22826.d(7): Error: #line integer ["filespec"]\n expected -fail_compilation/issue22826.d(7): Error: declaration expected, not `3` +fail_compilation/issue22826.d(6): Error: found `3` when expecting new line following `#line` directive --- */ #line 12 "issue22826.d" 3 diff --git a/gcc/testsuite/gdc.test/fail_compilation/lexer1.d b/gcc/testsuite/gdc.test/fail_compilation/lexer1.d index 115f136..e6cabf2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/lexer1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/lexer1.d @@ -11,8 +11,8 @@ fail_compilation/lexer1.d(35): Error: declaration expected, not `0.1i` fail_compilation/lexer1.d(36): Error: declaration expected, not `0.1fi` fail_compilation/lexer1.d(37): Error: declaration expected, not `0.1Li` fail_compilation/lexer1.d(38): Error: declaration expected, not `' '` -fail_compilation/lexer1.d(39): Error: declaration expected, not `55295U` -fail_compilation/lexer1.d(40): Error: declaration expected, not `65536U` +fail_compilation/lexer1.d(39): Error: declaration expected, not `'\ud7ff'` +fail_compilation/lexer1.d(40): Error: declaration expected, not `'\U00010000'` fail_compilation/lexer1.d(41): Error: declaration expected, not `"ab\\c\"\u1234a\U00011100a\0ab"d` fail_compilation/lexer1.d(43): Error: declaration expected, not `module` fail_compilation/lexer1.d(45): Error: escape hex sequence has 1 hex digits instead of 2 diff --git a/gcc/testsuite/gdc.test/fail_compilation/lexer4.d b/gcc/testsuite/gdc.test/fail_compilation/lexer4.d index ecc7208..c9db264 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/lexer4.d +++ b/gcc/testsuite/gdc.test/fail_compilation/lexer4.d @@ -13,12 +13,12 @@ fail_compilation/lexer4.d(30): Error: exponent required for hex float fail_compilation/lexer4.d(31): Error: lower case integer suffix 'l' is not allowed. Please use 'L' instead fail_compilation/lexer4.d(32): Error: use 'i' suffix instead of 'I' fail_compilation/lexer4.d(34): Error: line number `1234567891234567879` out of range -fail_compilation/lexer4.d(36): Error: #line integer ["filespec"]\n expected -fail_compilation/lexer4.d(19): Error: #line integer ["filespec"]\n expected -fail_compilation/lexer4.d(19): Error: declaration expected, not `"file"` +fail_compilation/lexer4.d(36): Error: positive integer argument expected following `#line` +fail_compilation/lexer4.d(19): Error: found `"file"` when expecting new line following `#line` directive --- */ + static c1 = ' ; static c2 = ''; diff --git a/gcc/testsuite/gdc.test/fail_compilation/mangle2.d b/gcc/testsuite/gdc.test/fail_compilation/mangle2.d index 415e719..69e148f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/mangle2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/mangle2.d @@ -39,4 +39,3 @@ __gshared extern pragma(mangle, "test\09") ubyte test9_5_e; //\xff chars __gshared pragma(mangle, "test\xff9") ubyte test9_6; __gshared extern pragma(mangle, "test\xff9") ubyte test9_6_e; - diff --git a/gcc/testsuite/gdc.test/fail_compilation/no_TypeInfo.d b/gcc/testsuite/gdc.test/fail_compilation/no_TypeInfo.d index a55332a..78056fc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/no_TypeInfo.d +++ b/gcc/testsuite/gdc.test/fail_compilation/no_TypeInfo.d @@ -13,4 +13,3 @@ void test() int i; auto ti = typeid(i); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/nogc1.d b/gcc/testsuite/gdc.test/fail_compilation/nogc1.d index 8f18ec5..859bd40 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/nogc1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/nogc1.d @@ -63,9 +63,12 @@ fail_compilation/nogc1.d(55): Error: cannot use `new` in `@nogc` function `nogc1 /* TEST_OUTPUT: --- -fail_compilation/nogc1.d(73): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/nogc1.d(74): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. -fail_compilation/nogc1.d(75): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. +fail_compilation/nogc1.d(76): Error: the `delete` keyword is obsolete +fail_compilation/nogc1.d(76): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/nogc1.d(77): Error: the `delete` keyword is obsolete +fail_compilation/nogc1.d(77): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead +fail_compilation/nogc1.d(78): Error: the `delete` keyword is obsolete +fail_compilation/nogc1.d(78): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead --- */ @nogc void testDelete(int* p, Object o, S1* s) diff --git a/gcc/testsuite/gdc.test/fail_compilation/opapplyscope.d b/gcc/testsuite/gdc.test/fail_compilation/opapplyscope.d index b15d6e4..8414bf1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/opapplyscope.d +++ b/gcc/testsuite/gdc.test/fail_compilation/opapplyscope.d @@ -24,4 +24,3 @@ void test() @safe global = x; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/pragmainline.d b/gcc/testsuite/gdc.test/fail_compilation/pragmainline.d index 6d935a0..5d43277 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/pragmainline.d +++ b/gcc/testsuite/gdc.test/fail_compilation/pragmainline.d @@ -7,4 +7,3 @@ fail_compilation/pragmainline.d(8): Error: pragma `inline` one boolean expressio pragma(inline, 1,2,3) void bar(); pragma(inline, "string") void baz(); // works now - diff --git a/gcc/testsuite/gdc.test/fail_compilation/pragmas.d b/gcc/testsuite/gdc.test/fail_compilation/pragmas.d index 25ab151..cd56ff4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/pragmas.d +++ b/gcc/testsuite/gdc.test/fail_compilation/pragmas.d @@ -30,5 +30,3 @@ void test4() { pragma(unrecognized, "string"); } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d index eeea28c..6e7e909 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d +++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d @@ -116,6 +116,7 @@ fail_compilation/reserved_version.d(217): Error: version identifier `AVR` is res fail_compilation/reserved_version.d(218): Error: version identifier `D_PreConditions` is reserved and cannot be set fail_compilation/reserved_version.d(219): Error: version identifier `D_PostConditions` is reserved and cannot be set fail_compilation/reserved_version.d(220): Error: version identifier `D_ProfileGC` is reserved and cannot be set +fail_compilation/reserved_version.d(221): Error: version identifier `D_Invariants` is reserved and cannot be set --- */ @@ -238,6 +239,7 @@ version = AVR; version = D_PreConditions; version = D_PostConditions; version = D_ProfileGC; +version = D_Invariants; // This should work though debug = DigitalMars; diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d index 792ea0a..cd85b41 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d +++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d @@ -106,6 +106,7 @@ // REQUIRED_ARGS: -version=D_PreConditions // REQUIRED_ARGS: -version=D_PostConditions // REQUIRED_ARGS: -version=D_ProfileGC +// REQUIRED_ARGS: -version=D_Invariants // REQUIRED_ARGS: -debug=DigitalMars // REQUIRED_ARGS: -debug=GNU // REQUIRED_ARGS: -debug=LDC @@ -209,6 +210,7 @@ // REQUIRED_ARGS: -debug=D_PreConditions // REQUIRED_ARGS: -debug=D_PostConditions // REQUIRED_ARGS: -debug=D_ProfileGC +// REQUIRED_ARGS: -debug=D_Invariants /* TEST_OUTPUT: --- @@ -318,5 +320,6 @@ Error: version identifier `none` is reserved and cannot be set Error: version identifier `D_PreConditions` is reserved and cannot be set Error: version identifier `D_PostConditions` is reserved and cannot be set Error: version identifier `D_ProfileGC` is reserved and cannot be set +Error: version identifier `D_Invariants` is reserved and cannot be set --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d index 68269ae..4f1e324 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d @@ -315,4 +315,3 @@ struct S1300 int* oops; // this(int* p) @safe { oops = p; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope3.d b/gcc/testsuite/gdc.test/fail_compilation/retscope3.d index 130d49b..951ad59 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope3.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope3.d @@ -53,47 +53,6 @@ void bar4() /* TEST_OUTPUT: --- -fail_compilation/retscope3.d(3027): Error: scope variable `l` assigned to `elem` with longer lifetime ---- -*/ - -#line 3000 - -struct List -{ - Elem front() @safe return scope; - - ~this() @trusted scope; - - @disable this(this); - - void* data; -} - -struct Elem -{ - void* data; -} - -List list() @trusted -{ - return List(); -} - -void test3000() @safe -{ - Elem elem; - { - auto l = list(); // inferred as scope - elem = l.front; // escapes, b/c l isn't scoped - } -} - -/**********************************************/ - -/* -TEST_OUTPUT: ---- fail_compilation/retscope3.d(4003): Error: copying `u[]` into allocated memory escapes a reference to variadic parameter `u` fail_compilation/retscope3.d(4016): Error: storing reference to outer local variable `i` into allocated memory causes it to escape fail_compilation/retscope3.d(4025): Error: storing reference to stack allocated value returned by `makeSA()` into allocated memory causes it to escape diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope5.d b/gcc/testsuite/gdc.test/fail_compilation/retscope5.d index 0625d8e..a4c8d58 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope5.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope5.d @@ -23,4 +23,3 @@ void test() @safe p = &t.a; // should not compile } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d index 47f216f..7e68bfc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d @@ -231,3 +231,23 @@ const(int)* f_c_20150() @safe int x = 42; return escape_c_20150(&x); } + +/* TEST_OUTPUT: +--- +fail_compilation/retscope6.d(13010): Error: reference to local variable `str` assigned to non-scope parameter `x` calling retscope6.f_throw +--- +*/ + +#line 13000 +// https://issues.dlang.org/show_bug.cgi?id=22221 + +void f_throw(string x) @safe pure +{ + throw new Exception(x); +} + +void escape_throw_20150() @safe +{ + immutable(char)[4] str; + f_throw(str[]); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/shared.d b/gcc/testsuite/gdc.test/fail_compilation/shared.d index 6011d17..ab6f540 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/shared.d +++ b/gcc/testsuite/gdc.test/fail_compilation/shared.d @@ -91,7 +91,6 @@ fail_compilation/shared.d(2194): Error: direct access to shared `(new shared(K2) fail_compilation/shared.d(2202): Error: direct access to shared `c` is not allowed, see `core.atomic` fail_compilation/shared.d(2206): Error: function `shared.test_inference_2` function returns `shared` but cannot be inferred `ref` fail_compilation/shared.d(2208): Error: returning `c` escapes a reference to parameter `c` -fail_compilation/shared.d(2208): perhaps annotate the parameter with `return` fail_compilation/shared.d(2214): Error: function `shared.test_inference_3` function returns `shared` but cannot be inferred `ref` fail_compilation/shared.d(2216): return value `getSharedObject()` is not an lvalue fail_compilation/shared.d(2222): Error: direct access to shared `a` is not allowed, see `core.atomic` @@ -100,6 +99,7 @@ fail_compilation/shared.d(2222): cannot implicitly convert `a` of type `s fail_compilation/shared.d(2222): Error: cannot implicitly convert expression `a` of type `shared(const(Object))` to `object.Object` --- */ + #line 2100 // Derived from https://issues.dlang.org/show_bug.cgi?id=20908 ref shared(int) test20908() diff --git a/gcc/testsuite/gdc.test/fail_compilation/switches.d b/gcc/testsuite/gdc.test/fail_compilation/switches.d index da66d0e..b53fb4c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/switches.d +++ b/gcc/testsuite/gdc.test/fail_compilation/switches.d @@ -91,5 +91,3 @@ int test(int n) return y; } } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test1021.d b/gcc/testsuite/gdc.test/fail_compilation/test1021.d index 0792545..b3bb5b3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test1021.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test1021.d @@ -167,5 +167,3 @@ void test5c() S5c s; foo5(s, s); } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test11047.d b/gcc/testsuite/gdc.test/fail_compilation/test11047.d index 2cbc9c6..6f4f644 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test11047.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test11047.d @@ -15,5 +15,3 @@ int x; __traits(getAttributes, foo); __traits(getAttributes, foo)[0]; } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test11176.d b/gcc/testsuite/gdc.test/fail_compilation/test11176.d index 6c94b40..cf60b80 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test11176.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test11176.d @@ -15,4 +15,3 @@ fail_compilation/test11176.d(16): Error: `b.ptr` cannot be used in `@safe` code, @safe ubyte oops(ubyte[3] b) { return *b.ptr; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test13536.d b/gcc/testsuite/gdc.test/fail_compilation/test13536.d index e29861f..c45d76a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test13536.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test13536.d @@ -23,4 +23,3 @@ void fun() @safe { u.sysDg = &s.sysMethod; u.safeDg(); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test13537.d b/gcc/testsuite/gdc.test/fail_compilation/test13537.d index a92a7c1..8e9811c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test13537.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test13537.d @@ -57,4 +57,3 @@ void gun() @system @safe: void abc(ref int x) { } void def(const ref int x) { } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test14496.d b/gcc/testsuite/gdc.test/fail_compilation/test14496.d index 2835907..92dd3cf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test14496.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test14496.d @@ -48,6 +48,3 @@ struct Baz { Bar bar; Baz baz; } - - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15399.d b/gcc/testsuite/gdc.test/fail_compilation/test15399.d index 00ec33a..fe9934a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test15399.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test15399.d @@ -44,4 +44,3 @@ struct S2 @safe void bar(ref int*); @safe void cbar(ref const int*); @safe void sinister(out int*); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15544.d b/gcc/testsuite/gdc.test/fail_compilation/test15544.d index eeb4492..91ac675 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test15544.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test15544.d @@ -46,5 +46,3 @@ void testClosure1() dg = &bar; // Error auto dg2 = &bar; } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15660.d b/gcc/testsuite/gdc.test/fail_compilation/test15660.d index c979bb5..be244d7 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test15660.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test15660.d @@ -19,4 +19,3 @@ void main() void[] v; immutable x = f(v); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15672.d b/gcc/testsuite/gdc.test/fail_compilation/test15672.d index 859521d..1c3bedf 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test15672.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test15672.d @@ -34,5 +34,3 @@ alias const(byte) CT; { return cast(T[])[]; } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15703.d b/gcc/testsuite/gdc.test/fail_compilation/test15703.d index 1665e85..dd07857 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test15703.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test15703.d @@ -28,4 +28,3 @@ void test2() @safe const(ubyte)[] a; auto b = cast(const(uint[])) a; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15704.d b/gcc/testsuite/gdc.test/fail_compilation/test15704.d index d818033..2be9d30 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test15704.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test15704.d @@ -14,4 +14,3 @@ void main() @safe { arr1[] = arr2[]; // overwrites pointers with arbitrary ints } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15989.d b/gcc/testsuite/gdc.test/fail_compilation/test15989.d index a78dec4..38ca331 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test15989.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test15989.d @@ -48,4 +48,3 @@ void test() enum c = new C(); enum pi = new int(3); } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16188.d b/gcc/testsuite/gdc.test/fail_compilation/test16188.d index 87c55ea..c8ab825 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test16188.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test16188.d @@ -27,4 +27,3 @@ struct Where } struct WhereField(FieldType) {} - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16193.d b/gcc/testsuite/gdc.test/fail_compilation/test16193.d index 4124c43..053f583 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test16193.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test16193.d @@ -41,4 +41,3 @@ void abc() @nogc { x++; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16195.d b/gcc/testsuite/gdc.test/fail_compilation/test16195.d index 6d6c51e..018ab0d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test16195.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test16195.d @@ -1,7 +1,8 @@ /* * TEST_OUTPUT: --- -fail_compilation/test16195.d(13): Error: The `delete` keyword is obsolete. Use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead. +fail_compilation/test16195.d(14): Error: the `delete` keyword is obsolete +fail_compilation/test16195.d(14): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16381.d b/gcc/testsuite/gdc.test/fail_compilation/test16381.d index b854c27..fd92798 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test16381.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test16381.d @@ -14,4 +14,3 @@ void bar() { float g = foo().ptr[0]; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16589.d b/gcc/testsuite/gdc.test/fail_compilation/test16589.d index 0e86081..dc4c593 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test16589.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test16589.d @@ -3,15 +3,15 @@ REQUIRED_ARGS: -preview=dip1000 TEST_OUTPUT: --- fail_compilation/test16589.d(26): Error: returning `&this.data` escapes a reference to parameter `this` -fail_compilation/test16589.d(26): perhaps annotate the function with `return` +fail_compilation/test16589.d(24): perhaps annotate the function with `return` fail_compilation/test16589.d(31): Error: returning `&this` escapes a reference to parameter `this` -fail_compilation/test16589.d(31): perhaps annotate the function with `return` +fail_compilation/test16589.d(29): perhaps annotate the function with `return` fail_compilation/test16589.d(37): Error: returning `&s.data` escapes a reference to parameter `s` -fail_compilation/test16589.d(37): perhaps annotate the parameter with `return` +fail_compilation/test16589.d(35): perhaps annotate the parameter with `return` fail_compilation/test16589.d(42): Error: returning `&s` escapes a reference to parameter `s` -fail_compilation/test16589.d(42): perhaps annotate the parameter with `return` -fail_compilation/test16589.d(47): Error: returning `&s.data` escapes a reference to local variable `s` -fail_compilation/test16589.d(52): Error: returning `& s` escapes a reference to local variable `s` +fail_compilation/test16589.d(40): perhaps annotate the parameter with `return` +fail_compilation/test16589.d(47): Error: returning `&s.data` escapes a reference to parameter `s` +fail_compilation/test16589.d(52): Error: returning `& s` escapes a reference to parameter `s` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17284.d b/gcc/testsuite/gdc.test/fail_compilation/test17284.d index ef19a56..713be42 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test17284.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test17284.d @@ -17,4 +17,3 @@ union U { C c; int i; } } pragma(msg, typeof(func!U)); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17425.d b/gcc/testsuite/gdc.test/fail_compilation/test17425.d index 77c4956..7140615 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test17425.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test17425.d @@ -29,4 +29,3 @@ enum a2 = __traits(getParameterStorageClasses, i, 4); enum a3 = __traits(getParameterStorageClasses, foo, int); enum a4 = __traits(getParameterStorageClasses, foo, 0, 1); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17450.d b/gcc/testsuite/gdc.test/fail_compilation/test17450.d index f350cbd..098adaa 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test17450.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test17450.d @@ -3,9 +3,9 @@ REQUIRED_ARGS: -preview=dip1000 TEST_OUTPUT: --- fail_compilation/test17450.d(17): Error: returning `&s.bar` escapes a reference to parameter `s` -fail_compilation/test17450.d(17): perhaps annotate the parameter with `return` +fail_compilation/test17450.d(16): perhaps annotate the parameter with `return` fail_compilation/test17450.d(20): Error: returning `&this.bar` escapes a reference to parameter `this` -fail_compilation/test17450.d(20): perhaps annotate the function with `return` +fail_compilation/test17450.d(19): perhaps annotate the function with `return` --- */ // https://issues.dlang.org/show_bug.cgi?id=17450 diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18282.d b/gcc/testsuite/gdc.test/fail_compilation/test18282.d index b853801..cf26878 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test18282.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test18282.d @@ -86,4 +86,3 @@ struct S S*[] arr; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18484.d b/gcc/testsuite/gdc.test/fail_compilation/test18484.d index 678609b..55d0ff1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test18484.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test18484.d @@ -23,4 +23,3 @@ int* test2() { return S().bar(); // error } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18644.d b/gcc/testsuite/gdc.test/fail_compilation/test18644.d index 20743ea..430967e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test18644.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test18644.d @@ -21,5 +21,3 @@ fail_compilation/test18644.d(22): Error: escaping reference to stack allocated v ref int foo() { return i; } return foo(); } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18708.d b/gcc/testsuite/gdc.test/fail_compilation/test18708.d index 5c6f162..16530ca 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test18708.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test18708.d @@ -60,5 +60,3 @@ class E : Exception super(msg, file, line); } } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21353.d b/gcc/testsuite/gdc.test/fail_compilation/test21353.d index 0f22fe7..55c84f9 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test21353.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test21353.d @@ -23,4 +23,3 @@ void main() imports.imp21353.P(); with (imports.imp21353) { P(); } // fixed } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21927.d b/gcc/testsuite/gdc.test/fail_compilation/test21927.d index fa23285..4791409 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test21927.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test21927.d @@ -2,8 +2,8 @@ /* TEST_OUTPUT: --- -fail_compilation/test21927.d(17): Error: invalid `foreach` aggregate `this.T2(Args2...)` -fail_compilation/test21927.d(18): Error: invalid `foreach` aggregate `this.T2!()` +fail_compilation/test21927.d(17): Error: invalid `foreach` aggregate `this.T2(Args2...)` of type `void` +fail_compilation/test21927.d(18): Error: invalid `foreach` aggregate `this.T2!()` of type `void` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21939.d b/gcc/testsuite/gdc.test/fail_compilation/test21939.d index cb755ef..8f30bac 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test21939.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test21939.d @@ -2,7 +2,8 @@ /* TEST_OUTPUT: --- -fail_compilation/test21939.d(9): Error: invalid `foreach` aggregate `Object`, define `opApply()`, range primitives, or use `.tupleof` +fail_compilation/test21939.d(10): Error: invalid `foreach` aggregate `Object` of type `Object` +fail_compilation/test21939.d(10): maybe define `opApply()`, range primitives, or use `.tupleof` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22145.d b/gcc/testsuite/gdc.test/fail_compilation/test22145.d index 3e9f747..084083c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test22145.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test22145.d @@ -25,4 +25,3 @@ void test() @safe global = x; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22541.d b/gcc/testsuite/gdc.test/fail_compilation/test22541.d index 910db0a..6152f44 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test22541.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test22541.d @@ -2,7 +2,7 @@ TEST_OUTPUT: --- fail_compilation/test22541.d(104): Error: returning `i` escapes a reference to parameter `i` -fail_compilation/test22541.d(104): perhaps annotate the parameter with `return` +fail_compilation/test22541.d(102): perhaps annotate the parameter with `return` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22840.d b/gcc/testsuite/gdc.test/fail_compilation/test22840.d new file mode 100644 index 0000000..f7be64a --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test22840.d @@ -0,0 +1,26 @@ +/* REQUIRED_ARGS: -preview=dip1000 + * TEST_OUTPUT: +--- +fail_compilation/test22840.d(25): Error: returning `sb.slice()` escapes a reference to local variable `sb` +--- +*/ + +// inout method with inferred @safe escapes local data +// https://issues.dlang.org/show_bug.cgi?id=22840 + +// See also: https://issues.dlang.org/show_bug.cgi?id=20149 + +struct S +{ + int buf; + auto slice() inout + { + return &buf; + } +} + +int* fun() @safe +{ + S sb; + return sb.slice(); // should error +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22910.d b/gcc/testsuite/gdc.test/fail_compilation/test22910.d new file mode 100644 index 0000000..581c693 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test22910.d @@ -0,0 +1,19 @@ +/* REQUIRED_ARGS: -preview=dip1000 +TEST_OUTPUT: +--- +fail_compilation/test22910.d(17): Error: returning `&this.val` escapes a reference to parameter `this` +fail_compilation/test22910.d(15): perhaps change the `return scope` into `scope return` +--- +*/ +@safe: + +struct S +{ + int val; + int* ptr; + + int* retScope() return scope + { + return &this.val; + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test3818.d b/gcc/testsuite/gdc.test/fail_compilation/test3818.d index c66db85..a8ee1b8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test3818.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test3818.d @@ -23,5 +23,3 @@ void test1() static foreach (a, b, c) { } - - diff --git a/gcc/testsuite/gdc.test/fail_compilation/test64.d b/gcc/testsuite/gdc.test/fail_compilation/test64.d index d10f669..35f85a2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test64.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test64.d @@ -16,4 +16,3 @@ int main(string[] args) //writefln(file1); return 0; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/testpull1810.d b/gcc/testsuite/gdc.test/fail_compilation/testpull1810.d index 73ac830..830e9af 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/testpull1810.d +++ b/gcc/testsuite/gdc.test/fail_compilation/testpull1810.d @@ -20,4 +20,3 @@ uint foo(uint i) } return 4; } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/testscopestatic.d b/gcc/testsuite/gdc.test/fail_compilation/testscopestatic.d index 45e73c0..86c6328 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/testscopestatic.d +++ b/gcc/testsuite/gdc.test/fail_compilation/testscopestatic.d @@ -21,4 +21,3 @@ void foo() scope int x; } } - diff --git a/gcc/testsuite/gdc.test/fail_compilation/varargsstc.d b/gcc/testsuite/gdc.test/fail_compilation/varargsstc.d index 674455b..e040574 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/varargsstc.d +++ b/gcc/testsuite/gdc.test/fail_compilation/varargsstc.d @@ -8,4 +8,3 @@ fail_compilation/varargsstc.d(102): Error: variadic parameter cannot have attrib int printf(const(char)*, const scope shared return ...); int printf(const(char)*, ref out scope immutable shared return ...); - diff --git a/gcc/testsuite/gdc.test/fail_compilation/warn12809.d b/gcc/testsuite/gdc.test/fail_compilation/warn12809.d index 06c998d..8daf44c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/warn12809.d +++ b/gcc/testsuite/gdc.test/fail_compilation/warn12809.d @@ -71,5 +71,3 @@ void test3() finally foo(); int x = 1; } - - diff --git a/gcc/testsuite/gdc.test/runnable/betterc.d b/gcc/testsuite/gdc.test/runnable/betterc.d index 0da798b..74967e9 100644 --- a/gcc/testsuite/gdc.test/runnable/betterc.d +++ b/gcc/testsuite/gdc.test/runnable/betterc.d @@ -199,4 +199,3 @@ void test18457() } assert(dtor == 1); } - diff --git a/gcc/testsuite/gdc.test/runnable/bug846.d b/gcc/testsuite/gdc.test/runnable/bug846.d index 71beb85..732168e 100644 --- a/gcc/testsuite/gdc.test/runnable/bug846.d +++ b/gcc/testsuite/gdc.test/runnable/bug846.d @@ -8,4 +8,3 @@ void main() auto num = removeIf( "abcdef".dup, ( char c ) { return c == 'c'; } ); assert(num == 5); } - diff --git a/gcc/testsuite/gdc.test/runnable/fix22372.d b/gcc/testsuite/gdc.test/runnable/fix22372.d index 55864a0..23681d9 100644 --- a/gcc/testsuite/gdc.test/runnable/fix22372.d +++ b/gcc/testsuite/gdc.test/runnable/fix22372.d @@ -35,4 +35,3 @@ void foo() assert(i == 1); // this fails } } - diff --git a/gcc/testsuite/gdc.test/runnable/functype.d b/gcc/testsuite/gdc.test/runnable/functype.d index 28e2709..5dad618 100644 --- a/gcc/testsuite/gdc.test/runnable/functype.d +++ b/gcc/testsuite/gdc.test/runnable/functype.d @@ -338,4 +338,3 @@ int main() printf("Success\n"); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/a18a.d b/gcc/testsuite/gdc.test/runnable/imports/a18a.d index 444f00a..cbec56c 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/a18a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/a18a.d @@ -25,4 +25,3 @@ class Container(T) : IContainer!(int) return new Enumerator!(int)(); } } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/a21a.d b/gcc/testsuite/gdc.test/runnable/imports/a21a.d index ded47da..6ffbecf 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/a21a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/a21a.d @@ -18,4 +18,3 @@ class SomeClass mixin GoodMixin; mixin BadMixin; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/bug846.d b/gcc/testsuite/gdc.test/runnable/imports/bug846.d index d83805d..49102af 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/bug846.d +++ b/gcc/testsuite/gdc.test/runnable/imports/bug846.d @@ -36,4 +36,3 @@ template removeIf( Buf, Pred ) return removeIf_!(ElemTypeOf!(Buf), Pred).fn( buf, pred ); } } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/c22a.d b/gcc/testsuite/gdc.test/runnable/imports/c22a.d index 98f49bc..82f2b8a 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/c22a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/c22a.d @@ -2,4 +2,3 @@ module imports.c22a; void afn1() {} void afn2() {} - diff --git a/gcc/testsuite/gdc.test/runnable/imports/c22b.d b/gcc/testsuite/gdc.test/runnable/imports/c22b.d index 0596933..af0c044 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/c22b.d +++ b/gcc/testsuite/gdc.test/runnable/imports/c22b.d @@ -3,4 +3,3 @@ module imports.c22b; public import imports.c22a : afn1; void bfn1() {} - diff --git a/gcc/testsuite/gdc.test/runnable/imports/link7745b.d b/gcc/testsuite/gdc.test/runnable/imports/link7745b.d index 2782782..f97230f 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/link7745b.d +++ b/gcc/testsuite/gdc.test/runnable/imports/link7745b.d @@ -3,5 +3,3 @@ struct C { auto asdfg() {} } // extreme test of bug 4820 void nextis(W)(void delegate() dg = {}) {} - - diff --git a/gcc/testsuite/gdc.test/runnable/imports/m1a.d b/gcc/testsuite/gdc.test/runnable/imports/m1a.d index 7489160..ac840b3 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/m1a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/m1a.d @@ -8,4 +8,3 @@ A aFunc( aliasM1 f ) } //A aFunc( A function() f ); - diff --git a/gcc/testsuite/gdc.test/runnable/imports/template2962a.d b/gcc/testsuite/gdc.test/runnable/imports/template2962a.d index 8cfb444..3ab2074 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/template2962a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/template2962a.d @@ -7,4 +7,3 @@ void main() { funcC!(bool)(1.0); foo!int(0); } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test10441b.d b/gcc/testsuite/gdc.test/runnable/imports/test10441b.d index 1f9318c..ea8e527 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test10441b.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test10441b.d @@ -6,4 +6,3 @@ auto foo()() { return 1; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test10441c.d b/gcc/testsuite/gdc.test/runnable/imports/test10441c.d index fa9686a..fc63f4d 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test10441c.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test10441c.d @@ -3,4 +3,3 @@ auto boo(T)(T t) { return 1; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test10a.d b/gcc/testsuite/gdc.test/runnable/imports/test10a.d index f75d375..4a634fc 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test10a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test10a.d @@ -6,4 +6,3 @@ void init() } int[1] it; - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test11039b.d b/gcc/testsuite/gdc.test/runnable/imports/test11039b.d index 7a56f8a..c14ed40 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test11039b.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test11039b.d @@ -4,4 +4,3 @@ module imports.test11039b; import test11039; static anotherGlobalField = SomeStruct!string("Hello Again!"); - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test13a.d b/gcc/testsuite/gdc.test/runnable/imports/test13a.d index 4512e41..a840fab 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test13a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test13a.d @@ -52,4 +52,3 @@ unittest { assert(pairA == pairB); printf("Pair tests passed!\r\n"); } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test27a.d b/gcc/testsuite/gdc.test/runnable/imports/test27a.d index 8a68a16..f49159a 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test27a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test27a.d @@ -15,4 +15,3 @@ public: Variant b = Variant(v); } } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test29a.d b/gcc/testsuite/gdc.test/runnable/imports/test29a.d index fe3ab97..9e834e2 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test29a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test29a.d @@ -3,4 +3,3 @@ module imports.test29a; private import imports.test29b; deprecated alias imports.test29b.qwert qwert; - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test31a.d b/gcc/testsuite/gdc.test/runnable/imports/test31a.d index 3d88280..150f92b 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test31a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test31a.d @@ -3,4 +3,3 @@ module imports.test31a; template Baz() { private void privfunc(){ } } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test32a.d b/gcc/testsuite/gdc.test/runnable/imports/test32a.d index 4d3ef36..158b766 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test32a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test32a.d @@ -7,4 +7,3 @@ struct S{ int f(){ return S.sizeof; // OK } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test35a.d b/gcc/testsuite/gdc.test/runnable/imports/test35a.d index b011934..e49ea80 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test35a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test35a.d @@ -36,4 +36,3 @@ template removeIf( Buf, Pred ) return removeIf_!(ElemTypeOf!(Buf), Pred).fn( buf, pred ); } } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test40a.d b/gcc/testsuite/gdc.test/runnable/imports/test40a.d index d894f45..e93dbff 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test40a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test40a.d @@ -38,4 +38,3 @@ class Context printf("context.func>\n"); } } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test41a.d b/gcc/testsuite/gdc.test/runnable/imports/test41a.d index 20750c9..bd55214 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test41a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test41a.d @@ -9,4 +9,3 @@ public void func(T)() { assert(false, "Blah"); } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test45a.d b/gcc/testsuite/gdc.test/runnable/imports/test45a.d index d466cbe..30d43df 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test45a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test45a.d @@ -14,4 +14,3 @@ int bar(T)(T t) printf("bar(t)\n"); return 3; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test45b.d b/gcc/testsuite/gdc.test/runnable/imports/test45b.d index d1b0c34..b64a576 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test45b.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test45b.d @@ -13,4 +13,3 @@ int bar(T)(T t, int i) printf("bar(t,i)\n"); return 4; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test46b.d b/gcc/testsuite/gdc.test/runnable/imports/test46b.d index e73122a..ab562c9 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test46b.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test46b.d @@ -7,4 +7,3 @@ class B private C!(char) c; this() { c = new C!(char); } } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test46c.d b/gcc/testsuite/gdc.test/runnable/imports/test46c.d index d5cc142f..1fe9acc 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test46c.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test46c.d @@ -4,4 +4,3 @@ class C(T) { void foo() { } } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test49a.d b/gcc/testsuite/gdc.test/runnable/imports/test49a.d index cb9c952..a017ec2 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test49a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test49a.d @@ -25,4 +25,3 @@ void baz() { alias Foo!(int) bar; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test57a.d b/gcc/testsuite/gdc.test/runnable/imports/test57a.d index 8da955f..237d602 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test57a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test57a.d @@ -6,5 +6,3 @@ import imports.test57b; // doesn't work void foo() { C!(int) x; } - - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test57b.d b/gcc/testsuite/gdc.test/runnable/imports/test57b.d index e667de5..8c59ce0 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test57b.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test57b.d @@ -1,3 +1,2 @@ module imports.test57b; class C(T) { struct X {} } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/test58a.d b/gcc/testsuite/gdc.test/runnable/imports/test58a.d index 1f3c6d4..74dd900 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/test58a.d +++ b/gcc/testsuite/gdc.test/runnable/imports/test58a.d @@ -4,4 +4,3 @@ void foo(T)() { long[] a; a[] = -a[]; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/testminitAA.d b/gcc/testsuite/gdc.test/runnable/imports/testminitAA.d index 0d5ddd8..7625cd1 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/testminitAA.d +++ b/gcc/testsuite/gdc.test/runnable/imports/testminitAA.d @@ -8,4 +8,3 @@ static this() printf("AA\n"); aa = 1; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/testminitBB.d b/gcc/testsuite/gdc.test/runnable/imports/testminitBB.d index 72a750c..a0be186 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/testminitBB.d +++ b/gcc/testsuite/gdc.test/runnable/imports/testminitBB.d @@ -8,4 +8,3 @@ static this() printf("BB\n"); bb = 1; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/testmod1b.d b/gcc/testsuite/gdc.test/runnable/imports/testmod1b.d index bedcbc6..47a8aaf 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/testmod1b.d +++ b/gcc/testsuite/gdc.test/runnable/imports/testmod1b.d @@ -5,4 +5,3 @@ import testmod1; void bar3() { Foo!(int) w; } - diff --git a/gcc/testsuite/gdc.test/runnable/imports/tlsa.d b/gcc/testsuite/gdc.test/runnable/imports/tlsa.d index b9957d9..7577304 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/tlsa.d +++ b/gcc/testsuite/gdc.test/runnable/imports/tlsa.d @@ -31,5 +31,3 @@ int bar4() } /*************************************/ - - diff --git a/gcc/testsuite/gdc.test/runnable/manboy.d b/gcc/testsuite/gdc.test/runnable/manboy.d index 8e53307..6f353e9 100644 --- a/gcc/testsuite/gdc.test/runnable/manboy.d +++ b/gcc/testsuite/gdc.test/runnable/manboy.d @@ -17,4 +17,3 @@ int main() assert(a(10, 1, -1, -1, 1, 0) == -67); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/nrvo.d b/gcc/testsuite/gdc.test/runnable/nrvo.d new file mode 100644 index 0000000..5c653fe --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/nrvo.d @@ -0,0 +1,30 @@ +/***************************************************/ + +struct S1 +{ + int x; + ~this() {} +} + +__gshared S1* s1ptr; + +S1 test1a() +{ + auto result = S1(123); + (() @trusted { result.x++; s1ptr = &result; })(); + return result; +} + +void test1() +{ + auto r = test1a(); + assert(r.x == 124); + assert(&r == s1ptr); +} + +/***************************************************/ + +void main() +{ + test1(); +} diff --git a/gcc/testsuite/gdc.test/runnable/pi.d b/gcc/testsuite/gdc.test/runnable/pi.d index bb5f0d0..73c5919 100644 --- a/gcc/testsuite/gdc.test/runnable/pi.d +++ b/gcc/testsuite/gdc.test/runnable/pi.d @@ -169,6 +169,3 @@ int tiszero() return false; return true; } - - - diff --git a/gcc/testsuite/gdc.test/runnable/template2962.d b/gcc/testsuite/gdc.test/runnable/template2962.d index 3993e81..a229230 100644 --- a/gcc/testsuite/gdc.test/runnable/template2962.d +++ b/gcc/testsuite/gdc.test/runnable/template2962.d @@ -27,4 +27,3 @@ void bug2962comment36()(int p) int inner()() { return p; } alias inner!() finner; } - diff --git a/gcc/testsuite/gdc.test/runnable/test10441.d b/gcc/testsuite/gdc.test/runnable/test10441.d index 6dc24ea..9a1bf9c 100644 --- a/gcc/testsuite/gdc.test/runnable/test10441.d +++ b/gcc/testsuite/gdc.test/runnable/test10441.d @@ -7,4 +7,3 @@ void main() boo(1); foo(); } - diff --git a/gcc/testsuite/gdc.test/runnable/test10942.d b/gcc/testsuite/gdc.test/runnable/test10942.d index 8c45c20..0c19dad 100644 --- a/gcc/testsuite/gdc.test/runnable/test10942.d +++ b/gcc/testsuite/gdc.test/runnable/test10942.d @@ -30,4 +30,3 @@ string getEnum(size_t count) mixin(getEnum(1087)); void main() { } - diff --git a/gcc/testsuite/gdc.test/runnable/test11.d b/gcc/testsuite/gdc.test/runnable/test11.d index abaae37..6735a81 100644 --- a/gcc/testsuite/gdc.test/runnable/test11.d +++ b/gcc/testsuite/gdc.test/runnable/test11.d @@ -1389,5 +1389,3 @@ int main(string[] argv) printf("Success\n"); return 0; } - - diff --git a/gcc/testsuite/gdc.test/runnable/test11039.d b/gcc/testsuite/gdc.test/runnable/test11039.d index cc5cdba..0900609 100644 --- a/gcc/testsuite/gdc.test/runnable/test11039.d +++ b/gcc/testsuite/gdc.test/runnable/test11039.d @@ -20,4 +20,3 @@ void main() globalField.getInnerField(); anotherGlobalField.getInnerField(); } - diff --git a/gcc/testsuite/gdc.test/runnable/test12.d b/gcc/testsuite/gdc.test/runnable/test12.d index 01c7486..22f4b84 100644 --- a/gcc/testsuite/gdc.test/runnable/test12.d +++ b/gcc/testsuite/gdc.test/runnable/test12.d @@ -1246,4 +1246,3 @@ int main(string[] argv) printf("Success\n"); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/test15568.d b/gcc/testsuite/gdc.test/runnable/test15568.d index d21ede2..ada6e3c 100644 --- a/gcc/testsuite/gdc.test/runnable/test15568.d +++ b/gcc/testsuite/gdc.test/runnable/test15568.d @@ -55,4 +55,3 @@ unittest a.foo(c, null, false); } - diff --git a/gcc/testsuite/gdc.test/runnable/test16140.d b/gcc/testsuite/gdc.test/runnable/test16140.d index 3004945..6ea66a3 100644 --- a/gcc/testsuite/gdc.test/runnable/test16140.d +++ b/gcc/testsuite/gdc.test/runnable/test16140.d @@ -29,4 +29,3 @@ void main() res ~= value; assert(res == [1, 2, 3]); } - diff --git a/gcc/testsuite/gdc.test/runnable/test17.d b/gcc/testsuite/gdc.test/runnable/test17.d index 4b17ede..b09cfb3 100644 --- a/gcc/testsuite/gdc.test/runnable/test17.d +++ b/gcc/testsuite/gdc.test/runnable/test17.d @@ -40,4 +40,3 @@ int main() ulog("point(1.2)\n"); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/test17246.d b/gcc/testsuite/gdc.test/runnable/test17246.d index 2d51720..778d62d 100644 --- a/gcc/testsuite/gdc.test/runnable/test17246.d +++ b/gcc/testsuite/gdc.test/runnable/test17246.d @@ -47,4 +47,3 @@ int main(string[] args) auto bar = genBar(args.length == 0); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/test19735.d b/gcc/testsuite/gdc.test/runnable/test19735.d index 8a1a5e7..98fc5da 100644 --- a/gcc/testsuite/gdc.test/runnable/test19735.d +++ b/gcc/testsuite/gdc.test/runnable/test19735.d @@ -19,4 +19,3 @@ void main() { assert(test1(1) == test2(1)); } - diff --git a/gcc/testsuite/gdc.test/runnable/test20036.d b/gcc/testsuite/gdc.test/runnable/test20036.d index 640de19..f22c1f7 100644 --- a/gcc/testsuite/gdc.test/runnable/test20036.d +++ b/gcc/testsuite/gdc.test/runnable/test20036.d @@ -7,4 +7,3 @@ void main() foreach(p; px) assert(p && *p == 7); } - diff --git a/gcc/testsuite/gdc.test/runnable/test20565.d b/gcc/testsuite/gdc.test/runnable/test20565.d index 47a8db3..df4a226 100644 --- a/gcc/testsuite/gdc.test/runnable/test20565.d +++ b/gcc/testsuite/gdc.test/runnable/test20565.d @@ -15,4 +15,3 @@ void main() assert(temp!int() == 5); } } - diff --git a/gcc/testsuite/gdc.test/runnable/test21.d b/gcc/testsuite/gdc.test/runnable/test21.d index 66e3cf2..c5323396 100644 --- a/gcc/testsuite/gdc.test/runnable/test21.d +++ b/gcc/testsuite/gdc.test/runnable/test21.d @@ -7,4 +7,3 @@ int main() TA!(int) variable; return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/test22175.d b/gcc/testsuite/gdc.test/runnable/test22175.d new file mode 100644 index 0000000..195001b --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test22175.d @@ -0,0 +1,32 @@ +// https://issues.dlang.org/show_bug.cgi?id=22175 + +struct Struct +{ + short a = 24, b = 25, c = 26, d = 27; + ubyte e = 28; +} + +Struct foo() { Struct s; s.a = 60; s.b = 61; s.c = 62, s.d = 63; s.e = 64; return s; } + +Struct test(int i) { + Struct var = i ? Struct() : foo(); + Struct nest() { return var; } + return nest(); +} + +int main() +{ + auto s = test(0); + assert(s.a == 60); + assert(s.b == 61); + assert(s.c == 62); + assert(s.d == 63); + assert(s.e == 64); + s = test(1); + assert(s.a == 24); + assert(s.b == 25); + assert(s.c == 26); + assert(s.d == 27); + assert(s.e == 28); + return 0; +} diff --git a/gcc/testsuite/gdc.test/runnable/test22945.d b/gcc/testsuite/gdc.test/runnable/test22945.d new file mode 100644 index 0000000..a8b968d --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test22945.d @@ -0,0 +1,38 @@ +/* +REQUIRED_ARGS: -release -check=assert=on +PERMUTE_ARGS: -check=invariant=on +*/ + +// https://issues.dlang.org/show_bug.cgi?id=22945 + +bool hitStruct; +bool hitClass; + +struct S +{ + this(int) {} + invariant { hitStruct = true; } +} + +class C +{ + this() {} + invariant { hitClass = true; } +} + +int main() +{ + cast(void) S(0); + cast(void) new C(); + + version(D_Invariants) + { + assert(hitStruct && hitClass); + } + else + { + assert(!hitStruct && !hitClass); + } + + return 0; +} diff --git a/gcc/testsuite/gdc.test/runnable/test27.d b/gcc/testsuite/gdc.test/runnable/test27.d index 9c0a8d0..a5f1606 100644 --- a/gcc/testsuite/gdc.test/runnable/test27.d +++ b/gcc/testsuite/gdc.test/runnable/test27.d @@ -10,4 +10,3 @@ int main() v.func(5); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/test28.d b/gcc/testsuite/gdc.test/runnable/test28.d index 8fb60b9..f744712 100644 --- a/gcc/testsuite/gdc.test/runnable/test28.d +++ b/gcc/testsuite/gdc.test/runnable/test28.d @@ -1339,4 +1339,3 @@ void main() printf("Success\n"); } - diff --git a/gcc/testsuite/gdc.test/runnable/test3.d b/gcc/testsuite/gdc.test/runnable/test3.d index 4c6b9de..36c1aa3 100644 --- a/gcc/testsuite/gdc.test/runnable/test3.d +++ b/gcc/testsuite/gdc.test/runnable/test3.d @@ -38,4 +38,3 @@ int main(string[] args) assert(a.bar == "lolobetty"); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/test30.d b/gcc/testsuite/gdc.test/runnable/test30.d index 384ff4c..5510021 100644 --- a/gcc/testsuite/gdc.test/runnable/test30.d +++ b/gcc/testsuite/gdc.test/runnable/test30.d @@ -7,4 +7,3 @@ int main() return 7; return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/test32.d b/gcc/testsuite/gdc.test/runnable/test32.d index d98d468..31f0cc7 100644 --- a/gcc/testsuite/gdc.test/runnable/test32.d +++ b/gcc/testsuite/gdc.test/runnable/test32.d @@ -8,4 +8,3 @@ void main() { assert(S.sizeof == int.sizeof); } - diff --git a/gcc/testsuite/gdc.test/runnable/test34.d b/gcc/testsuite/gdc.test/runnable/test34.d index dee6609..df46137 100644 --- a/gcc/testsuite/gdc.test/runnable/test34.d +++ b/gcc/testsuite/gdc.test/runnable/test34.d @@ -1317,5 +1317,3 @@ void main() printf("Success\n"); } - - diff --git a/gcc/testsuite/gdc.test/runnable/test40.d b/gcc/testsuite/gdc.test/runnable/test40.d index 2c1069d..497b0be 100644 --- a/gcc/testsuite/gdc.test/runnable/test40.d +++ b/gcc/testsuite/gdc.test/runnable/test40.d @@ -13,4 +13,3 @@ class Foo { void main() { Bar.foobar(); } - diff --git a/gcc/testsuite/gdc.test/runnable/test41.d b/gcc/testsuite/gdc.test/runnable/test41.d index fd89bab..02f59d0 100644 --- a/gcc/testsuite/gdc.test/runnable/test41.d +++ b/gcc/testsuite/gdc.test/runnable/test41.d @@ -26,4 +26,3 @@ int main() return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/test57.d b/gcc/testsuite/gdc.test/runnable/test57.d index 54cf672..c79b3f8 100644 --- a/gcc/testsuite/gdc.test/runnable/test57.d +++ b/gcc/testsuite/gdc.test/runnable/test57.d @@ -7,4 +7,3 @@ module test57; import imports.test57a; void main() {} - diff --git a/gcc/testsuite/gdc.test/runnable/test7932.d b/gcc/testsuite/gdc.test/runnable/test7932.d index 22aa279..8c6663e 100644 --- a/gcc/testsuite/gdc.test/runnable/test7932.d +++ b/gcc/testsuite/gdc.test/runnable/test7932.d @@ -28,4 +28,3 @@ void main() auto x = new C; x.f(1); } - diff --git a/gcc/testsuite/gdc.test/runnable/test9495.d b/gcc/testsuite/gdc.test/runnable/test9495.d index e8eaad8..309f0e3 100644 --- a/gcc/testsuite/gdc.test/runnable/test9495.d +++ b/gcc/testsuite/gdc.test/runnable/test9495.d @@ -28,4 +28,4 @@ void main(string[] args) { test9495a(); test9495b(); -}
\ No newline at end of file +} diff --git a/gcc/testsuite/gdc.test/runnable/testmain.d b/gcc/testsuite/gdc.test/runnable/testmain.d index d615e10..1f70f8c 100644 --- a/gcc/testsuite/gdc.test/runnable/testmain.d +++ b/gcc/testsuite/gdc.test/runnable/testmain.d @@ -3,4 +3,3 @@ // PERMUTE_ARGS: -betterC void foo() { } - diff --git a/gcc/testsuite/gdc.test/runnable/testmod2.d b/gcc/testsuite/gdc.test/runnable/testmod2.d index 111696a..1af9fbb 100644 --- a/gcc/testsuite/gdc.test/runnable/testmod2.d +++ b/gcc/testsuite/gdc.test/runnable/testmod2.d @@ -9,4 +9,3 @@ void main() void whatever() {} foo!(whatever)(); } - diff --git a/gcc/testsuite/gdc.test/runnable/testscope2.d b/gcc/testsuite/gdc.test/runnable/testscope2.d index 4de1eba..a1164dc 100644 --- a/gcc/testsuite/gdc.test/runnable/testscope2.d +++ b/gcc/testsuite/gdc.test/runnable/testscope2.d @@ -4,7 +4,7 @@ TEST_OUTPUT: --- foo1 ulong function(return ref int* delegate() return p) ref return foo2 int function(return ref int delegate() p) ref -foo3 int function(return ref inout(int*) p) ref +foo3 int function(ref inout(int*) p) ref foo4 int function(return ref inout(int*) p) ref --- */ @@ -47,13 +47,13 @@ void test3() // Test scope mangling assert(SS.foo1.mangleof == "_D10testscope22SS4foo1MFNcNjNkKDFNjZPiZm"); assert(SS.foo2.mangleof == "_D10testscope22SS4foo2MFNcNkKDFZiZi"); - assert(SS.foo3.mangleof == "_D10testscope22SS4foo3MFNcNkKNgPiZi"); + assert(SS.foo3.mangleof == "_D10testscope22SS4foo3MFNcKNgPiZi"); assert(SS.foo4.mangleof == "_D10testscope22SS4foo4MFNcNkKNgPiZi"); // Test scope pretty-printing assert(typeof(SS.foo1).stringof == "ref ulong(return ref int* delegate() return p) return"); assert(typeof(SS.foo2).stringof == "ref int(return ref int delegate() p)"); - assert(typeof(SS.foo3).stringof == "ref int(return ref inout(int*) p)"); + assert(typeof(SS.foo3).stringof == "ref int(ref inout(int*) p)"); assert(typeof(SS.foo4).stringof == "ref int(return ref inout(int*) p)"); } } diff --git a/gcc/testsuite/gdc.test/runnable/testthread2.d b/gcc/testsuite/gdc.test/runnable/testthread2.d index 53f8a3b..2c87ecd 100644 --- a/gcc/testsuite/gdc.test/runnable/testthread2.d +++ b/gcc/testsuite/gdc.test/runnable/testthread2.d @@ -111,4 +111,3 @@ void main() } } } - diff --git a/gcc/testsuite/gdc.test/runnable/tls.d b/gcc/testsuite/gdc.test/runnable/tls.d index 7b59509..04bbbd1 100644 --- a/gcc/testsuite/gdc.test/runnable/tls.d +++ b/gcc/testsuite/gdc.test/runnable/tls.d @@ -96,4 +96,3 @@ int main() printf("Success\n"); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/tls_dup.d b/gcc/testsuite/gdc.test/runnable/tls_dup.d index 6acffb4..8e171de 100644 --- a/gcc/testsuite/gdc.test/runnable/tls_dup.d +++ b/gcc/testsuite/gdc.test/runnable/tls_dup.d @@ -101,4 +101,3 @@ int main() printf("Success\n"); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable/xtest55.d b/gcc/testsuite/gdc.test/runnable/xtest55.d index f976520..b7d1266 100644 --- a/gcc/testsuite/gdc.test/runnable/xtest55.d +++ b/gcc/testsuite/gdc.test/runnable/xtest55.d @@ -21,4 +21,3 @@ int main() assert(stuff1.num == 1); return 0; } - diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cabi2.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cabi2.cpp index 31e5286..164f032 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cabi2.cpp +++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cabi2.cpp @@ -252,4 +252,3 @@ S16 ctest16(char x, S16 s, char y) { #if __cplusplus } #endif - diff --git a/gcc/testsuite/gdc.test/runnable_cxx/test6716.d b/gcc/testsuite/gdc.test/runnable_cxx/test6716.d index edda423..6aeb25d 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/test6716.d +++ b/gcc/testsuite/gdc.test/runnable_cxx/test6716.d @@ -17,4 +17,4 @@ extern(C++) int test6716(int magic) { assert(magic == 12345); return 0; -}
\ No newline at end of file +} diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 77b6ad0..b1da32e 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -26b581670ef6e2643d74078f200d1cd21fa40e90 +c52e28b723ccfbe845a95e8e7b528e3cc0b9d790 The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index ba64131..6ca4012 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -294,13 +294,13 @@ DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \ DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \ core/sys/openbsd/err.d core/sys/openbsd/execinfo.d \ - core/sys/openbsd/pthread_np.d core/sys/openbsd/stdlib.d \ - core/sys/openbsd/string.d core/sys/openbsd/sys/cdefs.d \ - core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \ - core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \ - core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \ - core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d \ - core/sys/openbsd/unistd.d + core/sys/openbsd/pthread_np.d core/sys/openbsd/pwd.d \ + core/sys/openbsd/stdlib.d core/sys/openbsd/string.d \ + core/sys/openbsd/sys/cdefs.d core/sys/openbsd/sys/elf.d \ + core/sys/openbsd/sys/elf32.d core/sys/openbsd/sys/elf64.d \ + core/sys/openbsd/sys/elf_common.d core/sys/openbsd/sys/link_elf.d \ + core/sys/openbsd/sys/mman.d core/sys/openbsd/sys/sysctl.d \ + core/sys/openbsd/time.d core/sys/openbsd/unistd.d DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \ core/sys/posix/arpa/inet.d core/sys/posix/config.d \ diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 1c64d35..f7f78d7 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -344,9 +344,10 @@ am__objects_14 = core/sys/netbsd/dlfcn.lo core/sys/netbsd/err.lo \ @DRUNTIME_OS_NETBSD_TRUE@am__objects_15 = $(am__objects_14) am__objects_16 = core/sys/openbsd/dlfcn.lo core/sys/openbsd/err.lo \ core/sys/openbsd/execinfo.lo core/sys/openbsd/pthread_np.lo \ - core/sys/openbsd/stdlib.lo core/sys/openbsd/string.lo \ - core/sys/openbsd/sys/cdefs.lo core/sys/openbsd/sys/elf.lo \ - core/sys/openbsd/sys/elf32.lo core/sys/openbsd/sys/elf64.lo \ + core/sys/openbsd/pwd.lo core/sys/openbsd/stdlib.lo \ + core/sys/openbsd/string.lo core/sys/openbsd/sys/cdefs.lo \ + core/sys/openbsd/sys/elf.lo core/sys/openbsd/sys/elf32.lo \ + core/sys/openbsd/sys/elf64.lo \ core/sys/openbsd/sys/elf_common.lo \ core/sys/openbsd/sys/link_elf.lo core/sys/openbsd/sys/mman.lo \ core/sys/openbsd/sys/sysctl.lo core/sys/openbsd/time.lo \ @@ -958,13 +959,13 @@ DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \ DRUNTIME_DSOURCES_OPENBSD = core/sys/openbsd/dlfcn.d \ core/sys/openbsd/err.d core/sys/openbsd/execinfo.d \ - core/sys/openbsd/pthread_np.d core/sys/openbsd/stdlib.d \ - core/sys/openbsd/string.d core/sys/openbsd/sys/cdefs.d \ - core/sys/openbsd/sys/elf.d core/sys/openbsd/sys/elf32.d \ - core/sys/openbsd/sys/elf64.d core/sys/openbsd/sys/elf_common.d \ - core/sys/openbsd/sys/link_elf.d core/sys/openbsd/sys/mman.d \ - core/sys/openbsd/sys/sysctl.d core/sys/openbsd/time.d \ - core/sys/openbsd/unistd.d + core/sys/openbsd/pthread_np.d core/sys/openbsd/pwd.d \ + core/sys/openbsd/stdlib.d core/sys/openbsd/string.d \ + core/sys/openbsd/sys/cdefs.d core/sys/openbsd/sys/elf.d \ + core/sys/openbsd/sys/elf32.d core/sys/openbsd/sys/elf64.d \ + core/sys/openbsd/sys/elf_common.d core/sys/openbsd/sys/link_elf.d \ + core/sys/openbsd/sys/mman.d core/sys/openbsd/sys/sysctl.d \ + core/sys/openbsd/time.d core/sys/openbsd/unistd.d DRUNTIME_DSOURCES_POSIX = core/sys/posix/aio.d \ core/sys/posix/arpa/inet.d core/sys/posix/config.d \ @@ -1619,6 +1620,7 @@ core/sys/openbsd/dlfcn.lo: core/sys/openbsd/$(am__dirstamp) core/sys/openbsd/err.lo: core/sys/openbsd/$(am__dirstamp) core/sys/openbsd/execinfo.lo: core/sys/openbsd/$(am__dirstamp) core/sys/openbsd/pthread_np.lo: core/sys/openbsd/$(am__dirstamp) +core/sys/openbsd/pwd.lo: core/sys/openbsd/$(am__dirstamp) core/sys/openbsd/stdlib.lo: core/sys/openbsd/$(am__dirstamp) core/sys/openbsd/string.lo: core/sys/openbsd/$(am__dirstamp) core/sys/openbsd/sys/$(am__dirstamp): diff --git a/libphobos/libdruntime/core/atomic.d b/libphobos/libdruntime/core/atomic.d index e6a82e5..4af3fdf 100644 --- a/libphobos/libdruntime/core/atomic.d +++ b/libphobos/libdruntime/core/atomic.d @@ -292,7 +292,7 @@ template cas(MemoryOrder succ = MemoryOrder.seq, MemoryOrder fail = MemoryOrder. in (atomicPtrIsProperlyAligned(here), "Argument `here` is not properly aligned") { // resolve implicit conversions - T arg1 = ifThis; + const T arg1 = ifThis; T arg2 = writeThis; static if (__traits(isFloating, T)) @@ -1276,4 +1276,13 @@ version (CoreUnittest) shared NoIndirections n; static assert(is(typeof(atomicLoad(n)) == NoIndirections)); } + + unittest // Issue 21631 + { + shared uint si1 = 45; + shared uint si2 = 38; + shared uint* psi = &si1; + + assert((&psi).cas(cast(const) psi, &si2)); + } } diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d index 930e0cd..cb8d433 100644 --- a/libphobos/libdruntime/core/demangle.d +++ b/libphobos/libdruntime/core/demangle.d @@ -1339,7 +1339,7 @@ pure @safe: TypeFunction: CallConvention FuncAttrs Arguments ArgClose Type */ - char[] parseTypeFunction( char[] name = null, IsDelegate isdg = IsDelegate.no ) return + char[] parseTypeFunction( char[] name = null, IsDelegate isdg = IsDelegate.no ) return scope { debug(trace) printf( "parseTypeFunction+\n" ); debug(trace) scope(success) printf( "parseTypeFunction-\n" ); diff --git a/libphobos/libdruntime/core/internal/array/casting.d b/libphobos/libdruntime/core/internal/array/casting.d index e862f8e..4366da8 100644 --- a/libphobos/libdruntime/core/internal/array/casting.d +++ b/libphobos/libdruntime/core/internal/array/casting.d @@ -17,12 +17,13 @@ builds. It is separate from `__ArrayCast` to minimize code bloat. Params: - fromType = name of the type being cast from - fromSize = total size in bytes of the array being cast from - toType = name of the type being cast o - toSize = total size in bytes of the array being cast to + fromType = name of the type being cast from + fromSize = total size in bytes of the array being cast from + fromLength = length of array being cast from + toType = name of the type being cast to + toElemSize = element size of array being cast to */ -private void onArrayCastError()(string fromType, size_t fromSize, string toType, size_t toSize) @trusted +private void onArrayCastError()(string fromType, size_t fromSize, size_t fromLength, string toType, size_t toElemSize) @trusted { import core.internal.string : unsignedToTempString; import core.memory : pureMalloc; @@ -45,17 +46,22 @@ private void onArrayCastError()(string fromType, size_t fromSize, string toType, index += N; } - add("An array of size "); - auto s = unsignedToTempString(fromSize); + add("`"); + add(fromType); + add("[]` of length "); + auto s = unsignedToTempString(fromLength); add(s[]); - add(" does not align on an array of size "); - s = unsignedToTempString(toSize); + add(" cannot be cast to `"); + add(toType); + add("[]` as its length in bytes ("); + s = unsignedToTempString(fromSize); add(s[]); - add(", so `"); - add(fromType); - add("` cannot be cast to `"); + add(") is not a multiple of `"); add(toType); - add("`"); + add(".sizeof` ("); + s = unsignedToTempString(toElemSize); + add(s[]); + add(")."); msg[index] = '\0'; // null-termination // first argument must evaluate to `false` at compile-time to maintain memory safety in release builds @@ -64,7 +70,7 @@ private void onArrayCastError()(string fromType, size_t fromSize, string toType, /** The compiler lowers expressions of `cast(TTo[])TFrom[]` to -this implementation. +this implementation. Note that this does not detect alignment problems. Params: from = the array to reinterpret-cast @@ -79,7 +85,7 @@ TTo[] __ArrayCast(TFrom, TTo)(return scope TFrom[] from) @nogc pure @trusted if ((fromSize % TTo.sizeof) != 0) { - onArrayCastError(TFrom.stringof, fromSize, TTo.stringof, toLength * TTo.sizeof); + onArrayCastError(TFrom.stringof, fromSize, from.length, TTo.stringof, TTo.sizeof); } struct Array @@ -113,3 +119,26 @@ TTo[] __ArrayCast(TFrom, TTo)(return scope TFrom[] from) @nogc pure @trusted foreach (v; s) assert(v == cast(short) 0xabab); } + +@system nothrow unittest +{ + string msg; + try + { + auto str = "hello"; + auto wstr = cast(wstring) str; + } + catch (Throwable t) + msg = t.msg; + + static immutable expected = "`immutable(char)[]` of length 5 cannot be cast to `immutable(wchar)[]` as " ~ + "its length in bytes (5) is not a multiple of `immutable(wchar).sizeof` (2)."; + + if (msg != expected) + { + import core.stdc.stdio; + printf("Expected: |%.*s|\n", cast(int) expected.length, expected.ptr); + printf("Actual : |%.*s|\n", cast(int) msg.length, msg.ptr); + assert(false); + } +} diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d index aa51867..e29e426 100644 --- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d +++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d @@ -2935,19 +2935,18 @@ struct Gcx else version (linux) { // clone() fits better as we don't want to do anything but scanning in the child process. - // no fork-handlera are called, so we can avoid deadlocks due to malloc locks. Probably related: + // no fork-handlers are called, so we can avoid deadlocks due to malloc locks. Probably related: // https://sourceware.org/bugzilla/show_bug.cgi?id=4737 import core.sys.linux.sched : clone; import core.sys.posix.signal : SIGCHLD; - enum CLONE_CHILD_CLEARTID = 0x00200000; /* Register exit futex and memory */ - const flags = CLONE_CHILD_CLEARTID | SIGCHLD; // child thread id not needed + const flags = SIGCHLD; // exit signal scope int delegate() scope dg = &child_mark; extern(C) static int wrap_delegate(void* arg) { auto dg = cast(int delegate() scope*)arg; return (*dg)(); } - char[256] stackbuf; // enough stack space for clone() to place some info for the child without stomping the parent stack + ubyte[256] stackbuf; // enough stack space for clone() to place some info for the child without stomping the parent stack auto stack = stackbuf.ptr + (isStackGrowingDown ? stackbuf.length : 0); auto pid = clone(&wrap_delegate, stack, flags, &dg); } @@ -2957,7 +2956,6 @@ struct Gcx auto pid = fork(); fork_needs_lock = true; } - assert(pid != -1); switch (pid) { case -1: // fork() failed, retry without forking @@ -3028,7 +3026,7 @@ struct Gcx //printf("\tpool address range = %p .. %p\n", minAddr, maxAddr); version (COLLECT_FORK) - bool doFork = shouldFork; + alias doFork = shouldFork; else enum doFork = false; @@ -3083,6 +3081,7 @@ Lmark: final switch (forkResult) { case ChildStatus.error: + // fork() failed, retry without forking disableFork(); goto Lmark; case ChildStatus.running: diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d index 92f8f70..dbe55a4 100644 --- a/libphobos/libdruntime/core/stdc/stdlib.d +++ b/libphobos/libdruntime/core/stdc/stdlib.d @@ -69,8 +69,8 @@ struct div_t /// struct ldiv_t { - int quot, - rem; + c_long quot, + rem; } /// diff --git a/libphobos/libdruntime/core/stdcpp/string.d b/libphobos/libdruntime/core/stdcpp/string.d index dfec1ec..defbd83 100644 --- a/libphobos/libdruntime/core/stdcpp/string.d +++ b/libphobos/libdruntime/core/stdcpp/string.d @@ -343,7 +343,7 @@ extern(D): /// inout(T)* data() inout @safe { return _Get_data()._Myptr; } /// - inout(T)[] as_array() return scope inout nothrow @trusted { return _Get_data()._Myptr[0 .. _Get_data()._Mysize]; } + inout(T)[] as_array() scope return inout nothrow @trusted { return _Get_data()._Myptr[0 .. _Get_data()._Mysize]; } /// ref inout(T) at(size_type i) inout nothrow @trusted { return _Get_data()._Myptr[0 .. _Get_data()._Mysize][i]; } @@ -1920,7 +1920,7 @@ extern(D): /// inout(T)* data() inout @safe { return __get_pointer(); } /// - inout(T)[] as_array() return scope inout nothrow @trusted { return __get_pointer()[0 .. size()]; } + inout(T)[] as_array() scope return inout nothrow @trusted { return __get_pointer()[0 .. size()]; } /// ref inout(T) at(size_type i) inout nothrow @trusted { return __get_pointer()[0 .. size()][i]; } diff --git a/libphobos/libdruntime/core/sys/openbsd/pwd.d b/libphobos/libdruntime/core/sys/openbsd/pwd.d new file mode 100644 index 0000000..f6a35a8 --- /dev/null +++ b/libphobos/libdruntime/core/sys/openbsd/pwd.d @@ -0,0 +1,19 @@ +/** + * D header file for OpenBSD pwd.h. + * + * Copyright: Copyright © 2022, The D Language Foundation + * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>. + * Authors: Brian Callahan + */ +module core.sys.openbsd.pwd; + +version (OpenBSD): +extern (C): +nothrow: +@nogc: + +public import core.sys.posix.pwd; +import core.sys.posix.sys.types : uid_t; + +passwd* getpwnam_shadow(scope const char*); +passwd* getpwuid_shadow(uid_t); diff --git a/libphobos/libdruntime/core/thread/context.d b/libphobos/libdruntime/core/thread/context.d index 1b3c0ca..e477269 100644 --- a/libphobos/libdruntime/core/thread/context.d +++ b/libphobos/libdruntime/core/thread/context.d @@ -6,7 +6,7 @@ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). * (See accompanying file LICENSE) * Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak - * Source: $(DRUNTIMESRC core/thread/package.d) + * Source: $(DRUNTIMESRC core/thread/context.d) */ module core.thread.context; diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d index 47b67f1..5ef2695 100644 --- a/libphobos/libdruntime/rt/dmain2.d +++ b/libphobos/libdruntime/rt/dmain2.d @@ -669,7 +669,7 @@ extern (C) void _d_print_throwable(Throwable t) void sink(in char[] buf) scope nothrow { - fprintf(stderr, "%.*s", cast(int)buf.length, buf.ptr); + fwrite(buf.ptr, char.sizeof, buf.length, stderr); } formatThrowable(t, &sink); } diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 6eb555e..7306c10 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -a74fa63e6775d626850d8ebd854d9803c7ffb97d +99e9c1b7741e0f4e6f2a8c14883c4828d092701d 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/conv.d b/libphobos/src/std/conv.d index 06b3797..8f6c3bf 100644 --- a/libphobos/src/std/conv.d +++ b/libphobos/src/std/conv.d @@ -2850,7 +2850,7 @@ do static if (isNarrowString!Source) { import std.string : representation; - auto s = source.representation; + scope s = source.representation; } else { @@ -2898,7 +2898,7 @@ do } static if (isNarrowString!Source) - source = cast(Source) s; + source = source[$ - s.length .. $]; static if (doCount) { @@ -3105,7 +3105,7 @@ if (isSomeString!Source && !is(Source == enum) && * A $(LREF ConvException) if `source` is empty, if no number could be * parsed, or if an overflow occurred. */ -auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref scope Source source) +auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source) if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) && isFloatingPoint!Target && !is(Target == enum)) { @@ -3115,18 +3115,17 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum static if (isNarrowString!Source) { import std.string : representation; - auto p = source.representation; + scope p = source.representation; } else { alias p = source; } - void advanceSource() @trusted + void advanceSource() { - // p is assigned from source.representation above so the cast is valid static if (isNarrowString!Source) - source = cast(Source) p; + source = source[$ - p.length .. $]; } static immutable real[14] negtab = @@ -5983,3 +5982,14 @@ if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) && } } } + +// Converts an unsigned integer to a compile-time string constant. +package enum toCtString(ulong n) = n.stringof[0 .. $ - "LU".length]; + +// Check that .stringof does what we expect, since it's not guaranteed by the +// language spec. +@safe /*@betterC*/ unittest +{ + assert(toCtString!0 == "0"); + assert(toCtString!123456 == "123456"); +} diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d index 949ad7d..e80f122 100644 --- a/libphobos/src/std/datetime/systime.d +++ b/libphobos/src/std/datetime/systime.d @@ -390,6 +390,33 @@ public: hnsecsToUnixEpoch; } } + else version (Hurd) + { + static if (clockType == ClockType.second) + return unixTimeToStdTime(core.stdc.time.time(null)); + else + { + import core.sys.hurd.time : CLOCK_REALTIME_COARSE; + import core.sys.posix.time : clock_gettime, CLOCK_REALTIME; + static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_COARSE; + else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; + else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; + else static assert(0, "Previous static if is wrong."); + timespec ts = void; + immutable error = clock_gettime(clockArg, &ts); + // Posix clock_gettime called with a valid address and valid clock_id is only + // permitted to fail if the number of seconds does not fit in time_t. If tv_sec + // is long or larger overflow won't happen before 292 billion years A.D. + static if (ts.tv_sec.max < long.max) + { + if (error) + throw new TimeException("Call to clock_gettime() failed"); + } + return convert!("seconds", "hnsecs")(ts.tv_sec) + + ts.tv_nsec / 100 + + hnsecsToUnixEpoch; + } + } else static assert(0, "Unsupported OS"); } else static assert(0, "Unsupported OS"); @@ -693,7 +720,7 @@ public: Returns: The `this` of this `SysTime`. +/ - ref SysTime opAssign()(auto ref const(SysTime) rhs) return scope @safe pure nothrow + ref SysTime opAssign()(auto ref const(SysTime) rhs) scope return @safe pure nothrow { _stdTime = rhs._stdTime; _timezone = rhs._timezone; diff --git a/libphobos/src/std/experimental/logger/core.d b/libphobos/src/std/experimental/logger/core.d index afd98ad..6a28de5 100644 --- a/libphobos/src/std/experimental/logger/core.d +++ b/libphobos/src/std/experimental/logger/core.d @@ -1633,14 +1633,14 @@ private @property Logger defaultSharedLoggerImpl() @trusted import std.concurrency : initOnce; initOnce!stdSharedDefaultLogger({ auto buffer = cast(ubyte[]) _buffer; - return emplace!FileLogger(buffer, stderr, LogLevel.warning); + return emplace!FileLogger(buffer, stderr, LogLevel.info); }()); return stdSharedDefaultLogger; } /** This property sets and gets the default `Logger`. Unless set to another -logger by the user, the default logger's log level is LogLevel.warning. +logger by the user, the default logger's log level is LogLevel.info. Example: ------------- @@ -2008,7 +2008,7 @@ version (StdUnittest) private void testFuncNames(Logger logger) @safe auto oldunspecificLogger = sharedLog; - assert(oldunspecificLogger.logLevel == LogLevel.warning, + assert(oldunspecificLogger.logLevel == LogLevel.info, to!string(oldunspecificLogger.logLevel)); assert(l.logLevel == LogLevel.all); @@ -3064,7 +3064,7 @@ private void trustedStore(T)(ref shared T dst, ref T src) @trusted { auto dl = cast(FileLogger) sharedLog; assert(dl !is null); - assert(dl.logLevel == LogLevel.warning); + assert(dl.logLevel == LogLevel.info); assert(globalLogLevel == LogLevel.all); auto tl = cast(StdForwardLogger) stdThreadLocalLog; diff --git a/libphobos/src/std/experimental/logger/filelogger.d b/libphobos/src/std/experimental/logger/filelogger.d index a0bea77..5112e52 100644 --- a/libphobos/src/std/experimental/logger/filelogger.d +++ b/libphobos/src/std/experimental/logger/filelogger.d @@ -263,7 +263,7 @@ class FileLogger : Logger { auto dl = cast(FileLogger) sharedLog; assert(dl !is null); - assert(dl.logLevel == LogLevel.warning); + assert(dl.logLevel == LogLevel.info); assert(globalLogLevel == LogLevel.all); auto tl = cast(StdForwardLogger) stdThreadLocalLog; diff --git a/libphobos/src/std/experimental/logger/multilogger.d b/libphobos/src/std/experimental/logger/multilogger.d index 90bfb58..9acd23a 100644 --- a/libphobos/src/std/experimental/logger/multilogger.d +++ b/libphobos/src/std/experimental/logger/multilogger.d @@ -191,7 +191,7 @@ class MultiLogger : Logger { auto dl = cast(FileLogger) sharedLog; assert(dl !is null); - assert(dl.logLevel == LogLevel.warning); + assert(dl.logLevel == LogLevel.info); assert(globalLogLevel == LogLevel.all); auto tl = cast(StdForwardLogger) stdThreadLocalLog; diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d index b09b82a..6bc7d4d 100644 --- a/libphobos/src/std/file.d +++ b/libphobos/src/std/file.d @@ -214,7 +214,7 @@ class FileException : Exception string file = __FILE__, size_t line = __LINE__) @safe { - this(name, sysErrorString(errno), file, line, errno); + this(name, generateSysErrorMsg(errno), file, line, errno); } else version (Posix) this(scope const(char)[] name, uint errno = .errno, @@ -3471,7 +3471,7 @@ else version (Posix) string getcwd() @trusted while (true) { auto len = GetModuleFileNameW(null, buffer.ptr, cast(DWORD) buffer.length); - enforce(len, sysErrorString(GetLastError())); + wenforce(len); if (len != buffer.length) return to!(string)(buffer[0 .. len]); buffer.length *= 2; @@ -3574,6 +3574,10 @@ else version (Posix) string getcwd() @trusted // Only Solaris 10 and later return readLink(format("/proc/%d/path/a.out", getpid())); } + else version (Hurd) + { + return readLink("/proc/self/exe"); + } else static assert(0, "thisExePath is not supported on this platform"); } diff --git a/libphobos/src/std/format/internal/write.d b/libphobos/src/std/format/internal/write.d index 68b9e4d..f1d6964 100644 --- a/libphobos/src/std/format/internal/write.d +++ b/libphobos/src/std/format/internal/write.d @@ -2000,8 +2000,7 @@ template hasToString(T, Char) enum hasToString = HasToStringResult.none; } else static if (is(typeof( - { - T val = void; + (T val) { const FormatSpec!Char f; static struct S {void put(scope Char s){}} S s; @@ -2015,8 +2014,7 @@ template hasToString(T, Char) enum hasToString = HasToStringResult.customPutWriterFormatSpec; } else static if (is(typeof( - { - T val = void; + (T val) { static struct S {void put(scope Char s){}} S s; val.toString(s); @@ -2026,36 +2024,36 @@ template hasToString(T, Char) { enum hasToString = HasToStringResult.customPutWriter; } - else static if (is(typeof({ T val = void; FormatSpec!Char f; val.toString((scope const(char)[] s){}, f); }))) + else static if (is(typeof((T val) { FormatSpec!Char f; val.toString((scope const(char)[] s){}, f); }))) { enum hasToString = HasToStringResult.constCharSinkFormatSpec; } - else static if (is(typeof({ T val = void; val.toString((scope const(char)[] s){}, "%s"); }))) + else static if (is(typeof((T val) { val.toString((scope const(char)[] s){}, "%s"); }))) { enum hasToString = HasToStringResult.constCharSinkFormatString; } - else static if (is(typeof({ T val = void; val.toString((scope const(char)[] s){}); }))) + else static if (is(typeof((T val) { val.toString((scope const(char)[] s){}); }))) { enum hasToString = HasToStringResult.constCharSink; } else static if (hasPreviewIn && - is(typeof({ T val = void; FormatSpec!Char f; val.toString((in char[] s){}, f); }))) + is(typeof((T val) { FormatSpec!Char f; val.toString((in char[] s){}, f); }))) { enum hasToString = HasToStringResult.inCharSinkFormatSpec; } else static if (hasPreviewIn && - is(typeof({ T val = void; val.toString((in char[] s){}, "%s"); }))) + is(typeof((T val) { val.toString((in char[] s){}, "%s"); }))) { enum hasToString = HasToStringResult.inCharSinkFormatString; } else static if (hasPreviewIn && - is(typeof({ T val = void; val.toString((in char[] s){}); }))) + is(typeof((T val) { val.toString((in char[] s){}); }))) { enum hasToString = HasToStringResult.inCharSink; } - else static if (is(typeof({ T val = void; return val.toString(); }()) S) && isSomeString!S) + else static if (is(ReturnType!((T val) { return val.toString(); }) S) && isSomeString!S) { enum hasToString = HasToStringResult.hasSomeToString; } @@ -2171,6 +2169,133 @@ template hasToString(T, Char) } } +// const toString methods +@safe unittest +{ + import std.range.primitives : isOutputRange; + + static struct A + { + void toString(Writer)(ref Writer w) const + if (isOutputRange!(Writer, string)) + {} + } + static struct B + { + void toString(scope void delegate(scope const(char)[]) sink, scope FormatSpec!char fmt) const {} + } + static struct C + { + void toString(scope void delegate(scope const(char)[]) sink, string fmt) const {} + } + static struct D + { + void toString(scope void delegate(scope const(char)[]) sink) const {} + } + static struct E + { + string toString() const {return "";} + } + static struct F + { + void toString(Writer)(ref Writer w, scope const ref FormatSpec!char fmt) const + if (isOutputRange!(Writer, string)) + {} + } + static struct G + { + string toString() const {return "";} + void toString(Writer)(ref Writer w) const if (isOutputRange!(Writer, string)) {} + } + static struct H + { + string toString() const {return "";} + void toString(Writer)(ref Writer w, scope const ref FormatSpec!char fmt) const + if (isOutputRange!(Writer, string)) + {} + } + static struct I + { + void toString(Writer)(ref Writer w) const if (isOutputRange!(Writer, string)) {} + void toString(Writer)(ref Writer w, scope const ref FormatSpec!char fmt) const + if (isOutputRange!(Writer, string)) + {} + } + static struct J + { + string toString() const {return "";} + void toString(Writer)(ref Writer w, scope ref FormatSpec!char fmt) const + if (isOutputRange!(Writer, string)) + {} + } + static struct K + { + void toString(Writer)(Writer w, scope const ref FormatSpec!char fmt) const + if (isOutputRange!(Writer, string)) + {} + } + static struct L + { + void toString(Writer)(ref Writer w, scope const FormatSpec!char fmt) const + if (isOutputRange!(Writer, string)) + {} + } + static struct M + { + void toString(scope void delegate(in char[]) sink, in FormatSpec!char fmt) const {} + } + static struct N + { + void toString(scope void delegate(in char[]) sink, string fmt) const {} + } + static struct O + { + void toString(scope void delegate(in char[]) sink) const {} + } + + with(HasToStringResult) + { + static assert(hasToString!(A, char) == customPutWriter); + static assert(hasToString!(B, char) == constCharSinkFormatSpec); + static assert(hasToString!(C, char) == constCharSinkFormatString); + static assert(hasToString!(D, char) == constCharSink); + static assert(hasToString!(E, char) == hasSomeToString); + static assert(hasToString!(F, char) == customPutWriterFormatSpec); + static assert(hasToString!(G, char) == customPutWriter); + static assert(hasToString!(H, char) == customPutWriterFormatSpec); + static assert(hasToString!(I, char) == customPutWriterFormatSpec); + static assert(hasToString!(J, char) == hasSomeToString); + static assert(hasToString!(K, char) == constCharSinkFormatSpec); + static assert(hasToString!(L, char) == none); + static if (hasPreviewIn) + { + static assert(hasToString!(M, char) == inCharSinkFormatSpec); + static assert(hasToString!(N, char) == inCharSinkFormatString); + static assert(hasToString!(O, char) == inCharSink); + } + + // https://issues.dlang.org/show_bug.cgi?id=22873 + static assert(hasToString!(inout(A), char) == customPutWriter); + static assert(hasToString!(inout(B), char) == constCharSinkFormatSpec); + static assert(hasToString!(inout(C), char) == constCharSinkFormatString); + static assert(hasToString!(inout(D), char) == constCharSink); + static assert(hasToString!(inout(E), char) == hasSomeToString); + static assert(hasToString!(inout(F), char) == customPutWriterFormatSpec); + static assert(hasToString!(inout(G), char) == customPutWriter); + static assert(hasToString!(inout(H), char) == customPutWriterFormatSpec); + static assert(hasToString!(inout(I), char) == customPutWriterFormatSpec); + static assert(hasToString!(inout(J), char) == hasSomeToString); + static assert(hasToString!(inout(K), char) == constCharSinkFormatSpec); + static assert(hasToString!(inout(L), char) == none); + static if (hasPreviewIn) + { + static assert(hasToString!(inout(M), char) == inCharSinkFormatSpec); + static assert(hasToString!(inout(N), char) == inCharSinkFormatString); + static assert(hasToString!(inout(O), char) == inCharSink); + } + } +} + // object formatting with toString private void formatObject(Writer, T, Char)(ref Writer w, ref T val, scope const ref FormatSpec!Char f) if (hasToString!(T, Char)) diff --git a/libphobos/src/std/format/package.d b/libphobos/src/std/format/package.d index 6c9e9ae..76d68f6 100644 --- a/libphobos/src/std/format/package.d +++ b/libphobos/src/std/format/package.d @@ -1589,7 +1589,7 @@ char[] sformat(alias fmt, Args...)(char[] buf, Args args) if (isSomeString!(typeof(fmt))) { alias e = checkFormatException!(fmt, Args); - static assert(!e, e.msg); + static assert(!e, e); return .sformat(buf, fmt, args); } diff --git a/libphobos/src/std/format/read.d b/libphobos/src/std/format/read.d index b3d8d1f..144fa8c 100644 --- a/libphobos/src/std/format/read.d +++ b/libphobos/src/std/format/read.d @@ -305,7 +305,7 @@ if (isSomeString!(typeof(fmt))) import std.format : checkFormatException; alias e = checkFormatException!(fmt, Args); - static assert(!e, e.msg); + static assert(!e, e); return .formattedRead(r, fmt, args); } diff --git a/libphobos/src/std/format/write.d b/libphobos/src/std/format/write.d index e67d95c..cbab512 100644 --- a/libphobos/src/std/format/write.d +++ b/libphobos/src/std/format/write.d @@ -677,7 +677,7 @@ if (isSomeString!(typeof(fmt))) import std.format : checkFormatException; alias e = checkFormatException!(fmt, Args); - static assert(!e, e.msg); + static assert(!e, e); return .formattedWrite(w, fmt, args); } diff --git a/libphobos/src/std/functional.d b/libphobos/src/std/functional.d index 90b0f91..70aaee3 100644 --- a/libphobos/src/std/functional.d +++ b/libphobos/src/std/functional.d @@ -65,6 +65,7 @@ module std.functional; import std.meta : AliasSeq, Reverse; import std.traits : isCallable, Parameters; +import std.conv : toCtString; import std.internal.attributes : betterC; @@ -1848,17 +1849,6 @@ if (isCallable!(F)) } } -// Converts an unsigned integer to a compile-time string constant. -private enum toCtString(ulong n) = n.stringof[0 .. $ - "LU".length]; - -// Check that .stringof does what we expect, since it's not guaranteed by the -// language spec. -@safe unittest -{ - assert(toCtString!0 == "0"); - assert(toCtString!123456 == "123456"); -} - /** * Passes the fields of a struct as arguments to a function. * diff --git a/libphobos/src/std/json.d b/libphobos/src/std/json.d index 89def0f..c6e746a 100644 --- a/libphobos/src/std/json.d +++ b/libphobos/src/std/json.d @@ -321,7 +321,7 @@ struct JSONValue (*a)[0] = "world"; // segmentation fault --- */ - @property ref inout(JSONValue[]) array() return scope inout pure @system + @property ref inout(JSONValue[]) array() scope return inout pure @system { enforce!JSONException(type == JSONType.array, "JSONValue is not an array"); diff --git a/libphobos/src/std/outbuffer.d b/libphobos/src/std/outbuffer.d index 9590238..c434481 100644 --- a/libphobos/src/std/outbuffer.d +++ b/libphobos/src/std/outbuffer.d @@ -331,7 +331,7 @@ class OutBuffer import std.format : checkFormatException; alias e = checkFormatException!(fmt, A); - static assert(!e, e.msg); + static assert(!e, e); return this.writef(fmt, args); } @@ -377,7 +377,7 @@ class OutBuffer import std.format : checkFormatException; alias e = checkFormatException!(fmt, A); - static assert(!e, e.msg); + static assert(!e, e); return this.writefln(fmt, args); } diff --git a/libphobos/src/std/parallelism.d b/libphobos/src/std/parallelism.d index 971cfa0..2c97638 100644 --- a/libphobos/src/std/parallelism.d +++ b/libphobos/src/std/parallelism.d @@ -1039,6 +1039,11 @@ uint totalCPUsImpl() @nogc nothrow @trusted import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf; return cast(uint) sysconf(_SC_NPROCESSORS_ONLN); } + else version (Hurd) + { + import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf; + return cast(uint) sysconf(_SC_NPROCESSORS_ONLN); + } else { static assert(0, "Don't know how to get N CPUs on this OS."); diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d index 2c68f36..28bfb04 100644 --- a/libphobos/src/std/process.d +++ b/libphobos/src/std/process.d @@ -299,10 +299,9 @@ static: } else version (Windows) { - import std.exception : enforce; - enforce( + import std.windows.syserror : wenforce; + wenforce( SetEnvironmentVariableW(name.tempCStringW(), value.tempCStringW()), - sysErrorString(GetLastError()) ); return value; } @@ -1330,7 +1329,7 @@ private Pid spawnProcessWin(scope const(char)[] commandLine, { throw new StdioException( "Failed to make "~which~" stream inheritable by child process (" - ~sysErrorString(GetLastError()) ~ ')', + ~generateSysErrorMsg() ~ ')', 0); } } @@ -2775,7 +2774,7 @@ Pipe pipe() @trusted //TODO: @safe if (!CreatePipe(&readHandle, &writeHandle, null, 0)) { throw new StdioException( - "Error creating pipe (" ~ sysErrorString(GetLastError()) ~ ')', + "Error creating pipe (" ~ generateSysErrorMsg() ~ ')', 0); } @@ -3475,7 +3474,7 @@ class ProcessException : Exception string file = __FILE__, size_t line = __LINE__) { - auto lastMsg = sysErrorString(GetLastError()); + auto lastMsg = generateSysErrorMsg(); auto msg = customMsg.empty ? lastMsg : customMsg ~ " (" ~ lastMsg ~ ')'; return new ProcessException(msg, file, line); diff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d index cd23232..915159f 100644 --- a/libphobos/src/std/socket.d +++ b/libphobos/src/std/socket.d @@ -169,7 +169,7 @@ string formatSocketError(int err) @trusted else version (Windows) { - return sysErrorString(err); + return generateSysErrorMsg(err); } else return "Socket error " ~ to!string(err); @@ -842,7 +842,7 @@ private string formatGaiError(int err) @trusted { version (Windows) { - return sysErrorString(err); + return generateSysErrorMsg(err); } else { diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d index bc2d3fe..1bde73d 100644 --- a/libphobos/src/std/stdio.d +++ b/libphobos/src/std/stdio.d @@ -1458,6 +1458,7 @@ Throws: `Exception` if the file is not opened. { import core.sys.windows.winbase : OVERLAPPED; import core.sys.windows.winnt : BOOL, ULARGE_INTEGER; + import std.windows.syserror : wenforce; private BOOL lockImpl(alias F, Flags...)(ulong start, ulong length, Flags flags) @@ -1474,15 +1475,6 @@ Throws: `Exception` if the file is not opened. return F(windowsHandle, flags, 0, liLength.LowPart, liLength.HighPart, &overlapped); } - - private static T wenforce(T)(T cond, lazy string str) - { - import core.sys.windows.winbase : GetLastError; - import std.windows.syserror : sysErrorString; - - if (cond) return cond; - throw new Exception(str ~ ": " ~ sysErrorString(GetLastError())); - } } version (Posix) { @@ -1783,7 +1775,7 @@ Throws: `Exception` if the file is not opened. import std.format : checkFormatException; alias e = checkFormatException!(fmt, A); - static assert(!e, e.msg); + static assert(!e, e); return this.writef(fmt, args); } @@ -1802,7 +1794,7 @@ Throws: `Exception` if the file is not opened. import std.format : checkFormatException; alias e = checkFormatException!(fmt, A); - static assert(!e, e.msg); + static assert(!e, e); return this.writefln(fmt, args); } @@ -2151,7 +2143,7 @@ $(CONSOLE import std.format : checkFormatException; alias e = checkFormatException!(format, Data); - static assert(!e, e.msg); + static assert(!e, e); return this.readf(format, data); } @@ -4388,7 +4380,7 @@ if (isSomeString!(typeof(fmt))) import std.format : checkFormatException; alias e = checkFormatException!(fmt, A); - static assert(!e, e.msg); + static assert(!e, e); return .writef(fmt, args); } @@ -4429,7 +4421,7 @@ if (isSomeString!(typeof(fmt))) import std.format : checkFormatException; alias e = checkFormatException!(fmt, A); - static assert(!e, e.msg); + static assert(!e, e); return .writefln(fmt, args); } @@ -4510,7 +4502,7 @@ if (isSomeString!(typeof(format))) import std.format : checkFormatException; alias e = checkFormatException!(format, A); - static assert(!e, e.msg); + static assert(!e, e); return .readf(format, args); } diff --git a/libphobos/src/std/sumtype.d b/libphobos/src/std/sumtype.d index f4f4216..dac531f 100644 --- a/libphobos/src/std/sumtype.d +++ b/libphobos/src/std/sumtype.d @@ -237,21 +237,11 @@ import std.traits : ConstOf, ImmutableOf, InoutOf, TemplateArgsOf; import std.traits : CommonType, DeducedParameterType; import std.typecons : ReplaceTypeUnless; import std.typecons : Flag; +import std.conv : toCtString; /// Placeholder used to refer to the enclosing [SumType]. struct This {} -// Converts an unsigned integer to a compile-time string constant. -private enum toCtString(ulong n) = n.stringof[0 .. $ - "LU".length]; - -// Check that .stringof does what we expect, since it's not guaranteed by the -// language spec. -@safe unittest -{ - assert(toCtString!0 == "0"); - assert(toCtString!123456 == "123456"); -} - // True if a variable of type T can appear on the lhs of an assignment private enum isAssignableTo(T) = isAssignable!T || (!isCopyable!T && isRvalueAssignable!T); diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index ea8f8bd..1ee7faa 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -3109,6 +3109,64 @@ struct Nullable(T) { return isNull ? fallback : _value.payload; } + + /// $(MREF_ALTTEXT Range interface, std, range, primitives) functions. + alias empty = isNull; + + /// ditto + alias popFront = nullify; + + /// ditto + alias popBack = nullify; + + /// ditto + @property ref inout(T) front() inout @safe pure nothrow + { + return get(); + } + + /// ditto + alias back = front; + + /// ditto + @property inout(typeof(this)) save() inout + { + return this; + } + + /// ditto + inout(typeof(this)) opIndex() inout + { + return this; + } + + /// ditto + inout(typeof(this)) opIndex(size_t[2] dim) inout + in (dim[0] <= length && dim[1] <= length && dim[1] >= dim[0]) + { + return (dim[0] == 0 && dim[1] == 1) ? this : this.init; + } + /// ditto + size_t[2] opSlice(size_t dim : 0)(size_t from, size_t to) const + { + return [from, to]; + } + + /// ditto + @property size_t length() const @safe pure nothrow + { + return !empty; + } + + /// ditto + alias opDollar(size_t dim : 0) = length; + + /// ditto + ref inout(T) opIndex(size_t index) inout @safe pure nothrow + in (index < length) + { + return get(); + } } /// ditto @@ -3162,6 +3220,23 @@ auto nullable(T)(T t) assert(a.isNull); assertThrown!Throwable(a.get); } +/// +@safe unittest +{ + import std.algorithm.iteration : each, joiner; + Nullable!int a = 42; + Nullable!int b; + // Add each value to an array + int[] arr; + a.each!((n) => arr ~= n); + assert(arr == [42]); + b.each!((n) => arr ~= n); + assert(arr == [42]); + // Take first value from an array of Nullables + Nullable!int[] c = new Nullable!int[](10); + c[7] = Nullable!int(42); + assert(c.joiner.front == 42); +} @safe unittest { auto k = Nullable!int(74); @@ -3638,6 +3713,42 @@ auto nullable(T)(T t) a = b = c = nullable(5); } +// https://issues.dlang.org/show_bug.cgi?id=18374 +@safe pure nothrow unittest +{ + import std.algorithm.comparison : equal; + import std.range : only, takeNone; + import std.range.primitives : hasAssignableElements, hasLength, + hasLvalueElements, hasSlicing, hasSwappableElements, + isRandomAccessRange; + Nullable!int a = 42; + assert(!a.empty); + assert(a.front == 42); + assert(a.back == 42); + assert(a[0] == 42); + assert(a.equal(only(42))); + assert(a[0 .. $].equal(only(42))); + a[0] = 43; + assert(a.equal(only(43))); + --a[0]; + assert(a.equal(only(42))); + Nullable!int b; + assert(b.empty); + assert(b.equal(takeNone(b))); + Nullable!int c = a.save(); + assert(!c.empty); + c.popFront(); + assert(!a.empty); + assert(c.empty); + + assert(isRandomAccessRange!(Nullable!int)); + assert(hasLength!(Nullable!int)); + assert(hasSlicing!(Nullable!int)); + assert(hasAssignableElements!(Nullable!int)); + assert(hasSwappableElements!(Nullable!int)); + assert(hasLvalueElements!(Nullable!int)); +} + /** Just like `Nullable!T`, except that the null state is defined as a particular value. For example, $(D Nullable!(uint, uint.max)) is an @@ -8793,19 +8904,6 @@ private: enum isBaseEnumType(T) = is(E == T); alias Base = OriginalType!E; Base mValue; - static struct Negation - { - @safe @nogc pure nothrow: - private: - Base mValue; - - // Prevent non-copy construction outside the module. - @disable this(); - this(Base value) - { - mValue = value; - } - } public: this(E flag) @@ -8830,10 +8928,10 @@ public: return mValue; } - Negation opUnary(string op)() const + auto opUnary(string op)() const if (op == "~") { - return Negation(~mValue); + return BitFlags(cast(E) cast(Base) ~mValue); } auto ref opAssign(T...)(T flags) @@ -8877,12 +8975,6 @@ public: return this; } - auto ref opOpAssign(string op: "&")(Negation negatedFlags) - { - mValue &= negatedFlags.mValue; - return this; - } - auto opBinary(string op)(BitFlags flags) const if (op == "|" || op == "&") { @@ -8899,13 +8991,6 @@ public: return result; } - auto opBinary(string op: "&")(Negation negatedFlags) const - { - BitFlags result = this; - result.opOpAssign!op(negatedFlags); - return result; - } - auto opBinaryRight(string op)(E flag) const if (op == "|" || op == "&") { @@ -9104,6 +9189,34 @@ public: assert(flags.A && !flags.B && !flags.C); } +// Negation of BitFlags should work with any base type. +// Double-negation of BitFlags should work. +@safe @nogc pure nothrow unittest +{ + static foreach (alias Base; AliasSeq!( + byte, + ubyte, + short, + ushort, + int, + uint, + long, + ulong, + )) + {{ + enum Enum : Base + { + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, + } + + auto flags = BitFlags!Enum(Enum.A); + + assert(flags == ~~flags); + }} +} + private enum false_(T) = false; // ReplaceType diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d index eeeda72..98735ac 100644 --- a/libphobos/src/std/uni/package.d +++ b/libphobos/src/std/uni/package.d @@ -9834,25 +9834,29 @@ dchar toLower(dchar c) Returns: An array with the same element type as `s`. +/ -ElementEncodingType!S[] toLower(S)(S s) -if (isSomeString!S || (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S))) +ElementEncodingType!S[] toLower(S)(return scope S s) @trusted +if (isSomeString!S) { static import std.ascii; + return toCase!(LowerTriple, std.ascii.toLower)(s); +} - static if (isSomeString!S) - return () @trusted { return toCase!(LowerTriple, std.ascii.toLower)(s); } (); - else - return toCase!(LowerTriple, std.ascii.toLower)(s); +/// ditto +ElementEncodingType!S[] toLower(S)(S s) +if (!isSomeString!S && (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S))) +{ + static import std.ascii; + return toCase!(LowerTriple, std.ascii.toLower)(s); } // overloads for the most common cases to reduce compile time @safe pure /*TODO nothrow*/ { - string toLower(string s) + string toLower(return scope string s) { return toLower!string(s); } - wstring toLower(wstring s) + wstring toLower(return scope wstring s) { return toLower!wstring(s); } - dstring toLower(dstring s) + dstring toLower(return scope dstring s) { return toLower!dstring(s); } @safe unittest @@ -10038,25 +10042,29 @@ dchar toUpper(dchar c) Returns: An new array with the same element type as `s`. +/ -ElementEncodingType!S[] toUpper(S)(S s) -if (isSomeString!S || (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S))) +ElementEncodingType!S[] toUpper(S)(return scope S s) @trusted +if (isSomeString!S) { static import std.ascii; + return toCase!(UpperTriple, std.ascii.toUpper)(s); +} - static if (isSomeString!S) - return () @trusted { return toCase!(UpperTriple, std.ascii.toUpper)(s); } (); - else - return toCase!(UpperTriple, std.ascii.toUpper)(s); +/// ditto +ElementEncodingType!S[] toUpper(S)(S s) +if (!isSomeString!S && (isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S))) +{ + static import std.ascii; + return toCase!(UpperTriple, std.ascii.toUpper)(s); } // overloads for the most common cases to reduce compile time @safe pure /*TODO nothrow*/ { - string toUpper(string s) + string toUpper(return scope string s) { return toUpper!string(s); } - wstring toUpper(wstring s) + wstring toUpper(return scope wstring s) { return toUpper!wstring(s); } - dstring toUpper(dstring s) + dstring toUpper(return scope dstring s) { return toUpper!dstring(s); } @safe unittest diff --git a/libphobos/src/std/windows/charset.d b/libphobos/src/std/windows/charset.d index 69626b5..ce33616 100644 --- a/libphobos/src/std/windows/charset.d +++ b/libphobos/src/std/windows/charset.d @@ -76,12 +76,7 @@ const(char)* toMBSz(scope const(char)[] s, uint codePage = 0) to!int(result.length), null, null); } - if (!readLen || readLen != result.length) - { - throw new Exception("Couldn't convert string: " ~ - sysErrorString(GetLastError())); - } - + wenforce(readLen && readLen == result.length, "Couldn't convert string"); return result.ptr; } } @@ -107,16 +102,10 @@ string fromMBSz(return scope immutable(char)* s, int codePage = 0) to!int(result.length)); } - if (!readLen || readLen != result.length) - { - throw new Exception("Couldn't convert string: " ~ - sysErrorString(GetLastError())); - } + wenforce(readLen && readLen == result.length, "Couldn't convert string"); return result[0 .. result.length-1].to!string; // omit trailing null } } return s[0 .. c-s]; // string is ASCII, no conversion necessary } - - diff --git a/libphobos/src/std/windows/syserror.d b/libphobos/src/std/windows/syserror.d index 94f8ee5..3d8c5e7 100644 --- a/libphobos/src/std/windows/syserror.d +++ b/libphobos/src/std/windows/syserror.d @@ -43,7 +43,7 @@ version (StdDdoc) { private alias DWORD = int; final @property DWORD code(); /// `GetLastError`'s return value. - this(DWORD code, string str=null, string file = null, size_t line = 0) @trusted; + this(DWORD code, string str=null, string file = null, size_t line = 0) nothrow @trusted; } /++ @@ -66,9 +66,9 @@ else: version (Windows): import core.sys.windows.winbase, core.sys.windows.winnt; -import std.array : appender; -import std.conv : to; -import std.format.write : formattedWrite; +import std.array : appender, Appender; +import std.conv : to, toTextRange, text; +import std.exception; import std.windows.charset; string sysErrorString( @@ -79,16 +79,25 @@ string sysErrorString( { auto buf = appender!string(); - if (!putSysError(errCode, buf, MAKELANGID(langId, subLangId))) - { - throw new Exception( - "failed getting error string for WinAPI error code: " ~ - sysErrorString(GetLastError())); - } + wenforce( + // Ignore unlikely UTF decoding errors, always report the actual error (`errCode`) + putSysError(errCode, buf, MAKELANGID(langId, subLangId)).ifThrown(false), + text("Could not fetch error string for WinAPI code ", errCode) + ); return buf.data; } +@safe unittest +{ + import std.algorithm.searching; + + assert(sysErrorString(ERROR_PATH_NOT_FOUND) !is null); + + const msg = collectExceptionMsg!WindowsException(sysErrorString(DWORD.max)); + assert(msg.startsWith(`Could not fetch error string for WinAPI code 4294967295: `)); +} + bool putSysError(Writer)(DWORD code, Writer w, /*WORD*/int langId = 0) { wchar *lpMsgBuf = null; @@ -114,7 +123,6 @@ bool putSysError(Writer)(DWORD code, Writer w, /*WORD*/int langId = 0) return false; } - class WindowsException : Exception { import core.sys.windows.windef : DWORD; @@ -122,11 +130,11 @@ class WindowsException : Exception final @property DWORD code() { return _code; } /// `GetLastError`'s return value. private DWORD _code; - this(DWORD code, string str=null, string file = null, size_t line = 0) @trusted + this(DWORD code, string str=null, string file = null, size_t line = 0) nothrow @trusted { _code = code; - auto buf = appender!string(); + auto buf = appender!(char[]); if (str != null) { @@ -135,18 +143,43 @@ class WindowsException : Exception buf.put(": "); } - if (code) + if (code && writeErrorMessage(code, buf)) { - auto success = putSysError(code, buf); - formattedWrite(buf, success ? " (error %d)" : "Error %d", code); + buf.put(" (error "); + toTextRange(code, buf); + buf.put(')'); } - super(buf.data, file, line); + super(cast(immutable) buf.data, file, line); } } +/// Writes the error string associated to `code` into `buf`. +/// Writes `Error <code>` when the error message lookup fails +private bool writeErrorMessage(DWORD code, ref Appender!(char[]) buf) nothrow +{ + bool success; + try + { + // Reset the buffer to undo partial changes + const len = buf[].length; + scope (failure) buf.shrinkTo(len); -T wenforce(T, S)(T value, lazy S msg = null, + success = putSysError(code, buf); + } + catch (Exception) {} + + // Write the error code instead if we couldn't find the string + if (!success) + { + buf.put("Error "); + toTextRange(code, buf); + } + + return success; +} + +T wenforce(T, S = string)(T value, lazy S msg = null, string file = __FILE__, size_t line = __LINE__) if (isSomeString!S) { @@ -177,11 +210,9 @@ T wenforce(T)(T condition, const(char)[] name, const(wchar)* namez, string file throw new WindowsException(GetLastError(), names, file, line); } -version (Windows) @system unittest { import std.algorithm.searching : startsWith, endsWith; - import std.exception; import std.string; auto e = collectException!WindowsException( @@ -199,3 +230,29 @@ version (Windows) e = new WindowsException(0, "Test"); assert(e.msg == "Test"); } + +@safe nothrow unittest +{ + import std.algorithm.searching : endsWith; + + auto e = new WindowsException(ERROR_FILE_NOT_FOUND); + assert(e.msg.endsWith("(error 2)")); + + e = new WindowsException(DWORD.max); + assert(e.msg == "Error 4294967295"); +} + +/// Tries to translate an error code from the Windows API to the corresponding +/// error message. Returns `Error <code>` on failure +package (std) string generateSysErrorMsg(DWORD errCode = GetLastError()) nothrow @trusted +{ + auto buf = appender!(char[]); + cast(void) writeErrorMessage(errCode, buf); + return cast(immutable) buf[]; +} + +nothrow @safe unittest +{ + assert(generateSysErrorMsg(ERROR_PATH_NOT_FOUND) !is null); + assert(generateSysErrorMsg(DWORD.max) == "Error 4294967295"); +} diff --git a/libphobos/testsuite/libphobos.exceptions/message_with_null.d b/libphobos/testsuite/libphobos.exceptions/message_with_null.d new file mode 100644 index 0000000..64092f0 --- /dev/null +++ b/libphobos/testsuite/libphobos.exceptions/message_with_null.d @@ -0,0 +1,8 @@ +// { dg-shouldfail " world!" } +// { dg-output "object.Exception@.*: hello.*world!" } +module message_with_null; + +void main() +{ + throw new Exception("hello\0 world!"); +} |