From patchwork Fri Dec 10 04:28:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 48747 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E03013858022 for ; Fri, 10 Dec 2021 04:31:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E03013858022 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1639110697; bh=HhWe2CYltjZCDWkhpaKFms8hf5myoJ2bG72mS2+i+b0=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=qeyp94xm9KBsBGeRvynuXDCJS9aZO+ZVs2y5BT7sha3kvuJN0RAkQ+REtL8FhxxgN BZSc5dqaWIBpz/4PSjKPIo2PS/acavUkfiJQ67C8vvLL1j6M/AGRUYxTe0qo+ND36g bQg3xpEvixp67XjZJqr6l+HevhPOb/cHC1Xsw/Zo= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [80.241.56.172]) by sourceware.org (Postfix) with ESMTPS id F33DA3858036 for ; Fri, 10 Dec 2021 04:28:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F33DA3858036 Received: from smtp202.mailbox.org (smtp202.mailbox.org [IPv6:2001:67c:2050:105:465:1:4:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 4J9Hw32czzzQjmg; Fri, 10 Dec 2021 05:28:35 +0100 (CET) X-Virus-Scanned: amavisd-new at heinlein-support.de To: gcc-patches@gcc.gnu.org Subject: [committed 2/3] d: Update for new front-end interface. Date: Fri, 10 Dec 2021 05:28:25 +0100 Message-Id: <20211210042825.532141-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch updates the gdc codegen interface for the new front-end. Bootstrapped and regression tested on x86_64-linux-gnu, committed to mainline. Regards, Iain. --- gcc/d/ChangeLog: * Make-lang.in (D_FRONTEND_OBJS): Add d/root-optional.o. * d-attribs.cc (build_attributes): Update for new front-end interface. * d-codegen.cc (d_build_call): Likewise. * d-compiler.cc (Compiler::paintAsType): Likewise. * d-lang.cc (d_handle_option): Remove OPT_fpreview_intpromote, add handling of OPT_frevert_intpromote. * d-port.cc (Port::valcpy): Assert buffer is aligned. * d-target.cc (Target::isVectorOpSupported): Update for new front-end interface. * decl.cc (layout_class_initializer): Likewise. * expr.cc (lvalue_p): Likewise. (binop_assignment): Likewise. (ExprVisitor::visit): Likewise. (ExprVisitor::visit (AssignExp *)): Remove generation of _d_arrayctor and _d_arraysetctor library helpers. (ExprVisitor::visit (VarExp *)): Support __traits(initSymbol). * intrinsics.cc (expand_intrinsic_rotate): Update for new front-end interface. * lang.opt (fpreview=intpromote): Remove. (frevert=intpromote): New. * runtime.def (ARRAYCTOR): Remove. (ARRAYSETCTOR): Remove. * toir.cc (IRVisitor::visit): Update for new front-end interface. * types.cc (layout_aggregate_members): Likewise. --- gcc/d/Make-lang.in | 1 + gcc/d/d-attribs.cc | 6 +- gcc/d/d-codegen.cc | 6 +- gcc/d/d-compiler.cc | 4 +- gcc/d/d-lang.cc | 11 +- gcc/d/d-port.cc | 2 + gcc/d/d-target.cc | 30 +- gcc/d/decl.cc | 2 +- gcc/d/expr.cc | 259 +-- gcc/d/intrinsics.cc | 2 +- gcc/d/lang.opt | 8 +- gcc/d/runtime.def | 7 - gcc/d/toir.cc | 3 +- gcc/d/types.cc | 2 +- 14 files changed, 178 insertions(+), 165 deletions(-) diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in index d7f714760f7..00169a743a1 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -162,6 +162,7 @@ D_FRONTEND_OBJS = \ d/root-filename.o \ d/root-hash.o \ d/root-longdouble.o \ + d/root-optional.o \ d/root-port.o \ d/root-region.o \ d/root-rmem.o \ diff --git a/gcc/d/d-attribs.cc b/gcc/d/d-attribs.cc index 04b9791ab1b..5c9f569d1c4 100644 --- a/gcc/d/d-attribs.cc +++ b/gcc/d/d-attribs.cc @@ -337,10 +337,10 @@ build_attributes (Expressions *eattrs) continue; /* Get the result of the attribute if it hasn't already been folded. */ - if (attr->op == TOKcall) + if (attr->op == EXP::call) attr = attr->ctfeInterpret (); - if (attr->op != TOKstructliteral) + if (attr->op != EXP::structLiteral) { warning_at (make_location_t (attr->loc), OPT_Wattributes, "%qE attribute has no effect", @@ -353,7 +353,7 @@ build_attributes (Expressions *eattrs) Expressions *elems = attr->isStructLiteralExp ()->elements; Expression *e0 = (*elems)[0]; - if (e0->op != TOKstring) + if (e0->op != EXP::string_) { warning_at (make_location_t (attr->loc), OPT_Wattributes, "unknown attribute %qs", e0->toChars()); diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index c082ac5ab80..39c3c6ce987 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -2154,9 +2154,9 @@ d_build_call (TypeFunction *tf, tree callable, tree object, { Lagain: Expression *arg = (*arguments)[i]; - gcc_assert (arg->op != TOKtuple); + gcc_assert (arg->op != EXP::tuple); - if (arg->op == TOKcomma) + if (arg->op == EXP::comma) { CommaExp *ce = arg->isCommaExp (); tree tce = build_expr (ce->e1); @@ -2200,7 +2200,7 @@ d_build_call (TypeFunction *tf, tree callable, tree object, /* Nested structs also have ADDRESSABLE set, but if the type has neither a copy constructor nor a destructor available, then we need to take care of copying its value before passing it. */ - if (arg->op == TOKstructliteral || (!sd->postblit && !sd->dtor)) + if (arg->op == EXP::structLiteral || (!sd->postblit && !sd->dtor)) targ = force_target_expr (targ); targ = convert (build_reference_type (TREE_TYPE (targ)), diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc index 3df40073ac5..c1e78c0a5de 100644 --- a/gcc/d/d-compiler.cc +++ b/gcc/d/d-compiler.cc @@ -50,7 +50,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type) cst = build_integer_cst (expr->toInteger (), build_ctype (expr->type)); else if (expr->type->isfloating ()) cst = build_float_cst (expr->toReal (), expr->type); - else if (expr->op == TOKarrayliteral) + else if (expr->op == EXP::arrayLiteral) { /* Build array as VECTOR_CST, assumes EXPR is constant. */ Expressions *elements = expr->isArrayLiteralExp ()->elements; @@ -99,7 +99,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type) cst = native_interpret_expr (vectype, buffer, len); Expression *e = d_eval_constant_expression (expr->loc, cst); - gcc_assert (e != NULL && e->op == TOKvector); + gcc_assert (e != NULL && e->op == EXP::vector); return e->isVectorExp ()->e1; } diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index 576eefcc01f..2c5d206a95f 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -620,10 +620,6 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, global.params.inclusiveInContracts = value; break; - case OPT_fpreview_intpromote: - global.params.fix16997 = value; - break; - case OPT_fpreview_nosharedaccess: global.params.noSharedAccess = value; break; @@ -642,8 +638,9 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, case OPT_frevert_all: global.params.useDIP25 = FeatureState::disabled; - global.params.markdown = !value; global.params.dtorFields = FeatureState::disabled; + global.params.fix16997 = !value; + global.params.markdown = !value; break; case OPT_frevert_dip25: @@ -654,6 +651,10 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, global.params.dtorFields = FeatureState::disabled; break; + case OPT_frevert_intpromote: + global.params.fix16997 = !value; + break; + case OPT_frevert_markdown: global.params.markdown = !value; break; diff --git a/gcc/d/d-port.cc b/gcc/d/d-port.cc index 58b3fe138b2..4e867a7db4a 100644 --- a/gcc/d/d-port.cc +++ b/gcc/d/d-port.cc @@ -145,6 +145,8 @@ Port::readlongBE (const void *buffer) void Port::valcpy (void *buffer, uint64_t value, size_t sz) { + gcc_assert (((size_t) buffer) % sz == 0); + switch (sz) { case 1: diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index 21417dddf78..dd244f12119 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -287,7 +287,7 @@ Target::isVectorTypeSupported (int sz, Type *type) Returns true if the operation is supported or type is not a vector. */ bool -Target::isVectorOpSupported (Type *type, unsigned op, Type *) +Target::isVectorOpSupported (Type *type, EXP op, Type *) { if (type->ty != TY::Tvector) return true; @@ -299,31 +299,31 @@ Target::isVectorOpSupported (Type *type, unsigned op, Type *) /* Don't support if expression cannot be represented. */ switch (op) { - case TOKpow: - case TOKpowass: + case EXP::pow: + case EXP::powAssign: /* pow() is lowered as a function call. */ return false; - case TOKmod: - case TOKmodass: + case EXP::mod: + case EXP::modAssign: /* fmod() is lowered as a function call. */ if (type->isfloating ()) return false; break; - case TOKandand: - case TOKoror: + case EXP::andAnd: + case EXP::orOr: /* Logical operators must have a result type of bool. */ return false; - case TOKle: - case TOKlt: - case TOKge: - case TOKgt: - case TOKequal: - case TOKnotequal: - case TOKidentity: - case TOKnotidentity: + case EXP::lessOrEqual: + case EXP::lessThan: + case EXP::greaterOrEqual: + case EXP::greaterThan: + case EXP::equal: + case EXP::notEqual: + case EXP::identity: + case EXP::notIdentity: /* Comparison operators must have a result type of bool. */ return false; diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index c69f5664e8c..bbde4a669e4 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -2239,7 +2239,7 @@ layout_class_initializer (ClassDeclaration *cd) ne->type = cd->type; Expression *e = ne->ctfeInterpret (); - gcc_assert (e->op == TOKclassreference); + gcc_assert (e->op == EXP::classReference); return build_class_instance (e->isClassReferenceExp ()); } diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 8e1d43e2b8f..f1c014dbc16 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -88,7 +88,7 @@ lvalue_p (Expression *e) if (ce != NULL && ce->e1->isLvalue ()) return true; - return (e->op != TOKslice && e->isLvalue ()); + return (e->op != EXP::slice && e->isLvalue ()); } /* Build an expression of code CODE, data type TYPE, and operands ARG0 and @@ -162,7 +162,7 @@ binop_assignment (tree_code code, Expression *e1, Expression *e2) { /* Skip casts for lhs assignment. */ Expression *e1b = e1; - while (e1b->op == TOKcast) + while (e1b->op == EXP::cast_) { CastExp *ce = e1b->isCastExp (); gcc_assert (same_type_p (ce->type, ce->to)); @@ -264,7 +264,7 @@ public: void visit (IdentityExp *e) { - tree_code code = (e->op == TOKidentity) ? EQ_EXPR : NE_EXPR; + tree_code code = (e->op == EXP::identity) ? EQ_EXPR : NE_EXPR; Type *tb1 = e->e1->type->toBasetype (); Type *tb2 = e->e2->type->toBasetype (); @@ -331,7 +331,7 @@ public: { Type *tb1 = e->e1->type->toBasetype (); Type *tb2 = e->e2->type->toBasetype (); - tree_code code = (e->op == TOKequal) ? EQ_EXPR : NE_EXPR; + tree_code code = (e->op == EXP::equal) ? EQ_EXPR : NE_EXPR; if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray) && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray)) @@ -391,7 +391,7 @@ public: Otherwise for inequality: (e1.length != 0 && memcmp); */ tree tsizecmp = build_boolop (code, t1len, size_zero_node); - if (e->op == TOKequal) + if (e->op == EXP::equal) result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result); else result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result); @@ -404,7 +404,7 @@ public: else { tree tlencmp = build_boolop (code, t1len, t2len); - if (e->op == TOKequal) + if (e->op == EXP::equal) result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result); else result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result); @@ -428,7 +428,7 @@ public: d_array_convert (e->e2), build_typeinfo (e->loc, t1array)); - if (e->op == TOKnotequal) + if (e->op == EXP::notEqual) result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result); this->result_ = result; @@ -453,7 +453,7 @@ public: build_expr (e->e1), build_expr (e->e2)); - if (e->op == TOKnotequal) + if (e->op == EXP::notEqual) result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result); this->result_ = result; @@ -499,19 +499,19 @@ public: switch (e->op) { - case TOKle: + case EXP::lessOrEqual: code = LE_EXPR; break; - case TOKlt: + case EXP::lessThan: code = LT_EXPR; break; - case TOKge: + case EXP::greaterOrEqual: code = GE_EXPR; break; - case TOKgt: + case EXP::greaterThan: code = GT_EXPR; break; @@ -540,7 +540,7 @@ public: void visit (LogicalExp *e) { - tree_code code = (e->op == TOKandand) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; + tree_code code = (e->op == EXP::andAnd) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; if (e->e2->type->toBasetype ()->ty != TY::Tvoid) { @@ -559,7 +559,7 @@ public: tree t2 = build_expr_dtor (e->e2); /* Invert condition for logical or if expression. */ - if (e->op == TOKoror) + if (e->op == EXP::orOr) t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1); this->result_ = build_condition (build_ctype (e->type), @@ -576,8 +576,8 @@ public: switch (e->op) { - case TOKadd: - case TOKmin: + case EXP::add: + case EXP::min: if ((e->e1->type->isreal () && e->e2->type->isimaginary ()) || (e->e1->type->isimaginary () && e->e2->type->isreal ())) { @@ -586,7 +586,7 @@ public: tree t1 = build_expr (e->e1); tree t2 = build_expr (e->e2); - if (e->op == TOKmin) + if (e->op == EXP::min) t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2); if (e->e1->type->isreal ()) @@ -597,22 +597,22 @@ public: return; } else - code = (e->op == TOKadd) + code = (e->op == EXP::add) ? PLUS_EXPR : MINUS_EXPR; break; - case TOKmul: + case EXP::mul: code = MULT_EXPR; break; - case TOKdiv: + case EXP::div: /* Determine if the div expression is a lowered pointer diff operation. The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */ if (MinExp *me = e->e1->isMinExp ()) { if (me->e1->type->ty == TY::Tpointer && me->e2->type->ty == TY::Tpointer - && e->e2->op == TOKint64) + && e->e2->op == EXP::int64) { code = EXACT_DIV_EXPR; break; @@ -623,32 +623,32 @@ public: ? TRUNC_DIV_EXPR : RDIV_EXPR; break; - case TOKmod: + case EXP::mod: code = e->e1->type->isfloating () ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR; break; - case TOKand: + case EXP::and_: code = BIT_AND_EXPR; break; - case TOKor: + case EXP::or_: code = BIT_IOR_EXPR; break; - case TOKxor: + case EXP::xor_: code = BIT_XOR_EXPR; break; - case TOKshl: + case EXP::leftShift: code = LSHIFT_EXPR; break; - case TOKshr: + case EXP::rightShift: code = RSHIFT_EXPR; break; - case TOKushr: + case EXP::unsignedRightShift: code = UNSIGNED_RSHIFT_EXPR; break; @@ -678,15 +678,15 @@ public: tree result; - if (e->e1->op == TOKcat) + if (e->e1->op == EXP::concatenate) { /* Flatten multiple concatenations to an array. So the expression ((a ~ b) ~ c) becomes [a, b, c] */ int ndims = 2; - for (Expression *ex = e->e1; ex->op == TOKcat;) + for (Expression *ex = e->e1; ex->op == EXP::concatenate;) { - if (ex->op == TOKcat) + if (ex->op == EXP::concatenate) { ex = ex->isCatExp ()->e1; ndims++; @@ -703,7 +703,7 @@ public: int dim = ndims - 1; for (Expression *oe = ce->e2; oe != NULL; - (ce->e1->op != TOKcat + (ce->e1->op != EXP::concatenate ? (oe = ce->e1) : (ce = ce->e1->isCatExp (), oe = ce->e2))) { @@ -751,59 +751,59 @@ public: switch (e->op) { - case TOKaddass: + case EXP::addAssign: code = PLUS_EXPR; break; - case TOKminass: + case EXP::minAssign: code = MINUS_EXPR; break; - case TOKmulass: + case EXP::mulAssign: code = MULT_EXPR; break; - case TOKdivass: + case EXP::divAssign: code = e->e1->type->isintegral () ? TRUNC_DIV_EXPR : RDIV_EXPR; break; - case TOKmodass: + case EXP::modAssign: code = e->e1->type->isfloating () ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR; break; - case TOKandass: + case EXP::andAssign: code = BIT_AND_EXPR; break; - case TOKorass: + case EXP::orAssign: code = BIT_IOR_EXPR; break; - case TOKxorass: + case EXP::xorAssign: code = BIT_XOR_EXPR; break; - case TOKpowass: + case EXP::powAssign: gcc_unreachable (); - case TOKshlass: + case EXP::leftShiftAssign: code = LSHIFT_EXPR; break; - case TOKshrass: - case TOKushrass: + case EXP::rightShiftAssign: + case EXP::unsignedRightShiftAssign: /* Use the original lhs type before it was promoted. The left operand of `>>>=' does not undergo integral promotions before shifting. Strip off casts just incase anyway. */ - while (e1b->op == TOKcast) + while (e1b->op == EXP::cast_) { CastExp *ce = e1b->isCastExp (); gcc_assert (same_type_p (ce->type, ce->to)); e1b = ce->e1; } - code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR; + code = (e->op == EXP::rightShiftAssign) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR; break; default: @@ -908,7 +908,7 @@ public: /* First, handle special assignment semantics. */ /* Look for array.length = n; */ - if (e->e1->op == TOKarraylength) + if (e->e1->op == EXP::arrayLength) { /* This case should have been rewritten to `_d_arraysetlengthT` in the semantic phase. */ @@ -916,7 +916,7 @@ public: } /* Look for array[] = n; */ - if (e->e1->op == TOKslice) + if (e->e1->op == EXP::slice) { SliceExp *se = e->e1->isSliceExp (); Type *stype = se->e1->type->toBasetype (); @@ -937,15 +937,18 @@ public: tree init = stabilize_expr (&t1); t1 = d_save_expr (t1); - if ((postblit || destructor) && e->op != TOKblit) + if ((postblit || destructor) && e->op != EXP::blit) { - libcall_fn libcall = (e->op == TOKconstruct) - ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN; + /* Need to call postblit/destructor as part of assignment. + Construction has already been handled by the front-end. */ + gcc_assert (e->op != EXP::construct); + /* So we can call postblits on const/immutable objects. */ Type *tm = etype->unSharedOf ()->mutableOf (); tree ti = build_typeinfo (e->loc, tm); - result = build_libcall (libcall, Type::tvoid, 4, + /* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti); */ + result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4, d_array_ptr (t1), build_address (t2), d_array_length (t1), ti); @@ -1011,14 +1014,11 @@ public: this->result_ = compound_expr (result, t1); } - else if ((postblit || destructor) && e->op != TOKblit) + else if ((postblit || destructor) + && e->op != EXP::blit && e->op != EXP::construct) { - /* Generate: _d_arrayassign(ti, from, to) - or: _d_arrayctor(ti, from, to) */ - libcall_fn libcall = (e->op == TOKconstruct) - ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN; - - this->result_ = build_libcall (libcall, e->type, 3, + /* Generate: _d_arrayassign(ti, from, to); */ + this->result_ = build_libcall (LIBCALL_ARRAYASSIGN, e->type, 3, build_typeinfo (e->loc, etype), d_array_convert (e->e2), d_array_convert (e->e1)); @@ -1039,8 +1039,8 @@ public: /* Look for reference initializations. */ if (e->memset == MemorySet::referenceInit) { - gcc_assert (e->op == TOKconstruct || e->op == TOKblit); - gcc_assert (e->e1->op == TOKvar); + gcc_assert (e->op == EXP::construct || e->op == EXP::blit); + gcc_assert (e->e1->op == EXP::variable); Declaration *decl = e->e1->isVarExp ()->var; if (decl->storage_class & (STCout | STCref)) @@ -1060,7 +1060,7 @@ public: /* Other types of assignments that may require post construction. */ Type *tb1 = e->e1->type->toBasetype (); - tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR; + tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR; /* Look for struct assignment. */ if (tb1->ty == TY::Tstruct) @@ -1071,10 +1071,10 @@ public: StructDeclaration *sd = tb1->isTypeStruct ()->sym; /* Look for struct = 0. */ - if (e->e2->op == TOKint64) + if (e->e2->op == EXP::int64) { /* Use memset to fill struct. */ - gcc_assert (e->op == TOKblit); + gcc_assert (e->op == EXP::blit); tree result = build_memset_call (t1); /* Maybe set-up hidden pointer to outer scope context. */ @@ -1095,8 +1095,8 @@ public: tree init = NULL_TREE; /* Fill any alignment holes in the struct using memset. */ - if ((e->op == TOKconstruct - || (e->e2->op == TOKstructliteral && e->op == TOKblit)) + if ((e->op == EXP::construct + || (e->e2->op == EXP::structLiteral && e->op == EXP::blit)) && (sd->isUnionDeclaration () || !identity_compare_p (sd))) { t1 = stabilize_reference (t1); @@ -1120,10 +1120,10 @@ public: if (tb1->ty == TY::Tsarray) { /* Look for array = 0. */ - if (e->e2->op == TOKint64) + if (e->e2->op == EXP::int64) { /* Use memset to fill the array. */ - gcc_assert (e->op == TOKblit); + gcc_assert (e->op == EXP::blit); this->result_ = build_memset_call (build_expr (e->e1)); return; } @@ -1132,17 +1132,17 @@ public: gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray); /* Determine if we need to run postblit. */ - bool postblit = needs_postblit (etype); - bool destructor = needs_dtor (etype); - bool lvalue = lvalue_p (e->e2); + const bool postblit = needs_postblit (etype); + const bool destructor = needs_dtor (etype); + const bool lvalue = lvalue_p (e->e2); /* Optimize static array assignment with array literal. Even if the elements in rhs are all rvalues and don't have to call postblits, this assignment should call dtors on old assigned elements. */ if ((!postblit && !destructor) - || (e->op == TOKconstruct && e->e2->op == TOKarrayliteral) - || (e->op == TOKconstruct && !lvalue && postblit) - || (e->op == TOKblit || e->e1->type->size () == 0)) + || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral) + || (e->op == EXP::construct && !lvalue && postblit) + || (e->op == EXP::blit || e->e1->type->size () == 0)) { tree t1 = build_expr (e->e1); tree t2 = convert_for_assignment (build_expr (e->e2), @@ -1152,32 +1152,22 @@ public: return; } + /* All other kinds of lvalue or rvalue static array assignment. + Array construction has already been handled by the front-end. */ + gcc_assert (e->op != EXP::construct); + + /* Generate: _d_arrayassign_l() + or: _d_arrayassign_r() */ + libcall_fn libcall = (lvalue) + ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R; + tree elembuf = build_local_temp (build_ctype (etype)); Type *arrtype = (e->type->ty == TY::Tsarray) ? etype->arrayOf () : e->type; - tree result; - - if (e->op == TOKconstruct) - { - /* Generate: _d_arrayctor(ti, from, to) */ - result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3, - build_typeinfo (e->loc, etype), - d_array_convert (e->e2), - d_array_convert (e->e1)); - } - else - { - /* Generate: _d_arrayassign_l() - or: _d_arrayassign_r() */ - libcall_fn libcall = (lvalue) - ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R; - tree elembuf = build_local_temp (build_ctype (etype)); - - result = build_libcall (libcall, arrtype, 4, - build_typeinfo (e->loc, etype), - d_array_convert (e->e2), - d_array_convert (e->e1), - build_address (elembuf)); - } + tree result = build_libcall (libcall, arrtype, 4, + build_typeinfo (e->loc, etype), + d_array_convert (e->e2), + d_array_convert (e->e1), + build_address (elembuf)); /* Cast the libcall result back to a static array. */ if (e->type->ty == TY::Tsarray) @@ -1202,12 +1192,12 @@ public: { tree result; - if (e->op == TOKplusplus) + if (e->op == EXP::plusPlus) { result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type), build_expr (e->e1), build_expr (e->e2)); } - else if (e->op == TOKminusminus) + else if (e->op == EXP::minusMinus) { result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type), build_expr (e->e1), build_expr (e->e2)); @@ -1441,7 +1431,7 @@ public: the destructor is called for the object instance. */ libcall_fn libcall; - if (e->e1->op == TOKvar) + if (e->e1->op == EXP::variable) { VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration (); if (v && v->onstack) @@ -1586,10 +1576,10 @@ public: size_t offset; tree result; - if (e->e1->op == TOKadd) + if (e->e1->op == EXP::add) { AddExp *ae = e->e1->isAddExp (); - if (ae->e1->op == TOKaddress + if (ae->e1->op == EXP::address && ae->e2->isConst () && ae->e2->type->isintegral ()) { Expression *ex = ae->e1->isAddrExp ()->e1; @@ -1598,7 +1588,7 @@ public: offset = ae->e2->toUInteger (); } } - else if (e->e1->op == TOKsymoff) + else if (e->e1->op == EXP::symbolOffset) { SymOffExp *se = e->e1->isSymOffExp (); if (!declaration_reference_p (se->var)) @@ -1650,7 +1640,7 @@ public: /* The frontend optimizer can convert const symbol into a struct literal. Taking the address of a struct literal is otherwise illegal. */ - if (e->e1->op == TOKstructliteral) + if (e->e1->op == EXP::structLiteral) { StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin; gcc_assert (sle != NULL); @@ -1689,21 +1679,21 @@ public: TypeFunction *tf = NULL; /* Calls to delegates can sometimes look like this. */ - if (e1b->op == TOKcomma) + if (e1b->op == EXP::comma) { e1b = e1b->isCommaExp ()->e2; - gcc_assert (e1b->op == TOKvar); + gcc_assert (e1b->op == EXP::variable); Declaration *var = e1b->isVarExp ()->var; gcc_assert (var->isFuncDeclaration () && !var->needThis ()); } - if (e1b->op == TOKdotvar && tb->ty != TY::Tdelegate) + if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate) { DotVarExp *dve = e1b->isDotVarExp (); /* Don't modify the static initializer for struct literals. */ - if (dve->e1->op == TOKstructliteral) + if (dve->e1->op == EXP::structLiteral) { StructLiteralExp *sle = dve->e1->isStructLiteralExp (); sle->useStaticInit = false; @@ -1775,7 +1765,7 @@ public: { /* This could be a delegate expression (TY == Tdelegate), but not actually a delegate variable. */ - if (e1b->op == TOKdotvar) + if (e1b->op == EXP::dotVariable) { /* This gets the true function type, getting the function type from e1->type can sometimes be incorrect, such as when calling @@ -1795,7 +1785,7 @@ public: object = delegate_object (callee); callee = delegate_method (callee); } - else if (e1b->op == TOKvar) + else if (e1b->op == EXP::variable) { FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration (); gcc_assert (fd != NULL); @@ -1877,7 +1867,7 @@ public: if (e->func->isNested () && !e->func->isThis ()) { - if (e->e1->op == TOKnull) + if (e->e1->op == EXP::null_) object = build_expr (e->e1); else object = get_frame_for_symbol (e->func); @@ -1908,7 +1898,7 @@ public: /* Get pointer to function out of the virtual table. */ if (e->func->isVirtual () && !e->func->isFinalFunc () - && e->e1->op != TOKsuper && e->e1->op != TOKdottype) + && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType) { tree fntype = build_pointer_type (TREE_TYPE (fndecl)); object = d_save_expr (object); @@ -2105,9 +2095,9 @@ public: Type *ftype = e->type->toBasetype (); /* This check is for lambda's, remove `vthis' as function isn't nested. */ - if (e->fd->tok == TOKreserved && ftype->ty == TY::Tpointer) + if (e->fd->tok == TOK::reserved && ftype->ty == TY::Tpointer) { - e->fd->tok = TOKfunction; + e->fd->tok = TOK::function_; e->fd->vthis = NULL; } @@ -2196,9 +2186,9 @@ public: FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration (); if (fld != NULL) { - if (fld->tok == TOKreserved) + if (fld->tok == TOK::reserved) { - fld->tok = TOKfunction; + fld->tok = TOK::function_; fld->vthis = NULL; } @@ -2210,7 +2200,7 @@ public: { /* Want the initializer, not the expression. */ VarDeclaration *var = e->var->isVarDeclaration (); - SymbolDeclaration *sd = e->var->isSymbolDeclaration (); + SymbolDeclaration *sdecl = e->var->isSymbolDeclaration (); tree init = NULL_TREE; if (var && (var->isConst () || var->isImmutable ()) @@ -2226,8 +2216,15 @@ public: var->inuse--; } } - else if (sd && sd->dsym) - init = layout_struct_initializer (sd->dsym); + else if (sdecl && sdecl->dsym) + { + if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ()) + init = layout_struct_initializer (sd); + else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ()) + init = layout_class_initializer (cd); + else + gcc_unreachable (); + } else error_at (make_location_t (e->loc), "non-constant expression %qs", e->toChars ()); @@ -2242,6 +2239,26 @@ public: tree result = get_decl_tree (e->var); TREE_USED (result) = 1; + /* The variable expression generated for `__traits(initSymbol)'. */ + if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ()) + { + if (e->type->isTypeDArray ()) + { + /* Generate a slice for non-zero initialized aggregates, + otherwise create an empty array. */ + gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ()); + + tree type = build_ctype (e->type); + tree length = size_int (sd->dsym->structsize); + tree ptr = (sd->dsym->isStructDeclaration () + && sd->dsym->type->isZeroInit (e->loc)) + ? null_pointer_node : build_address (result); + + this->result_ = d_array_value (type, length, ptr); + return; + } + } + /* For variables that are references - currently only out/inout arguments; objects don't count - evaluating the variable means we want what it refers to. */ @@ -2954,7 +2971,7 @@ public: tree type = build_ctype (e->type); /* First handle array literal expressions. */ - if (e->e1->op == TOKarrayliteral) + if (e->e1->op == EXP::arrayLiteral) { ArrayLiteralExp *ale = e->e1->isArrayLiteralExp (); vec *elms = NULL; diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc index b14b0ca5111..dec2bd47265 100644 --- a/gcc/d/intrinsics.cc +++ b/gcc/d/intrinsics.cc @@ -431,7 +431,7 @@ expand_intrinsic_rotate (intrinsic_code intrinsic, tree callexp) gcc_assert (ti && ti->tiargs && ti->tiargs->length == 2); Expression *e = isExpression ((*ti->tiargs)[0]); - gcc_assert (e && e->op == TOKint64); + gcc_assert (e && e->op == EXP::int64); count = build_expr (e, true); } diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt index d0a5e2f6859..893bc238631 100644 --- a/gcc/d/lang.opt +++ b/gcc/d/lang.opt @@ -380,10 +380,6 @@ fpreview=inclusiveincontracts D RejectNegative Implement 'in' contracts of overridden methods to be a superset of parent contract. -fpreview=intpromote -D RejectNegative -Use C-style integral promotion for unary '+', '-' and '~'. - fpreview=nosharedaccess D RejectNegative Disable access to shared memory objects. @@ -412,6 +408,10 @@ frevert=dtorfields D RejectNegative Don't destruct fields of partially constructed objects. +frevert=intpromote +D RejectNegative +Use C-style integral promotion for unary '+', '-' and '~'. + frevert=markdown D RejectNegative Disable Markdown replacements in Ddoc. diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def index fdff6db0626..3961a1d9bed 100644 --- a/gcc/d/runtime.def +++ b/gcc/d/runtime.def @@ -140,13 +140,6 @@ DEF_D_RUNTIME (ARRAYASSIGN_R, "_d_arrayassign_r", RT(ARRAY_VOID), DEF_D_RUNTIME (ARRAYSETASSIGN, "_d_arraysetassign", RT(VOIDPTR), P4(VOIDPTR, VOIDPTR, SIZE_T, CONST_TYPEINFO), 0) -/* Used for constructing a new array from an existing array. The `set' variant - is for when the constructor value is a single element. */ -DEF_D_RUNTIME (ARRAYCTOR, "_d_arrayctor", RT(ARRAY_VOID), - P3(CONST_TYPEINFO, ARRAY_VOID, ARRAY_VOID), 0) -DEF_D_RUNTIME (ARRAYSETCTOR, "_d_arraysetctor", RT(VOIDPTR), - P4(VOIDPTR, VOIDPTR, SIZE_T, CONST_TYPEINFO), 0) - /* Used for concatenating two or more arrays together. Then `n' variant is for when there is more than two arrays to handle. */ DEF_D_RUNTIME (ARRAYCATT, "_d_arraycatT", RT(ARRAY_BYTE), diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc index 55d63f89cb7..17b63ba8a7d 100644 --- a/gcc/d/toir.cc +++ b/gcc/d/toir.cc @@ -969,8 +969,7 @@ public: StructLiteralExp *sle = NULL; bool using_rvo_p = false; - if (DotVarExp *dve = (s->exp->op == TOKcall - && s->exp->isCallExp ()->e1->op == TOKdotvar + if (DotVarExp *dve = (s->exp->isCallExp () ? s->exp->isCallExp ()->e1->isDotVarExp () : NULL)) { diff --git a/gcc/d/types.cc b/gcc/d/types.cc index b39b92eb822..1d551e5249b 100644 --- a/gcc/d/types.cc +++ b/gcc/d/types.cc @@ -338,7 +338,7 @@ layout_aggregate_members (Dsymbols *members, tree context, bool inherited_p) RootObject *ro = (*td->objects)[j]; gcc_assert (ro->dyncast () == DYNCAST_EXPRESSION); Expression *e = (Expression *) ro; - gcc_assert (e->op == TOKdsymbol); + gcc_assert (e->op == EXP::dSymbol); DsymbolExp *se = e->isDsymbolExp (); tmembers.push (se->s); From patchwork Fri Dec 10 04:28:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 48748 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 450E83858035 for ; Fri, 10 Dec 2021 04:33:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 450E83858035 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1639110836; bh=beONMXjTlRZKy8NdkObreIdpj0wfGVOemhnPUQoxLOI=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=JYh2Kfj8l8CX6O5UQGgeBDCsYgu0w81G3kD3RroAZ5KPOCkR6IziBhV1ipKu4Ccdq z+7tSqx8hc/Epmldy9MLcrAshozpMEbvRF5qefNuxgECDbb/tzjU7fMDXg3aOvcKKV qEmD6e9FXdHXWiLN9gihSRszbmuCysrE7fkEoTEE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [IPv6:2001:67c:2050::465:101]) by sourceware.org (Postfix) with ESMTPS id B82243858024 for ; Fri, 10 Dec 2021 04:29:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B82243858024 Received: from smtp202.mailbox.org (smtp202.mailbox.org [80.241.60.245]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4J9Hwg1kTyzQjgF; Fri, 10 Dec 2021 05:29:07 +0100 (CET) X-Virus-Scanned: amavisd-new at heinlein-support.de To: gcc-patches@gcc.gnu.org Subject: [committed 3/3] d: Merge upstream druntime bc58b1e9, phobos 12329adb6. Date: Fri, 10 Dec 2021 05:28:58 +0100 Message-Id: <20211210042858.532279-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SOMETLD_ARE_BAD_TLD, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch merges the D2 testsuite with upstream dmd 3982604c5, and the D run-time libraries with upstream druntime bc58b1e9, and phobos 12329adb6. Druntime changes: - Import druntime mainline development. - Define SIG_BLOCK for Solaris (PR103528). Phobos changes: - Import phobos mainline development. Bootstrapped and regression tested on x86_64-linux-gnu, committed to mainline. Regards, Iain. --- libphobos/ChangeLog: PR d/103528 * libdruntime/MERGE: Merge upstream druntime bc58b1e9. * libdruntime/Makefile.am (DRUNTIME_DSOURCES_LINUX): Remove core/sys/linux/syscalls.d. * libdruntime/Makefile.in: Regenerate. * src/MERGE: Merge upstream phobos 12329adb6. * testsuite/libphobos.config/config.exp: Add test22523. * libdruntime/core/sys/linux/syscalls.d: Removed. * testsuite/libphobos.config/test22523.d: New test. --- .../gdc.test/compilable/covariant_override.d | 34 + .../gdc.test/compilable/emptygenmain.d | 3 + gcc/testsuite/gdc.test/compilable/noreturn1.d | 12 + gcc/testsuite/gdc.test/compilable/test17870.d | 26 + gcc/testsuite/gdc.test/compilable/test19873.d | 37 + gcc/testsuite/gdc.test/compilable/test21719.d | 21 + gcc/testsuite/gdc.test/compilable/test22254.d | 19 + gcc/testsuite/gdc.test/compilable/test22510.d | 18 + .../fail_compilation/covariant_override.d | 35 + .../gdc.test/fail_compilation/fail10964.d | 4 +- .../gdc.test/fail_compilation/fail10968.d | 38 +- .../gdc.test/fail_compilation/fail16997.d | 38 +- .../gdc.test/fail_compilation/fail809.d | 12 - .../gdc.test/fail_compilation/fob2.d | 2 +- .../fail_compilation/imports/test20023b.d | 10 + .../gdc.test/fail_compilation/retscope.d | 8 +- .../gdc.test/fail_compilation/test15191.d | 42 +- .../gdc.test/fail_compilation/test17977.d | 20 + .../gdc.test/fail_compilation/test20023.d | 16 + .../fail_compilation/traits_initSymbol.d | 63 + gcc/testsuite/gdc.test/runnable/b19294.d | 163 ++ gcc/testsuite/gdc.test/runnable/mars1.d | 2 +- gcc/testsuite/gdc.test/runnable/test15862.d | 39 + gcc/testsuite/gdc.test/runnable/test21367.d | 47 + gcc/testsuite/gdc.test/runnable/test22227.d | 16 + gcc/testsuite/gdc.test/runnable/testOpApply.d | 31 +- gcc/testsuite/gdc.test/runnable/testcgelem.d | 2 +- gcc/testsuite/gdc.test/runnable/testconst.d | 8 +- .../gdc.test/runnable/traits_initSymbol.d | 119 ++ gcc/testsuite/gdc.test/runnable/xtest46.d | 7 +- .../runnable_cxx/extra-files/cpp7925.cpp | 103 ++ .../gdc.test/runnable_cxx/test7925.d | 151 ++ libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/Makefile.am | 5 +- libphobos/libdruntime/Makefile.in | 12 +- libphobos/libdruntime/core/demangle.d | 8 +- .../core/internal/array/construction.d | 43 +- libphobos/libdruntime/core/internal/convert.d | 8 +- .../libdruntime/core/internal/lifetime.d | 49 +- libphobos/libdruntime/core/internal/string.d | 2 +- libphobos/libdruntime/core/internal/utf.d | 10 +- libphobos/libdruntime/core/lifetime.d | 111 +- libphobos/libdruntime/core/memory.d | 21 +- libphobos/libdruntime/core/stdc/stdlib.d | 10 + libphobos/libdruntime/core/stdc/string.d | 28 +- libphobos/libdruntime/core/stdc/wchar_.d | 26 +- libphobos/libdruntime/core/stdcpp/exception.d | 2 + libphobos/libdruntime/core/sync/mutex.d | 4 +- .../libdruntime/core/sys/bionic/string.d | 2 +- .../libdruntime/core/sys/darwin/mach/nlist.d | 2 +- .../libdruntime/core/sys/darwin/string.d | 2 +- .../core/sys/dragonflybsd/string.d | 2 +- .../libdruntime/core/sys/freebsd/string.d | 2 +- libphobos/libdruntime/core/sys/linux/string.d | 2 +- .../libdruntime/core/sys/linux/syscalls.d | 745 -------- libphobos/libdruntime/core/sys/linux/unistd.d | 26 +- .../libdruntime/core/sys/netbsd/string.d | 2 +- .../libdruntime/core/sys/openbsd/string.d | 2 +- libphobos/libdruntime/core/sys/posix/signal.d | 26 +- libphobos/libdruntime/core/sys/posix/string.d | 8 +- .../libdruntime/core/sys/posix/sys/socket.d | 2 +- .../libdruntime/core/sys/solaris/sys/elf.d | 5 +- .../core/sys/solaris/sys/elf_386.d | 3 - .../core/sys/solaris/sys/elf_SPARC.d | 3 - .../libdruntime/core/sys/windows/dbghelp.d | 8 +- libphobos/libdruntime/core/thread/osthread.d | 5 +- .../libdruntime/core/thread/threadbase.d | 5 +- libphobos/libdruntime/object.d | 8 +- libphobos/libdruntime/rt/aaA.d | 4 +- libphobos/libdruntime/rt/cast_.d | 2 +- libphobos/libdruntime/rt/config.d | 3 + libphobos/libdruntime/rt/lifetime.d | 4 +- libphobos/libdruntime/rt/monitor_.d | 2 +- libphobos/src/MERGE | 2 +- libphobos/src/std/algorithm/iteration.d | 52 +- libphobos/src/std/algorithm/mutation.d | 29 +- libphobos/src/std/algorithm/sorting.d | 26 +- libphobos/src/std/concurrency.d | 32 +- libphobos/src/std/container/dlist.d | 6 + libphobos/src/std/container/rbtree.d | 2 +- libphobos/src/std/datetime/interval.d | 6 +- libphobos/src/std/datetime/systime.d | 27 +- libphobos/src/std/datetime/timezone.d | 74 +- libphobos/src/std/file.d | 28 +- libphobos/src/std/internal/cstring.d | 2 +- libphobos/src/std/internal/math/biguintcore.d | 12 +- libphobos/src/std/json.d | 10 +- libphobos/src/std/net/isemail.d | 2 +- libphobos/src/std/process.d | 4 +- libphobos/src/std/random.d | 12 +- libphobos/src/std/stdio.d | 2 +- libphobos/src/std/typecons.d | 35 +- libphobos/src/std/uni/package.d | 4 +- libphobos/src/std/utf.d | 12 +- .../testsuite/libphobos.config/config.exp | 1 + .../testsuite/libphobos.config/test22523.d | 11 + 96 files changed, 1604 insertions(+), 1149 deletions(-) create mode 100644 gcc/d/dmd/root/optional.d create mode 100644 gcc/d/dmd/root/optional.h create mode 100644 gcc/testsuite/gdc.test/compilable/covariant_override.d create mode 100644 gcc/testsuite/gdc.test/compilable/emptygenmain.d create mode 100644 gcc/testsuite/gdc.test/compilable/test17870.d create mode 100644 gcc/testsuite/gdc.test/compilable/test19873.d create mode 100644 gcc/testsuite/gdc.test/compilable/test21719.d create mode 100644 gcc/testsuite/gdc.test/compilable/test22254.d create mode 100644 gcc/testsuite/gdc.test/compilable/test22510.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/covariant_override.d delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail809.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/test20023b.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test17977.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test20023.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/traits_initSymbol.d create mode 100644 gcc/testsuite/gdc.test/runnable/b19294.d create mode 100644 gcc/testsuite/gdc.test/runnable/test15862.d create mode 100644 gcc/testsuite/gdc.test/runnable/test21367.d create mode 100644 gcc/testsuite/gdc.test/runnable/test22227.d create mode 100644 gcc/testsuite/gdc.test/runnable/traits_initSymbol.d create mode 100644 gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp create mode 100644 gcc/testsuite/gdc.test/runnable_cxx/test7925.d delete mode 100644 libphobos/libdruntime/core/sys/linux/syscalls.d create mode 100644 libphobos/testsuite/libphobos.config/test22523.d diff --git a/gcc/testsuite/gdc.test/compilable/covariant_override.d b/gcc/testsuite/gdc.test/compilable/covariant_override.d new file mode 100644 index 00000000000..1afe0a28cfb --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/covariant_override.d @@ -0,0 +1,34 @@ +// https://issues.dlang.org/show_bug.cgi?id=21538 +// REQUIRED_ARGS: -preview=dip1000 + +interface I +{ + void f(void delegate() @safe dg) @safe; +} + +class CI : I +{ + override void f(void delegate() @system dg) @safe { } +} + +abstract class A +{ + void f(void delegate() @safe dg) @safe; +} + +class CA : A +{ + override void f(void delegate() @system dg) @safe { } +} + +// https://issues.dlang.org/show_bug.cgi?id=20904 +auto blah(void delegate()) +{ +} + +void delegate()[string] r; +void main() +{ + void delegate() nothrow a; + r["v"] = a; +} diff --git a/gcc/testsuite/gdc.test/compilable/emptygenmain.d b/gcc/testsuite/gdc.test/compilable/emptygenmain.d new file mode 100644 index 00000000000..be7bee83fa0 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/emptygenmain.d @@ -0,0 +1,3 @@ +// REQUIRED_ARGS: -main -c + +void foo() { } diff --git a/gcc/testsuite/gdc.test/compilable/noreturn1.d b/gcc/testsuite/gdc.test/compilable/noreturn1.d index b041e072e9c..22734cf48b3 100644 --- a/gcc/testsuite/gdc.test/compilable/noreturn1.d +++ b/gcc/testsuite/gdc.test/compilable/noreturn1.d @@ -111,3 +111,15 @@ void* useTls() void* a3 = &globalNoreturn; return a1 < a2 ? a2 : a3; } + +/***************************************************/ + +noreturn testfn(noreturn function() fn) +{ + fn(); +} + +noreturn testdg(noreturn delegate() dg) +{ + dg(); +} diff --git a/gcc/testsuite/gdc.test/compilable/test17870.d b/gcc/testsuite/gdc.test/compilable/test17870.d new file mode 100644 index 00000000000..2329b609170 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test17870.d @@ -0,0 +1,26 @@ +alias AliasSeq(T...) = T; + +class A +{ + int z = 3; +} + +class B : A +{ + int a = 1; +} + +class C : B +{ + int b = 2; + alias tup = AliasSeq!(b, a, z); +} + +void main() +{ + static const ins = new C; + static assert(&ins.tup[0] == &ins.b); + static assert(&ins.tup[1] == &ins.a); + static assert(&ins.tup[2] == &ins.z); + static assert(ins.tup == AliasSeq!(2,1,3)); +} diff --git a/gcc/testsuite/gdc.test/compilable/test19873.d b/gcc/testsuite/gdc.test/compilable/test19873.d new file mode 100644 index 00000000000..7252edd7520 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test19873.d @@ -0,0 +1,37 @@ +// PERMUTE_ARGS -preview=dip1000 +// https://issues.dlang.org/show_bug.cgi?id=19873 +int* ed(scope int* x) +{ + auto y = x; + return y; +} + +int* et(scope int* x) @trusted +{ + auto y = x; + return y; +} + +int* es(scope int* x) @system +{ + auto y = x; + return y; +} + +auto ad(scope int* x) +{ + auto y = x; + return y; +} + +auto at(scope int* x) @trusted +{ + auto y = x; + return y; +} + +auto as(scope int* x) @system +{ + auto y = x; + return y; +} diff --git a/gcc/testsuite/gdc.test/compilable/test21719.d b/gcc/testsuite/gdc.test/compilable/test21719.d new file mode 100644 index 00000000000..9d444e16c78 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test21719.d @@ -0,0 +1,21 @@ +// https://issues.dlang.org/show_bug.cgi?id=21719 + +struct S +{ + auto f() + { + } // inferred to be @safe @nogc pure nothrow +} + +class C +{ + auto f() // should also infer the same attributes + { + } +} + +pure @nogc nothrow @safe void test(S s, C c) +{ + s.f; + c.f; +} diff --git a/gcc/testsuite/gdc.test/compilable/test22254.d b/gcc/testsuite/gdc.test/compilable/test22254.d new file mode 100644 index 00000000000..94f6596a19d --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22254.d @@ -0,0 +1,19 @@ +// https://issues.dlang.org/show_bug.cgi?id=22254 + +struct Template(T) { T t; } + +Template!Bar a; +Template!Bar b; + +immutable struct Bar { } + +static assert(is(typeof(a) == typeof(b))); +static assert(is(typeof(a) == Template!(immutable Bar))); + +Template!C c1; +Template!C c2; + +immutable class C { } + +static assert(is(typeof(c1) == typeof(c2))); +static assert(is(typeof(c1) == Template!(immutable C))); diff --git a/gcc/testsuite/gdc.test/compilable/test22510.d b/gcc/testsuite/gdc.test/compilable/test22510.d new file mode 100644 index 00000000000..af5d0a433eb --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22510.d @@ -0,0 +1,18 @@ +// https://issues.dlang.org/show_bug.cgi?id=22510 + +struct S +{ + int b; + + @disable this(this); + this (scope ref inout S) inout + { + this.b = b; + } +} + +void main() +{ + auto scoped_s = S(4); + auto heap_s = new S(42); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/covariant_override.d b/gcc/testsuite/gdc.test/fail_compilation/covariant_override.d new file mode 100644 index 00000000000..7738770775d --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/covariant_override.d @@ -0,0 +1,35 @@ +/++ +https://issues.dlang.org/show_bug.cgi?id=21538 + +TEST_OUTPUT: +--- +fail_compilation/covariant_override.d(23): Error: function `@safe void covariant_override.CI.f(void delegate() @safe dg)` does not override any function, did you mean to override `@safe void covariant_override.I.f(void delegate() @system dg)`? +fail_compilation/covariant_override.d(34): Error: function `@safe void covariant_override.CA.f(void delegate() @safe dg)` does not override any function, did you mean to override `@safe void covariant_override.A.f(void delegate() @system dg)`? +fail_compilation/covariant_override.d(20): Error: class `covariant_override.CI` interface function `void f(void delegate() @system dg) @safe` is not implemented +--- +++/ + +static assert(!is(void delegate() @system : void delegate() @safe)); +static assert( is(void delegate() @safe : void delegate() @system)); + +interface I +{ + void f(void delegate() @system dg) @safe; +} + +class CI : I +{ + // this overrride should not be legal + override void f(void delegate() @safe dg) @safe { } +} + +abstract class A +{ + void f(void delegate() @system dg) @safe; +} + +class CA : A +{ + // this overrride should not be legal + override void f(void delegate() @safe dg) @safe { } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10964.d b/gcc/testsuite/gdc.test/fail_compilation/fail10964.d index de3673f7860..4b31a92f9ab 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail10964.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail10964.d @@ -5,8 +5,8 @@ fail_compilation/fail10964.d(28): Error: function `fail10964.S.__postblit` is no fail_compilation/fail10964.d(29): Error: function `fail10964.S.__postblit` is not `nothrow` fail_compilation/fail10964.d(30): Error: function `fail10964.S.__postblit` is not `nothrow` fail_compilation/fail10964.d(33): Error: function `fail10964.S.__postblit` is not `nothrow` -fail_compilation/fail10964.d(34): Error: function `fail10964.S.__postblit` is not `nothrow` -fail_compilation/fail10964.d(35): Error: function `fail10964.S.__postblit` is not `nothrow` +fail_compilation/fail10964.d(34): Error: function `core.internal.array.construction._d_arraysetctor!(S[], S)._d_arraysetctor` is not `nothrow` +fail_compilation/fail10964.d(35): Error: function `core.internal.array.construction._d_arrayctor!(S[], S)._d_arrayctor` is not `nothrow` fail_compilation/fail10964.d(22): Error: `nothrow` function `fail10964.foo` may throw --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10968.d b/gcc/testsuite/gdc.test/fail_compilation/fail10968.d index 06e0687ce39..d9f554a4b78 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail10968.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail10968.d @@ -1,24 +1,26 @@ /* TEST_OUTPUT: --- -fail_compilation/fail10968.d(39): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(39): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here -fail_compilation/fail10968.d(40): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(40): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here fail_compilation/fail10968.d(41): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` fail_compilation/fail10968.d(41): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here -fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here -fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here +fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here +fail_compilation/fail10968.d(42): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` +fail_compilation/fail10968.d(42): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` +fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here +fail_compilation/fail10968.d(43): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` +fail_compilation/fail10968.d(43): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` +fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here fail_compilation/fail10968.d(46): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` fail_compilation/fail10968.d(46): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` -fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here +fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here +fail_compilation/fail10968.d(47): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` +fail_compilation/fail10968.d(47): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` +fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here +fail_compilation/fail10968.d(47): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arraysetctor!(SA[], SA)._d_arraysetctor` +fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit` +fail_compilation/fail10968.d(48): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit` +fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here +fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arrayctor!(SA[], SA)._d_arrayctor` --- */ @@ -49,12 +51,12 @@ void bar() pure @safe /* TEST_OUTPUT: --- -fail_compilation/fail10968.d(72): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit -fail_compilation/fail10968.d(73): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit fail_compilation/fail10968.d(74): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit -fail_compilation/fail10968.d(77): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit -fail_compilation/fail10968.d(78): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit +fail_compilation/fail10968.d(75): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit +fail_compilation/fail10968.d(76): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit fail_compilation/fail10968.d(79): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit +fail_compilation/fail10968.d(80): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit +fail_compilation/fail10968.d(81): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail16997.d b/gcc/testsuite/gdc.test/fail_compilation/fail16997.d index a8f3ae453db..279d9da6dfc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail16997.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail16997.d @@ -1,25 +1,25 @@ /* -REQUIRED_ARGS: -de +REQUIRED_ARGS: -de -revert=intpromote TEST_OUTPUT: --- -fail_compilation/fail16997.d(31): Deprecation: integral promotion not done for `~c`, use '-preview=intpromote' switch or `~cast(int)(c)` -fail_compilation/fail16997.d(32): Deprecation: integral promotion not done for `-c`, use '-preview=intpromote' switch or `-cast(int)(c)` -fail_compilation/fail16997.d(33): Deprecation: integral promotion not done for `+c`, use '-preview=intpromote' switch or `+cast(int)(c)` -fail_compilation/fail16997.d(36): Deprecation: integral promotion not done for `~w`, use '-preview=intpromote' switch or `~cast(int)(w)` -fail_compilation/fail16997.d(37): Deprecation: integral promotion not done for `-w`, use '-preview=intpromote' switch or `-cast(int)(w)` -fail_compilation/fail16997.d(38): Deprecation: integral promotion not done for `+w`, use '-preview=intpromote' switch or `+cast(int)(w)` -fail_compilation/fail16997.d(41): Deprecation: integral promotion not done for `~sb`, use '-preview=intpromote' switch or `~cast(int)(sb)` -fail_compilation/fail16997.d(42): Deprecation: integral promotion not done for `-sb`, use '-preview=intpromote' switch or `-cast(int)(sb)` -fail_compilation/fail16997.d(43): Deprecation: integral promotion not done for `+sb`, use '-preview=intpromote' switch or `+cast(int)(sb)` -fail_compilation/fail16997.d(46): Deprecation: integral promotion not done for `~ub`, use '-preview=intpromote' switch or `~cast(int)(ub)` -fail_compilation/fail16997.d(47): Deprecation: integral promotion not done for `-ub`, use '-preview=intpromote' switch or `-cast(int)(ub)` -fail_compilation/fail16997.d(48): Deprecation: integral promotion not done for `+ub`, use '-preview=intpromote' switch or `+cast(int)(ub)` -fail_compilation/fail16997.d(51): Deprecation: integral promotion not done for `~s`, use '-preview=intpromote' switch or `~cast(int)(s)` -fail_compilation/fail16997.d(52): Deprecation: integral promotion not done for `-s`, use '-preview=intpromote' switch or `-cast(int)(s)` -fail_compilation/fail16997.d(53): Deprecation: integral promotion not done for `+s`, use '-preview=intpromote' switch or `+cast(int)(s)` -fail_compilation/fail16997.d(56): Deprecation: integral promotion not done for `~us`, use '-preview=intpromote' switch or `~cast(int)(us)` -fail_compilation/fail16997.d(57): Deprecation: integral promotion not done for `-us`, use '-preview=intpromote' switch or `-cast(int)(us)` -fail_compilation/fail16997.d(58): Deprecation: integral promotion not done for `+us`, use '-preview=intpromote' switch or `+cast(int)(us)` +fail_compilation/fail16997.d(31): Deprecation: integral promotion not done for `~c`, remove '-revert=intpromote' switch or `~cast(int)(c)` +fail_compilation/fail16997.d(32): Deprecation: integral promotion not done for `-c`, remove '-revert=intpromote' switch or `-cast(int)(c)` +fail_compilation/fail16997.d(33): Deprecation: integral promotion not done for `+c`, remove '-revert=intpromote' switch or `+cast(int)(c)` +fail_compilation/fail16997.d(36): Deprecation: integral promotion not done for `~w`, remove '-revert=intpromote' switch or `~cast(int)(w)` +fail_compilation/fail16997.d(37): Deprecation: integral promotion not done for `-w`, remove '-revert=intpromote' switch or `-cast(int)(w)` +fail_compilation/fail16997.d(38): Deprecation: integral promotion not done for `+w`, remove '-revert=intpromote' switch or `+cast(int)(w)` +fail_compilation/fail16997.d(41): Deprecation: integral promotion not done for `~sb`, remove '-revert=intpromote' switch or `~cast(int)(sb)` +fail_compilation/fail16997.d(42): Deprecation: integral promotion not done for `-sb`, remove '-revert=intpromote' switch or `-cast(int)(sb)` +fail_compilation/fail16997.d(43): Deprecation: integral promotion not done for `+sb`, remove '-revert=intpromote' switch or `+cast(int)(sb)` +fail_compilation/fail16997.d(46): Deprecation: integral promotion not done for `~ub`, remove '-revert=intpromote' switch or `~cast(int)(ub)` +fail_compilation/fail16997.d(47): Deprecation: integral promotion not done for `-ub`, remove '-revert=intpromote' switch or `-cast(int)(ub)` +fail_compilation/fail16997.d(48): Deprecation: integral promotion not done for `+ub`, remove '-revert=intpromote' switch or `+cast(int)(ub)` +fail_compilation/fail16997.d(51): Deprecation: integral promotion not done for `~s`, remove '-revert=intpromote' switch or `~cast(int)(s)` +fail_compilation/fail16997.d(52): Deprecation: integral promotion not done for `-s`, remove '-revert=intpromote' switch or `-cast(int)(s)` +fail_compilation/fail16997.d(53): Deprecation: integral promotion not done for `+s`, remove '-revert=intpromote' switch or `+cast(int)(s)` +fail_compilation/fail16997.d(56): Deprecation: integral promotion not done for `~us`, remove '-revert=intpromote' switch or `~cast(int)(us)` +fail_compilation/fail16997.d(57): Deprecation: integral promotion not done for `-us`, remove '-revert=intpromote' switch or `-cast(int)(us)` +fail_compilation/fail16997.d(58): Deprecation: integral promotion not done for `+us`, remove '-revert=intpromote' switch or `+cast(int)(us)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail809.d b/gcc/testsuite/gdc.test/fail_compilation/fail809.d deleted file mode 100644 index b83639b0d08..00000000000 --- a/gcc/testsuite/gdc.test/fail_compilation/fail809.d +++ /dev/null @@ -1,12 +0,0 @@ -// REQUIRED_ARGS: -preview=dip1000 -/* -TEST_OUTPUT: ---- -fail_compilation/fail809.d(11): Error: scope variable `dg_` may not be returned ---- -*/ -int delegate() test(lazy int dg) -{ - int delegate() dg_ = &dg; - return dg_; -} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fob2.d b/gcc/testsuite/gdc.test/fail_compilation/fob2.d index dbe8ea2f883..175ade3cafc 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fob2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fob2.d @@ -120,7 +120,7 @@ fail_compilation/fob2.d(515): Error: variable `fob2.test52.p` has undefined stat } -@live void test52() +@live void test52() @safe { int x = 5; auto p = &x; diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test20023b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test20023b.d new file mode 100644 index 00000000000..c3e8a78e98d --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test20023b.d @@ -0,0 +1,10 @@ +module imports.test20023b; + +auto threw()() @safe +{ + try + throw new Exception("Hello"); + catch (Exception e) + return e; + assert(0); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d index 58f0430f5ad..64db4c81196 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d @@ -14,14 +14,14 @@ fail_compilation/retscope.d(49): Error: address of struct temporary returned by -int* foo1(return scope int* p) { return p; } // ok +int* foo1(return scope int* p) @safe { return p; } // ok -int* foo2()(scope int* p) { return p; } // ok, 'return' is inferred +int* foo2()(scope int* p) @safe { return p; } // ok, 'return' is inferred alias foo2a = foo2!(); -int* foo3(scope int* p) { return p; } // error +int* foo3(scope int* p) @safe { return p; } // error -int* foo4(bool b) +int* foo4(bool b) @safe { int i; int j; diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15191.d b/gcc/testsuite/gdc.test/fail_compilation/test15191.d index 173473a6675..1b3078ff051 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test15191.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test15191.d @@ -1,18 +1,52 @@ /* TEST_OUTPUT: +PERMUTE_ARGS -dip1000 --- -fail_compilation/test15191.d(17): Error: cannot take address of `ref return` of `foo()` in `@safe` function `bar` +fail_compilation/test15191.d(31): Error: returning `&identity(x)` escapes a reference to local variable `x` +fail_compilation/test15191.d(37): Error: returning `&identityPtr(x)` escapes a reference to local variable `x` +fail_compilation/test15191.d(43): Error: cannot take address of `ref return` of `identityPtr()` in `@safe` function `addrOfRefTransitive` +fail_compilation/test15191.d(43): Error: returning `&identityPtr(x)` escapes a reference to local variable `x` --- */ - // https://issues.dlang.org/show_bug.cgi?id=15191 +// https://issues.dlang.org/show_bug.cgi?id=22519 -ref int foo(return ref int s)@safe +@safe: +ref int foo(return ref int s) { return s; } -int* bar(return ref int s) @safe +int* bar(return ref int s) { return &foo(s); } + +ref int identity(ref return int x) {return x;} +ref int* identityPtr(ref return int* x) {return x;} + +int* addrOfRefEscape() +{ + int x; + return &identity(x); +} + +int** addrOfRefSystem() @system +{ + int* x; + return &identityPtr(x); +} + +int** addrOfRefTransitive() +{ + int* x; + return &identityPtr(x); +} + +int gInt; +ref int getGlobalInt() {return gInt;} + +int* addrOfRefGlobal() +{ + return &getGlobalInt(); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17977.d b/gcc/testsuite/gdc.test/fail_compilation/test17977.d new file mode 100644 index 00000000000..ff6bc1c44f4 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test17977.d @@ -0,0 +1,20 @@ +/* +https://issues.dlang.org/show_bug.cgi?id=15399 +REQUIRED_ARGS: -preview=dip1000 +TEST_OUTPUT: +--- +fail_compilation/test17977.d(19): Error: address of variable `__slList3` assigned to `elem` with longer lifetime +--- +*/ + +@safe: +struct List { + int* data; + ~this(); + int* front() return; +} + +void test() +{ + auto elem = List().front; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20023.d b/gcc/testsuite/gdc.test/fail_compilation/test20023.d new file mode 100644 index 00000000000..909e699d3b5 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test20023.d @@ -0,0 +1,16 @@ +// REQUIRED_ARGS: -preview=dip1000 -preview=dip1008 -Ifail_compilation/extra-files +// https://issues.dlang.org/show_bug.cgi?id=20023 +/* +TEST_OUTPUT: +--- +fail_compilation/imports/test20023b.d(8): Error: scope variable `e` may not be returned +fail_compilation/test20023.d(15): Error: template instance `imports.test20023b.threw!()` error instantiating +--- +*/ +import imports.test20023b; + +@safe: +void main() +{ + threw!()(); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/traits_initSymbol.d b/gcc/testsuite/gdc.test/fail_compilation/traits_initSymbol.d new file mode 100644 index 00000000000..94ff80ad551 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/traits_initSymbol.d @@ -0,0 +1,63 @@ +/******************************************** +TEST_OUTPUT: +--- +fail_compilation/traits_initSymbol.d(105): Error: struct / class type expected as argument to __traits(initSymbol) instead of `int` +fail_compilation/traits_initSymbol.d(106): Error: struct / class type expected as argument to __traits(initSymbol) instead of `S[2]` +fail_compilation/traits_initSymbol.d(107): Error: struct / class type expected as argument to __traits(initSymbol) instead of `123` +--- +*/ +#line 100 + +struct S { int i = 4; } + +void test1() +{ + const void[] initInt = __traits(initSymbol, int); + const void[] initArray = __traits(initSymbol, S[2]); + const void[] initValue = __traits(initSymbol, 123); +} + +/******************************************** +TEST_OUTPUT: +--- +fail_compilation/traits_initSymbol.d(203): Error: cannot determine the address of the initializer symbol during CTFE +fail_compilation/traits_initSymbol.d(203): called from here: `(*function () pure nothrow @nogc @safe => S)()` +--- +*/ +#line 200 + +void test2() +{ + enum initLen = (() => __traits(initSymbol, S))(); +} + +/******************************************** +TEST_OUTPUT: +--- +fail_compilation/traits_initSymbol.d(305): Error: struct / class type expected as argument to __traits(initSymbol) instead of `traits_initSymbol.Interface` +--- +*/ +#line 300 + +interface Interface {} + +void test3() +{ + const void[] initInterface = __traits(initSymbol, Interface); +} + +/******************************************** +TEST_OUTPUT: +--- +fail_compilation/traits_initSymbol.d(404): Error: expected 1 arguments for `initSymbol` but had 0 +fail_compilation/traits_initSymbol.d(405): Error: expected 1 arguments for `initSymbol` but had 2 +--- +*/ +#line 400 + + +void test4() +{ + const void[] tmp = __traits(initSymbol); + const void[] tmo = __traits(initSymbol, Interface, S); +} diff --git a/gcc/testsuite/gdc.test/runnable/b19294.d b/gcc/testsuite/gdc.test/runnable/b19294.d new file mode 100644 index 00000000000..5700195ccb8 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/b19294.d @@ -0,0 +1,163 @@ +alias T = MyStruct!float; + +struct MyStruct(U) +{ + U x; + U y; + + this(U xx, U yy) + { + x = xx; + y = yy; + } + + MyStruct!U opBinary(string op)(MyStruct!U z) const + { + alias C = typeof(return); + auto w = C(this.x, this.y); + return w.opOpAssign!(op)(z); + } + + MyStruct!U opBinaryRight(string op)(MyStruct!U z) const + { + return opBinary!(op)(z); + } + + ref MyStruct opOpAssign(string op, U)(const MyStruct!U z) + { + mixin ("x "~op~"= z.x;"); + mixin ("y "~op~"= z.y;"); + return this; + } + + MyStruct!U opBinary(string op, R)(R z) const + if (is(R == int) || is(R == float)) + { + alias C = typeof(return); + auto w = C(this.x, this.y); + return w.opOpAssign!(op)(z); + } + + MyStruct!U opBinaryRight(string op, R)(R z) const + if (is(R == int) || is(R == float)) + { + return opBinary!(op)(z); + } + + ref MyStruct opOpAssign(string op, R)(const R z) + if (is(R == int) || is(R == float)) + { + mixin ("x "~op~"= z;"); + return this; + } +} + +void main() +{ + T c = MyStruct!float(1.0f, 1.0f); + T[] arr = [T(1,1), T(2,2), T(3,3), T(4,4), T(5,5), T(6,6)]; + T[] result = new T[arr.length]; + + // part 2 + + result[0] = c * c; + assert(result[0] == T(1, 1)); + + result[0] = arr[1] * arr[2]; + assert(result[0] == T(6, 6)); + + int[] intarr = [6, 5, 4, 3, 2, 1]; + + result[] = arr[] * arr[]; + assert(result[] == [T(1, 1), T(4, 4), T(9, 9), T(16, 16), T(25, 25), T(36, 36)]); + + result[] = arr[] * 3; + assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]); + result[] = 3 * arr[]; + assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]); + + result[] = arr[]; + result[1..3] = arr[1..3] * 2.0f; + assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(4, 4), T(5, 5), T(6, 6)]); + result[1..3] = 2.0f * arr[1..3]; + assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(4, 4), T(5, 5), T(6, 6)]); + + result[] = arr[]; + result[1..$] = arr[1..$] * 2.0f; + assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(8, 4), T(10, 5), T(12, 6)]); + result[1..$] = 2.0f * arr[1..$]; + assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(8, 4), T(10, 5), T(12, 6)]); + + result[] = intarr[] * arr[]; + assert(result[] == [T(6, 1), T(10, 2), T(12, 3), T(12, 4), T(10, 5), T(6, 6)]); + result[] = arr[] * intarr[]; + assert(result[] == [T(6, 1), T(10, 2), T(12, 3), T(12, 4), T(10, 5), T(6, 6)]); + + result[] = intarr[] * T(2,3); + assert(result[] == [T(12, 3), T(10, 3), T(8, 3), T(6, 3), T(4, 3), T(2, 3)]); + result[] = T(2,3) * intarr[]; + assert(result[] == [T(12, 3), T(10, 3), T(8, 3), T(6, 3), T(4, 3), T(2, 3)]); + + result[] = intarr[] * c; + assert(result[] == [T(6, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]); + result[] = c * intarr[]; + assert(result[] == [T(6, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]); + + result[] = arr[]; + result[1..3] = intarr[1..3] * c; + assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(4, 4), T(5, 5), T(6, 6)]); + result[1..3] = c * intarr[1..3]; + assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(4, 4), T(5, 5), T(6, 6)]); + + result[1..$] = intarr[1..$] * c; + assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]); + result[1..$] = c * intarr[1..$]; + assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]); + + result[] = arr[]; + result[1..3] = intarr[1..3] * arr[1..3]; + assert(result[] == [T(1, 1), T(10, 2), T(12, 3), T(4, 4), T(5, 5), T(6, 6)]); + result[1..3] = arr[1..3] * intarr[1..3]; + assert(result[] == [T(1, 1), T(10, 2), T(12, 3), T(4, 4), T(5, 5), T(6, 6)]); + + result[] = [1,2,3,4,5,6] * c; + assert(result[] == [T(1, 1), T(2, 1), T(3, 1), T(4, 1), T(5, 1), T(6, 1)]); + result[] = c * [1,2,3,4,5,6]; + assert(result[] == [T(1, 1), T(2, 1), T(3, 1), T(4, 1), T(5, 1), T(6, 1)]); + + result[] = arr[] * [1,2,3,4,5,6]; + assert(result[] == [T(1, 1), T(4, 2), T(9, 3), T(16, 4), T(25, 5), T(36, 6)]); + result[] = [1,2,3,4,5,6] * arr[]; + assert(result[] == [T(1, 1), T(4, 2), T(9, 3), T(16, 4), T(25, 5), T(36, 6)]); + + result[] = [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c] * [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c]; + assert(result[] == [T(1, 1), T(4, 1), T(9, 1), T(16, 1), T(25, 1), T(36, 1)]); + + result[] = [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c] * [1,2,3,4,5,6]; + assert(result[] == [T(1, 1), T(4, 1), T(9, 1), T(16, 1), T(25, 1), T(36, 1)]); + result[] = [1,2,3,4,5,6] * [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c]; + assert(result[] == [T(1, 1), T(4, 1), T(9, 1), T(16, 1), T(25, 1), T(36, 1)]); + + result[] = arr[] * c; + assert(result[] == [T(1, 1), T(2, 2), T(3, 3), T(4, 4), T(5, 5), T(6, 6)]); + result[] = c * arr[]; + assert(result[] == [T(1, 1), T(2, 2), T(3, 3), T(4, 4), T(5, 5), T(6, 6)]); + + result[] = c * 3.0f * arr[]; + assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]); + result[] = 3.0f * c * arr[]; + assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]); + + result[] = arr[] * 3.0f * c; + assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]); + // result[] = arr[] * c * 3.0f; //not ok + // assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]); + + result[] = 3.0f * arr[] * c; + assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]); + // result[] = c * arr[] * 3.0f; //not ok + // assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]); + + result[] = c * arr[] * c; + assert(result[] == [T(1, 1), T(2, 2), T(3, 3), T(4, 4), T(5, 5), T(6, 6)]); +} diff --git a/gcc/testsuite/gdc.test/runnable/mars1.d b/gcc/testsuite/gdc.test/runnable/mars1.d index 4f38f4d3322..30aa9503b09 100644 --- a/gcc/testsuite/gdc.test/runnable/mars1.d +++ b/gcc/testsuite/gdc.test/runnable/mars1.d @@ -1,5 +1,5 @@ /* -REQUIRED_ARGS: -mcpu=native -preview=intpromote +REQUIRED_ARGS: -mcpu=native PERMUTE_ARGS: -O -inline -release */ diff --git a/gcc/testsuite/gdc.test/runnable/test15862.d b/gcc/testsuite/gdc.test/runnable/test15862.d new file mode 100644 index 00000000000..87e25600d8b --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test15862.d @@ -0,0 +1,39 @@ +// https://issues.dlang.org/show_bug.cgi?id=15862 + +/* +PERMUTE_ARGS: +REQUIRED_ARGS: -O -release +*/ + + +int* p() pure nothrow {return new int;} +int[] a() pure nothrow {return [0];} +Object o() pure nothrow {return new Object;} + +auto pa() pure nothrow {return new int;} + +void main() +{ + { + int* p1 = p(); + int* p2 = p(); + + if (p1 is p2) assert(0); + + int[] a1 = a(); + int[] a2 = a(); + + if (a1 is a2) assert(0); + + Object o1 = o(); + Object o2 = o(); + + if (o1 is o2) assert(0); + } + { + auto p1 = pa(); + auto p2 = pa(); + + if (p1 is p2) assert(0); + } +} diff --git a/gcc/testsuite/gdc.test/runnable/test21367.d b/gcc/testsuite/gdc.test/runnable/test21367.d new file mode 100644 index 00000000000..96e8d6c66d1 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test21367.d @@ -0,0 +1,47 @@ +// https://issues.dlang.org/show_bug.cgi?id=21367 + +string result = ""; + +struct RCArray(T) +{ + T* data; + this(this) + { + result ~= "A"; + } + ~this() + { + result ~= "B"; + } +} + +struct Variant(T...) +{ + union + { + T payload; + } + this(this) + { + result ~= "C"; + } + + ~this() + { + result ~= "D"; + } +} + +alias Ft = Variant!(RCArray!double, RCArray!int); + +void fun(Ft a) {} +void main() +{ + Ft a; + Ft b = a; +} + +static ~this() +{ + assert(result == "CDD"); +} diff --git a/gcc/testsuite/gdc.test/runnable/test22227.d b/gcc/testsuite/gdc.test/runnable/test22227.d new file mode 100644 index 00000000000..7ef53c37a60 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test22227.d @@ -0,0 +1,16 @@ +// REQUIRED_ARGS: -debug -O -release +// https://issues.dlang.org/show_bug.cgi?id=22277 + +bool secret = false; + +void free(immutable void* x) pure nothrow +{ + debug secret = true; +} + +void main() +{ + free(null); + if (!secret) + assert(0); +} diff --git a/gcc/testsuite/gdc.test/runnable/testOpApply.d b/gcc/testsuite/gdc.test/runnable/testOpApply.d index 7b884e5857c..285365eea82 100644 --- a/gcc/testsuite/gdc.test/runnable/testOpApply.d +++ b/gcc/testsuite/gdc.test/runnable/testOpApply.d @@ -1,4 +1,4 @@ -/* PERMUTE_ARGS: +/* PERMUTE_ARGS: -preview=dip1000 */ // https://issues.dlang.org/show_bug.cgi?id=15624 @@ -140,3 +140,32 @@ void testInverseAttributes() } safe(); } + +// https://issues.dlang.org/show_bug.cgi?id=20907 +Lockstep!() lockstep() +{ + return Lockstep!()(); +} + +struct Lockstep() +{ + int opApply(int delegate(int) callback) @system + { + return 0; + } + + int opApply(int delegate(int) pure nothrow @nogc @safe callback) pure nothrow @nogc @safe + { + return 0; + } +} + +void foo0() +{ + foreach (x; lockstep()) {} +} + +void foo1() +{ + foreach (x; lockstep()) {} +} diff --git a/gcc/testsuite/gdc.test/runnable/testcgelem.d b/gcc/testsuite/gdc.test/runnable/testcgelem.d index b5c7f7d1855..617e3fb11cc 100644 --- a/gcc/testsuite/gdc.test/runnable/testcgelem.d +++ b/gcc/testsuite/gdc.test/runnable/testcgelem.d @@ -1,5 +1,5 @@ /* -REQUIRED_ARGS: -mcpu=native -preview=intpromote +REQUIRED_ARGS: -mcpu=native PERMUTE_ARGS: -O -inline -release */ diff --git a/gcc/testsuite/gdc.test/runnable/testconst.d b/gcc/testsuite/gdc.test/runnable/testconst.d index 5c0e75de60f..764bb1b045e 100644 --- a/gcc/testsuite/gdc.test/runnable/testconst.d +++ b/gcc/testsuite/gdc.test/runnable/testconst.d @@ -2860,9 +2860,11 @@ static assert(is(S7038b == shared)); immutable struct S7038c{ int x; } static assert(is(S7038c == immutable)); -static assert(!is(C7038 == const)); +// https://issues.dlang.org/show_bug.cgi?id=22515 +// Classes fixed for consistency with structs +static assert(is(C7038 == const)); const class C7038{ int x; } -static assert(!is(C7038 == const)); +static assert(is(C7038 == const)); void test7038() { @@ -2871,7 +2873,7 @@ void test7038() static assert(is(typeof(s.x) == const int)); C7038 c; - static assert(!is(typeof(c) == const)); + static assert(is(typeof(c) == const)); static assert(is(typeof(c.x) == const int)); } diff --git a/gcc/testsuite/gdc.test/runnable/traits_initSymbol.d b/gcc/testsuite/gdc.test/runnable/traits_initSymbol.d new file mode 100644 index 00000000000..0385d98c8ff --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/traits_initSymbol.d @@ -0,0 +1,119 @@ +struct Zero +{ + int x; +} + +void testZero() +{ + auto zeroInit = __traits(initSymbol, Zero); + static assert(is(typeof(zeroInit) == const(void[]))); + + assert(zeroInit.ptr is null); + assert(zeroInit.length == Zero.sizeof); +} + +struct NonZero +{ + long x = 1; +} + +void testNonZero() +{ + auto nonZeroInit = __traits(initSymbol, NonZero); + static assert(is(typeof(nonZeroInit) == const(void[]))); + + assert(nonZeroInit.ptr); + assert(nonZeroInit.length == NonZero.sizeof); + assert(cast(const(long[])) nonZeroInit == [1L]); +} + +class C +{ + short x = 123; +} + +void testClass() +{ + auto cInit = __traits(initSymbol, C); + static assert(is(typeof(cInit) == const(void[]))); + + assert(cInit.ptr); + assert(cInit.length == __traits(classInstanceSize, C)); + + scope c = new C; + assert((cast(void*) c)[0 .. cInit.length] == cInit); +} + +struct AlignedStruct +{ + short s = 5; + // 2 byte padding + align(4) char c = 'c'; + // 3 byte padding + int i = 4; + // reduced alignment + align(1) long l = 0xDEADBEEF; +} + +void testAlignedStruct() +{ + auto init = __traits(initSymbol, AlignedStruct); + + assert(init.ptr); + assert(init.length == AlignedStruct.sizeof); + + version (GNU) + AlignedStruct exp = AlignedStruct(); + else + AlignedStruct exp; + assert(init == (cast(void*) &exp)[0 .. AlignedStruct.sizeof]); + +} + +class AlignedClass : C +{ + short s = 5; + // 2 byte padding + align(4) char c = 'c'; + // 3 byte padding + int i = 4; + // reduced alignment + align(1) long l = 0xDEADBEEF; +} + +void testAlignedClass() +{ + auto init = __traits(initSymbol, AlignedClass); + + assert(init.ptr); + assert(init.length == __traits(classInstanceSize, AlignedClass)); + + scope ac = new AlignedClass(); + assert(init == (cast(void*) ac)[0 .. init.length]); +} + +extern (C++) class ExternCppClass +{ + int i = 4; +} + +void testExternCppClass() +{ + auto init = __traits(initSymbol, ExternCppClass); + + assert(init.ptr); + assert(init.length == __traits(classInstanceSize, ExternCppClass)); + + scope ac = new ExternCppClass(); + assert(init == (cast(void*) ac)[0 .. init.length]); +} + +void main() +{ + testZero(); + testNonZero(); + testClass(); + testAlignedStruct(); + testAlignedClass(); + testExternCppClass(); +} diff --git a/gcc/testsuite/gdc.test/runnable/xtest46.d b/gcc/testsuite/gdc.test/runnable/xtest46.d index 20cc225759a..4fe6b00eba7 100644 --- a/gcc/testsuite/gdc.test/runnable/xtest46.d +++ b/gcc/testsuite/gdc.test/runnable/xtest46.d @@ -4903,7 +4903,7 @@ static assert(is(typeof(S5933d.x) == FuncType5933)); class C5933a { auto x() { return 0; } } -static assert(is(typeof(&(new C5933b()).x) == int delegate())); +static assert(is(typeof(&(new C5933b()).x) == int delegate() pure nothrow @nogc @safe)); class C5933b { auto x() { return 0; } } //static assert(is(typeof((new C5933b()).x) == FuncType5933)); @@ -7923,8 +7923,9 @@ void test17349() { static struct S { - int bar(void delegate(ref int*)) { return 1; } - int bar(void delegate(ref const int*)) const { return 2; } + // Specify attribute inferred for dg1/dg2 + int bar(void delegate(ref int*) pure nothrow @nogc @safe) { return 1; } + int bar(void delegate(ref const int*) pure nothrow @nogc @safe) const { return 2; } } void dg1(ref int*) { } diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp new file mode 100644 index 00000000000..f3a9a8552a9 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp @@ -0,0 +1,103 @@ +#include +#include + +class C1 +{ +public: + virtual ~C1(); + + int i; + + int f0(); + int f1(int a); + int f2(int a, int b); + virtual int f3(int a, int b); + int f4(int a, ...); +}; + +C1::~C1() +{ +} + +int C1::f0() +{ + return i; +} + +int C1::f1(int a) +{ + return i + a; +} + +int C1::f2(int a, int b) +{ + return i + a + b; +} + +int C1::f3(int a, int b) +{ + return i + a + b; +} + +int C1::f4(int a, ...) +{ + int r = i + a; + int last = a; + + va_list argp; + va_start(argp, a); + while (last) + { + last = va_arg(argp, int); + r += last; + } + va_end(argp); + return r; +} + +C1 *createC1() +{ + return new C1(); +} + +class C2 +{ +public: + virtual ~C2(); + + int i; + + int f0(); + int f1(int a); + int f2(int a, int b); + virtual int f3(int a, int b); + int f4(int a, ...); +}; + +C2 *createC2(); + +void runCPPTests() +{ + C2 *c2 = createC2(); + c2->i = 100; + assert(c2->f0() == 100); + assert(c2->f1(1) == 101); + assert(c2->f2(20, 3) == 123); + assert(c2->f3(20, 3) == 123); + assert(c2->f4(20, 3, 0) == 123); + + int (C2::*fp0)() = &C2::f0; + int (C2::*fp1)(int) = &C2::f1; + int (C2::*fp2)(int, int) = &C2::f2; + int (C2::*fp3)(int, int) = &C2::f3; +#ifndef __DMC__ + int (C2::*fp4)(int, ...) = &C2::f4; +#endif + assert((c2->*(fp0))() == 100); + assert((c2->*(fp1))(1) == 101); + assert((c2->*(fp2))(20, 3) == 123); + assert((c2->*(fp3))(20, 3) == 123); +#ifndef __DMC__ + assert((c2->*(fp4))(20, 3, 0) == 123); +#endif +} diff --git a/gcc/testsuite/gdc.test/runnable_cxx/test7925.d b/gcc/testsuite/gdc.test/runnable_cxx/test7925.d new file mode 100644 index 00000000000..2f52826bc4f --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable_cxx/test7925.d @@ -0,0 +1,151 @@ +// EXTRA_CPP_SOURCES: cpp7925.cpp + +/* +Exclude -O due to a codegen bug on OSX: +https://issues.dlang.org/show_bug.cgi?id=22556 + +PERMUTE_ARGS(osx): -inline -release -g +*/ + +import core.vararg; + +extern(C++) class C1 +{ +public: + ~this(); + + int i; + + final int f0(); + final int f1(int a); + final int f2(int a, int b); + int f3(int a, int b); + final int f4(int a, ...); +}; + +extern(C++) C1 createC1(); + +extern(C++) class C2 +{ +public: + ~this() + { + } + + int i; + + final int f0() + { + return i; + } + + final int f1(int a) + { + return i + a; + } + + final int f2(int a, int b) + { + return i + a + b; + } + + int f3(int a, int b) + { + return i + a + b; + } + + final int f4(int a, ...) + { + int r = i + a; + int last = a; + + va_list argp; + va_start(argp, a); + while (last) + { + last = va_arg!int(argp); + r += last; + } + va_end(argp); + return r; + } +}; + +extern(C++) C2 createC2() +{ + return new C2; +} + +auto callMember(alias F, Params...)(__traits(parent, F) obj, Params params) +{ + static if(__traits(getFunctionVariadicStyle, F) == "stdarg") + enum varargSuffix = ", ..."; + else + enum varargSuffix = ""; + + static if(is(typeof(&F) R == return) && is(typeof(F) P == __parameters)) + mixin("extern(" ~ __traits(getLinkage, F) ~ ") R delegate(P" ~ varargSuffix ~ ") dg;"); + dg.funcptr = &F; + dg.ptr = cast(void*)obj; + return dg(params); +} + +extern(C++) void runCPPTests(); + +void main() +{ + C1 c1 = createC1(); + c1.i = 100; + assert(c1.f0() == 100); + assert(c1.f1(1) == 101); + assert(c1.f2(20, 3) == 123); + assert(c1.f3(20, 3) == 123); + assert(c1.f4(20, 3, 0) == 123); + + auto dg0 = &c1.f0; + auto dg1 = &c1.f1; + auto dg2 = &c1.f2; + auto dg3 = &c1.f3; + auto dg4 = &c1.f4; + assert(dg0() == 100); + assert(dg1(1) == 101); + assert(dg2(20, 3) == 123); + assert(dg3(20, 3) == 123); + assert(dg4(20, 3, 0) == 123); + + assert(callMember!(C1.f0)(c1) == 100); + assert(callMember!(C1.f1)(c1, 1) == 101); + assert(callMember!(C1.f2)(c1, 20, 3) == 123); + assert(callMember!(C1.f3)(c1, 20, 3) == 123); + assert(callMember!(C1.f4)(c1, 20, 3, 0) == 123); + + int i; + extern(C++) void delegate() lamdba1 = () { + i = 5; + }; + lamdba1(); + assert(i == 5); + + extern(C++) int function(int, int) lamdba2 = (int a, int b) { + return a + b; + }; + assert(lamdba2(3, 4) == 7); + + extern(C++) void delegate(int, ...) lamdba3 = (int a, ...) { + i = a; + int last = a; + + va_list argp; + va_start(argp, a); + while (last) + { + last = va_arg!int(argp); + i += last; + } + va_end(argp); + }; + lamdba3(1000, 200, 30, 4, 0); + assert(i == 1234); + + runCPPTests(); +} diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index d0d3a25ad1e..edb101758b8 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -178c44ff362902af589603767055cfac89215652 +bc58b1e9ea68051af9094651a26313371297b79f 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 44d4fe16be0..224d06e78ca 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -280,9 +280,8 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \ core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \ core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \ core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \ - core/sys/linux/syscalls.d core/sys/linux/termios.d \ - core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \ - core/sys/linux/unistd.d + core/sys/linux/termios.d core/sys/linux/time.d \ + core/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \ core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \ diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 84be8082f7a..bb936ddc1ff 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -367,9 +367,9 @@ am__objects_18 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \ core/sys/linux/sys/procfs.lo core/sys/linux/sys/signalfd.lo \ core/sys/linux/sys/socket.lo core/sys/linux/sys/sysinfo.lo \ core/sys/linux/sys/time.lo core/sys/linux/sys/xattr.lo \ - core/sys/linux/syscalls.lo core/sys/linux/termios.lo \ - core/sys/linux/time.lo core/sys/linux/timerfd.lo \ - core/sys/linux/tipc.lo core/sys/linux/unistd.lo + core/sys/linux/termios.lo core/sys/linux/time.lo \ + core/sys/linux/timerfd.lo core/sys/linux/tipc.lo \ + core/sys/linux/unistd.lo @DRUNTIME_OS_LINUX_TRUE@am__objects_19 = $(am__objects_18) am__objects_20 = core/sys/windows/accctrl.lo \ core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \ @@ -944,9 +944,8 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \ core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \ core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \ core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \ - core/sys/linux/syscalls.d core/sys/linux/termios.d \ - core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \ - core/sys/linux/unistd.d + core/sys/linux/termios.d core/sys/linux/time.d \ + core/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \ core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \ @@ -1675,7 +1674,6 @@ core/sys/linux/sys/socket.lo: core/sys/linux/sys/$(am__dirstamp) core/sys/linux/sys/sysinfo.lo: core/sys/linux/sys/$(am__dirstamp) core/sys/linux/sys/time.lo: core/sys/linux/sys/$(am__dirstamp) core/sys/linux/sys/xattr.lo: core/sys/linux/sys/$(am__dirstamp) -core/sys/linux/syscalls.lo: core/sys/linux/$(am__dirstamp) core/sys/linux/termios.lo: core/sys/linux/$(am__dirstamp) core/sys/linux/time.lo: core/sys/linux/$(am__dirstamp) core/sys/linux/timerfd.lo: core/sys/linux/$(am__dirstamp) diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d index 33ca0ddc7bd..1915fb0844a 100644 --- a/libphobos/libdruntime/core/demangle.d +++ b/libphobos/libdruntime/core/demangle.d @@ -54,13 +54,13 @@ pure @safe: enum AddType { no, yes } - this( return const(char)[] buf_, return char[] dst_ = null ) + this( return scope const(char)[] buf_, return scope char[] dst_ = null ) { this( buf_, AddType.yes, dst_ ); } - this( return const(char)[] buf_, AddType addType_, return char[] dst_ = null ) + this( return scope const(char)[] buf_, AddType addType_, return scope char[] dst_ = null ) { buf = buf_; addType = addType_; @@ -105,7 +105,7 @@ pure @safe: //throw new ParseException( msg ); debug(info) printf( "error: %.*s\n", cast(int) msg.length, msg.ptr ); throw __ctfe ? new ParseException(msg) - : cast(ParseException) cast(void*) typeid(ParseException).initializer; + : cast(ParseException) __traits(initSymbol, ParseException).ptr; } @@ -116,7 +116,7 @@ pure @safe: //throw new OverflowException( msg ); debug(info) printf( "overflow: %.*s\n", cast(int) msg.length, msg.ptr ); - throw cast(OverflowException) cast(void*) typeid(OverflowException).initializer; + throw cast(OverflowException) __traits(initSymbol, OverflowException).ptr; } diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d index 9c8223767e1..ae71f513129 100644 --- a/libphobos/libdruntime/core/internal/array/construction.d +++ b/libphobos/libdruntime/core/internal/array/construction.d @@ -14,16 +14,27 @@ import core.internal.traits : Unqual; /** * Does array initialization (not assignment) from another array of the same element type. * Params: + * to = what array to initialize * from = what data the array should be initialized with + * makeWeaklyPure = unused; its purpose is to prevent the function from becoming + * strongly pure and risk being optimised out * Returns: * The created and initialized array `to` * Bugs: * This function template was ported from a much older runtime hook that bypassed safety, * purity, and throwabilty checks. To prevent breaking existing code, this function template * is temporarily declared `@trusted` until the implementation can be brought up to modern D expectations. + * + * The third parameter is never used, but is necessary in order for the + * function be treated as weakly pure, instead of strongly pure. + * This is needed because constructions such as the one below can be ignored by + * the compiler if `_d_arrayctor` is believed to be pure, because purity would + * mean the call to `_d_arrayctor` has no effects (no side effects and the + * return value is ignored), despite it actually modifying the contents of `a`. + * const S[2] b; + * const S[2] a = b; // this would get lowered to _d_arrayctor(a, b) */ -Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @trusted - if (is(Unqual!T1 == Unqual!T2)) +Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from, char* makeWeaklyPure = null) @trusted { pragma(inline, false); import core.internal.traits : hasElaborateCopyConstructor; @@ -32,14 +43,12 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste import core.stdc.stdint : uintptr_t; debug(PRINTF) import core.stdc.stdio : printf; - debug(PRINTF) printf("_d_arrayctor(to = %p,%d, from = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, T1.tsize); + debug(PRINTF) printf("_d_arrayctor(from = %p,%d) size = %d\n", from.ptr, from.length, T.sizeof); - Tarr1 to = void; + void[] vFrom = (cast(void*) from.ptr)[0..from.length]; + void[] vTo = (cast(void*) to.ptr)[0..to.length]; - void[] vFrom = (cast(void*)from.ptr)[0..from.length]; - void[] vTo = (cast(void*)to.ptr)[0..to.length]; - - // Force `enforceRawArraysConformable` to be `pure` + // Force `enforceRawArraysConformable` to remain weakly `pure` void enforceRawArraysConformable(const char[] action, const size_t elementSize, const void[] a1, const void[] a2) @trusted { @@ -50,9 +59,9 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste (cast(Type)&enforceRawArraysConformableNogc)(action, elementSize, a1, a2, false); } - enforceRawArraysConformable("initialization", T1.sizeof, vFrom, vTo); + enforceRawArraysConformable("initialization", T.sizeof, vFrom, vTo); - static if (hasElaborateCopyConstructor!T1) + static if (hasElaborateCopyConstructor!T) { size_t i; try @@ -66,7 +75,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste */ while (i--) { - auto elem = cast(Unqual!T1*)&to[i]; + auto elem = cast(Unqual!T*) &to[i]; destroy(*elem); } @@ -76,7 +85,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste else { // blit all elements at once - memcpy(cast(void*) to.ptr, from.ptr, to.length * T1.sizeof); + memcpy(cast(void*) to.ptr, from.ptr, to.length * T.sizeof); } return to; @@ -94,7 +103,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste S[4] arr1; S[4] arr2 = [S(0), S(1), S(2), S(3)]; - arr1 = _d_arrayctor!(typeof(arr1))(arr2[]); + _d_arrayctor(arr1[], arr2[]); assert(counter == 4); assert(arr1 == arr2); @@ -117,7 +126,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste S[4] arr1; S[4] arr2 = [S(0), S(1), S(2), S(3)]; - arr1 = _d_arrayctor!(typeof(arr1))(arr2[]); + _d_arrayctor(arr1[], arr2[]); assert(counter == 4); assert(arr1 == arr2); @@ -143,7 +152,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste { Throw[4] a; Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)]; - a = _d_arrayctor!(typeof(a))(b[]); + _d_arrayctor(a[], b[]); } catch (Exception) { @@ -168,7 +177,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste { NoThrow[4] a; NoThrow[4] b = [NoThrow(1), NoThrow(2), NoThrow(3), NoThrow(4)]; - a = _d_arrayctor!(typeof(a))(b[]); + _d_arrayctor(a[], b[]); } catch (Exception) { @@ -274,7 +283,7 @@ void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted { Throw[4] a; Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)]; - a = _d_arrayctor!(typeof(a))(b[]); + _d_arrayctor(a[], b[]); } catch (Exception) { diff --git a/libphobos/libdruntime/core/internal/convert.d b/libphobos/libdruntime/core/internal/convert.d index 2789d2913a7..a876fcc537f 100644 --- a/libphobos/libdruntime/core/internal/convert.d +++ b/libphobos/libdruntime/core/internal/convert.d @@ -801,7 +801,7 @@ const(ubyte)[] toUbyte(T)(const ref T val) if (is(T == delegate) || is(T : V*, V } @trusted pure nothrow @nogc -const(ubyte)[] toUbyte(T)(const ref return scope T val) if (is(T == struct) || is(T == union)) +const(ubyte)[] toUbyte(T)(const return ref scope T val) if (is(T == struct) || is(T == union)) { if (__ctfe) { @@ -826,7 +826,11 @@ const(ubyte)[] toUbyte(T)(const ref return scope T val) if (is(T == struct) || i } else { - return (cast(const(ubyte)*)&val)[0 .. T.sizeof]; + // We're escaping a reference to `val` here because we cannot express + // ref return + scope, it's currently seen as ref + return scope + // https://issues.dlang.org/show_bug.cgi?id=22541 + // Once fixed, the @system lambda should be removed + return (() @system => (cast(const(ubyte)*)&val)[0 .. T.sizeof])(); } } diff --git a/libphobos/libdruntime/core/internal/lifetime.d b/libphobos/libdruntime/core/internal/lifetime.d index 7e9b5f2ad48..a7446debae6 100644 --- a/libphobos/libdruntime/core/internal/lifetime.d +++ b/libphobos/libdruntime/core/internal/lifetime.d @@ -89,44 +89,35 @@ Emplaces T.init. In contrast to `emplaceRef(chunk)`, there are no checks for disabled default constructors etc. +/ -template emplaceInitializer(T) +void emplaceInitializer(T)(scope ref T chunk) nothrow pure @trusted if (!is(T == const) && !is(T == immutable) && !is(T == inout)) { - import core.internal.traits : hasElaborateAssign, Unqual; + import core.internal.traits : hasElaborateAssign; - // Avoid stack allocation by hacking to get to the struct/union init symbol. - static if (is(T == struct) || is(T == union)) + static if (__traits(isZeroInit, T)) { - pragma(mangle, "_D" ~ Unqual!T.mangleof[1..$] ~ "6__initZ") - __gshared extern immutable T initializer; + import core.stdc.string : memset; + memset(cast(void*) &chunk, 0, T.sizeof); } - - void emplaceInitializer(scope ref T chunk) nothrow pure @trusted + else static if (__traits(isScalar, T) || + T.sizeof <= 16 && !hasElaborateAssign!T && __traits(compiles, (){ T chunk; chunk = T.init; })) { - static if (__traits(isZeroInit, T)) - { - import core.stdc.string : memset; - memset(cast(void*) &chunk, 0, T.sizeof); - } - else static if (__traits(isScalar, T) || - T.sizeof <= 16 && !hasElaborateAssign!T && __traits(compiles, (){ T chunk; chunk = T.init; })) - { - chunk = T.init; - } - else static if (__traits(isStaticArray, T)) - { - // For static arrays there is no initializer symbol created. Instead, we emplace elements one-by-one. - foreach (i; 0 .. T.length) - { - emplaceInitializer(chunk[i]); - } - } - else + chunk = T.init; + } + else static if (__traits(isStaticArray, T)) + { + // For static arrays there is no initializer symbol created. Instead, we emplace elements one-by-one. + foreach (i; 0 .. T.length) { - import core.stdc.string : memcpy; - memcpy(cast(void*)&chunk, &initializer, T.sizeof); + emplaceInitializer(chunk[i]); } } + else + { + import core.stdc.string : memcpy; + const initializer = __traits(initSymbol, T); + memcpy(cast(void*)&chunk, initializer.ptr, initializer.length); + } } @safe unittest diff --git a/libphobos/libdruntime/core/internal/string.d b/libphobos/libdruntime/core/internal/string.d index 529fee49436..64a9cc92ffb 100644 --- a/libphobos/libdruntime/core/internal/string.d +++ b/libphobos/libdruntime/core/internal/string.d @@ -119,7 +119,7 @@ char[] signedToTempString(uint radix = 10)(long value, return scope char[] buf) if (neg) { // about to do a slice without a bounds check - auto trustedSlice(return char[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; } + auto trustedSlice(return scope char[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; } r = trustedSlice(r); r[0] = '-'; } diff --git a/libphobos/libdruntime/core/internal/utf.d b/libphobos/libdruntime/core/internal/utf.d index ca0f7f599a6..27bf7f2b905 100644 --- a/libphobos/libdruntime/core/internal/utf.d +++ b/libphobos/libdruntime/core/internal/utf.d @@ -583,7 +583,7 @@ void validate(S)(const scope S s) /* =================== Conversion to UTF8 ======================= */ @safe pure nothrow @nogc -char[] toUTF8(return char[] buf, dchar c) +char[] toUTF8(return scope char[] buf, dchar c) in { assert(isValidDchar(c)); @@ -623,7 +623,7 @@ char[] toUTF8(return char[] buf, dchar c) * Encodes string s into UTF-8 and returns the encoded string. */ @safe pure nothrow -string toUTF8(return string s) +string toUTF8(return scope string s) in { validate(s); @@ -692,7 +692,7 @@ string toUTF8(const scope dchar[] s) /* =================== Conversion to UTF16 ======================= */ @safe pure nothrow @nogc -wchar[] toUTF16(return wchar[] buf, dchar c) +wchar[] toUTF16(return scope wchar[] buf, dchar c) in { assert(isValidDchar(c)); @@ -784,7 +784,7 @@ wptr toUTF16z(const scope char[] s) /** ditto */ @safe pure nothrow -wstring toUTF16(return wstring s) +wstring toUTF16(return scope wstring s) in { validate(s); @@ -864,7 +864,7 @@ dstring toUTF32(const scope wchar[] s) /** ditto */ @safe pure nothrow -dstring toUTF32(return dstring s) +dstring toUTF32(return scope dstring s) in { validate(s); diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d index d93b891226c..b45e95f4226 100644 --- a/libphobos/libdruntime/core/lifetime.d +++ b/libphobos/libdruntime/core/lifetime.d @@ -103,8 +103,8 @@ T emplace(T, Args...)(T chunk, auto ref Args args) " is abstract and it can't be emplaced"); // Initialize the object in its pre-ctor state - enum classSize = __traits(classInstanceSize, T); - (() @trusted => (cast(void*) chunk)[0 .. classSize] = typeid(T).initializer[])(); + const initializer = __traits(initSymbol, T); + (() @trusted { (cast(void*) chunk)[0 .. initializer.length] = initializer[]; })(); static if (isInnerClass!T) { @@ -224,6 +224,31 @@ T emplace(T, Args...)(void[] chunk, auto ref Args args) assert(c.i == 5); } +/// +@betterC +@nogc pure nothrow @system unittest +{ + // works with -betterC too: + + static extern (C++) class C + { + @nogc pure nothrow @safe: + int i = 3; + this(int i) + { + assert(this.i == 3); + this.i = i; + } + int virtualGetI() { return i; } + } + + import core.internal.traits : classInstanceAlignment; + + align(classInstanceAlignment!C) byte[__traits(classInstanceSize, C)] buffer; + C c = emplace!C(buffer[], 42); + assert(c.virtualGetI() == 42); +} + @system unittest { class Outer @@ -1921,7 +1946,7 @@ private void moveImpl(T)(scope ref T target, return scope ref T source) static if (is(T == struct)) { - // Unsafe when compiling without -dip1000 + // Unsafe when compiling without -preview=dip1000 if ((() @trusted => &source == &target)()) return; // Destroy target before overwriting it static if (hasElaborateDestructor!T) target.__xdtor(); @@ -2099,7 +2124,7 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source) static if (is(T == struct)) { - // Unsafe when compiling without -dip1000 + // Unsafe when compiling without -preview=dip1000 assert((() @trusted => &source !is &target)(), "source and target must not be identical"); static if (hasElaborateAssign!T || !isAssignable!T) @@ -2123,12 +2148,7 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source) static if (__traits(isZeroInit, T)) () @trusted { memset(&source, 0, sz); }(); else - { - import core.internal.lifetime : emplaceInitializer; - ubyte[T.sizeof] init = void; - emplaceInitializer(*(() @trusted { return cast(T*)init.ptr; }())); - () @trusted { memcpy(&source, init.ptr, sz); }(); - } + () @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }(); } } else static if (__traits(isStaticArray, T)) @@ -2201,3 +2221,74 @@ pure nothrow @nogc @system unittest static assert(!__traits(compiles, f(ncarray))); f(move(ncarray)); } + +/** + * This is called for a delete statement where the value + * being deleted is a pointer to a struct with a destructor + * but doesn't have an overloaded delete operator. + * + * Params: + * p = pointer to the value to be deleted + */ +void _d_delstruct(T)(ref T *p) +{ + if (p) + { + debug(PRINTF) printf("_d_delstruct(%p)\n", p); + + import core.memory : GC; + + destroy(*p); + GC.free(p); + p = null; + } +} + +@system unittest +{ + int dtors = 0; + struct S { ~this() { ++dtors; } } + + S *s = new S(); + _d_delstruct(s); + + assert(s == null); + assert(dtors == 1); +} + +@system unittest +{ + int innerDtors = 0; + int outerDtors = 0; + + struct Inner { ~this() { ++innerDtors; } } + struct Outer + { + Inner *i1; + Inner *i2; + + this(int x) + { + i1 = new Inner(); + i2 = new Inner(); + } + + ~this() + { + ++outerDtors; + + _d_delstruct(i1); + assert(i1 == null); + + _d_delstruct(i2); + assert(i2 == null); + } + } + + Outer *o = new Outer(0); + _d_delstruct(o); + + assert(o == null); + assert(innerDtors == 2); + assert(outerDtors == 1); +} diff --git a/libphobos/libdruntime/core/memory.d b/libphobos/libdruntime/core/memory.d index 3770c13337c..c4df0f2d0dd 100644 --- a/libphobos/libdruntime/core/memory.d +++ b/libphobos/libdruntime/core/memory.d @@ -270,7 +270,7 @@ extern(C): * reentrant, and must be called once for every call to disable before * automatic collections are enabled. */ - pragma(mangle, "gc_enable") static void enable() nothrow; /* FIXME pure */ + pragma(mangle, "gc_enable") static void enable() nothrow pure; /** @@ -280,7 +280,7 @@ extern(C): * such as during an out of memory condition. This function is reentrant, * but enable must be called once for each call to disable. */ - pragma(mangle, "gc_disable") static void disable() nothrow; /* FIXME pure */ + pragma(mangle, "gc_disable") static void disable() nothrow pure; /** @@ -290,14 +290,14 @@ extern(C): * and then to reclaim free space. This action may need to suspend all * running threads for at least part of the collection process. */ - pragma(mangle, "gc_collect") static void collect() nothrow; /* FIXME pure */ + pragma(mangle, "gc_collect") static void collect() nothrow pure; /** * Indicates that the managed memory space be minimized by returning free * physical memory to the operating system. The amount of free memory * returned depends on the allocator design and on program behavior. */ - pragma(mangle, "gc_minimize") static void minimize() nothrow; /* FIXME pure */ + pragma(mangle, "gc_minimize") static void minimize() nothrow pure; extern(D): @@ -551,7 +551,7 @@ extern(C): * Throws: * `OutOfMemoryError` on allocation failure. */ - pragma(mangle, "gc_realloc") static void* realloc(return void* p, size_t sz, uint ba = 0, const TypeInfo ti = null) pure nothrow; + pragma(mangle, "gc_realloc") static void* realloc(return scope void* p, size_t sz, uint ba = 0, const TypeInfo ti = null) pure nothrow; // https://issues.dlang.org/show_bug.cgi?id=13111 /// @@ -635,7 +635,7 @@ extern(C): * Returns: * The actual number of bytes reserved or zero on error. */ - pragma(mangle, "gc_reserve") static size_t reserve(size_t sz) nothrow; /* FIXME pure */ + pragma(mangle, "gc_reserve") static size_t reserve(size_t sz) nothrow pure; /** @@ -807,7 +807,7 @@ extern(C): * } * --- */ - pragma(mangle, "gc_addRoot") static void addRoot(const void* p) nothrow @nogc; /* FIXME pure */ + pragma(mangle, "gc_addRoot") static void addRoot(const void* p) nothrow @nogc pure; /** @@ -818,7 +818,7 @@ extern(C): * Params: * p = A pointer into a GC-managed memory block or null. */ - pragma(mangle, "gc_removeRoot") static void removeRoot(const void* p) nothrow @nogc; /* FIXME pure */ + pragma(mangle, "gc_removeRoot") static void removeRoot(const void* p) nothrow @nogc pure; /** @@ -849,7 +849,8 @@ extern(C): * // rawMemory will be recognized on collection. * --- */ - pragma(mangle, "gc_addRange") static void addRange(const void* p, size_t sz, const TypeInfo ti = null) @nogc nothrow; /* FIXME pure */ + pragma(mangle, "gc_addRange") + static void addRange(const void* p, size_t sz, const TypeInfo ti = null) @nogc nothrow pure; /** @@ -861,7 +862,7 @@ extern(C): * Params: * p = A pointer to a valid memory address or to null. */ - pragma(mangle, "gc_removeRange") static void removeRange(const void* p) nothrow @nogc; /* FIXME pure */ + pragma(mangle, "gc_removeRange") static void removeRange(const void* p) nothrow @nogc pure; /** diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d index 2f11a663eb5..92f8f705540 100644 --- a/libphobos/libdruntime/core/stdc/stdlib.d +++ b/libphobos/libdruntime/core/stdc/stdlib.d @@ -26,6 +26,10 @@ else version (TVOS) else version (WatchOS) version = Darwin; +version (CRuntime_Glibc) + version = AlignedAllocSupported; +else {} + extern (C): @system: @@ -166,6 +170,12 @@ void* realloc(void* ptr, size_t size); /// void free(void* ptr); +/// since C11 +version (AlignedAllocSupported) +{ + void* aligned_alloc(size_t alignment, size_t size); +} + /// noreturn abort() @safe; /// diff --git a/libphobos/libdruntime/core/stdc/string.d b/libphobos/libdruntime/core/stdc/string.d index a26811ca623..f15ef851909 100644 --- a/libphobos/libdruntime/core/stdc/string.d +++ b/libphobos/libdruntime/core/stdc/string.d @@ -35,31 +35,31 @@ nothrow: @nogc: /// -inout(void)* memchr(return inout void* s, int c, size_t n) pure; +inout(void)* memchr(return scope inout void* s, int c, size_t n) pure; /// int memcmp(scope const void* s1, scope const void* s2, size_t n) pure; /// -void* memcpy(return void* s1, scope const void* s2, size_t n) pure; +void* memcpy(return scope void* s1, scope const void* s2, size_t n) pure; version (Windows) { /// int memicmp(scope const char* s1, scope const char* s2, size_t n); } /// -void* memmove(return void* s1, scope const void* s2, size_t n) pure; +void* memmove(return scope void* s1, scope const void* s2, size_t n) pure; /// -void* memset(return void* s, int c, size_t n) pure; +void* memset(return scope void* s, int c, size_t n) pure; /// -char* strcat(return char* s1, scope const char* s2) pure; +char* strcat(return scope char* s1, scope const char* s2) pure; /// -inout(char)* strchr(return inout(char)* s, int c) pure; +inout(char)* strchr(return scope inout(char)* s, int c) pure; /// int strcmp(scope const char* s1, scope const char* s2) pure; /// int strcoll(scope const char* s1, scope const char* s2); /// -char* strcpy(return char* s1, scope const char* s2) pure; +char* strcpy(return scope char* s1, scope const char* s2) pure; /// size_t strcspn(scope const char* s1, scope const char* s2) pure; /// @@ -70,7 +70,7 @@ char* strerror(int errnum); version (ReturnStrerrorR) { /// - const(char)* strerror_r(int errnum, return char* buf, size_t buflen); + const(char)* strerror_r(int errnum, return scope char* buf, size_t buflen); } // This one is else @@ -80,20 +80,20 @@ else /// size_t strlen(scope const char* s) pure; /// -char* strncat(return char* s1, scope const char* s2, size_t n) pure; +char* strncat(return scope char* s1, scope const char* s2, size_t n) pure; /// int strncmp(scope const char* s1, scope const char* s2, size_t n) pure; /// -char* strncpy(return char* s1, scope const char* s2, size_t n) pure; +char* strncpy(return scope char* s1, scope const char* s2, size_t n) pure; /// -inout(char)* strpbrk(return inout(char)* s1, scope const char* s2) pure; +inout(char)* strpbrk(return scope inout(char)* s1, scope const char* s2) pure; /// -inout(char)* strrchr(return inout(char)* s, int c) pure; +inout(char)* strrchr(return scope inout(char)* s, int c) pure; /// size_t strspn(scope const char* s1, scope const char* s2) pure; /// -inout(char)* strstr(return inout(char)* s1, scope const char* s2) pure; +inout(char)* strstr(return scope inout(char)* s1, scope const char* s2) pure; /// -char* strtok(return char* s1, scope const char* s2); +char* strtok(return scope char* s1, scope const char* s2); /// size_t strxfrm(scope char* s1, scope const char* s2, size_t n); diff --git a/libphobos/libdruntime/core/stdc/wchar_.d b/libphobos/libdruntime/core/stdc/wchar_.d index 6da5618ada6..e8fb94b11e6 100644 --- a/libphobos/libdruntime/core/stdc/wchar_.d +++ b/libphobos/libdruntime/core/stdc/wchar_.d @@ -213,13 +213,13 @@ c_ulong wcstoul(const scope wchar_t* nptr, wchar_t** endptr, int base); ulong wcstoull(const scope wchar_t* nptr, wchar_t** endptr, int base); /// -pure wchar_t* wcscpy(return wchar_t* s1, scope const wchar_t* s2); +pure wchar_t* wcscpy(return scope wchar_t* s1, scope const wchar_t* s2); /// -pure wchar_t* wcsncpy(return wchar_t* s1, scope const wchar_t* s2, size_t n); +pure wchar_t* wcsncpy(return scope wchar_t* s1, scope const wchar_t* s2, size_t n); /// -pure wchar_t* wcscat(return wchar_t* s1, scope const wchar_t* s2); +pure wchar_t* wcscat(return scope wchar_t* s1, scope const wchar_t* s2); /// -pure wchar_t* wcsncat(return wchar_t* s1, scope const wchar_t* s2, size_t n); +pure wchar_t* wcsncat(return scope wchar_t* s1, scope const wchar_t* s2, size_t n); /// pure int wcscmp(scope const wchar_t* s1, scope const wchar_t* s2); /// @@ -229,32 +229,32 @@ pure int wcsncmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n); /// size_t wcsxfrm(scope wchar_t* s1, scope const wchar_t* s2, size_t n); /// -pure inout(wchar_t)* wcschr(return inout(wchar_t)* s, wchar_t c); +pure inout(wchar_t)* wcschr(return scope inout(wchar_t)* s, wchar_t c); /// pure size_t wcscspn(scope const wchar_t* s1, scope const wchar_t* s2); /// -pure inout(wchar_t)* wcspbrk(return inout(wchar_t)* s1, scope const wchar_t* s2); +pure inout(wchar_t)* wcspbrk(return scope inout(wchar_t)* s1, scope const wchar_t* s2); /// -pure inout(wchar_t)* wcsrchr(return inout(wchar_t)* s, wchar_t c); +pure inout(wchar_t)* wcsrchr(return scope inout(wchar_t)* s, wchar_t c); /// pure size_t wcsspn(scope const wchar_t* s1, scope const wchar_t* s2); /// -pure inout(wchar_t)* wcsstr(return inout(wchar_t)* s1, scope const wchar_t* s2); +pure inout(wchar_t)* wcsstr(return scope inout(wchar_t)* s1, scope const wchar_t* s2); /// -wchar_t* wcstok(return wchar_t* s1, scope const wchar_t* s2, wchar_t** ptr); +wchar_t* wcstok(return scope wchar_t* s1, scope const wchar_t* s2, wchar_t** ptr); /// pure size_t wcslen(scope const wchar_t* s); /// -pure inout(wchar_t)* wmemchr(return inout wchar_t* s, wchar_t c, size_t n); +pure inout(wchar_t)* wmemchr(return scope inout wchar_t* s, wchar_t c, size_t n); /// pure int wmemcmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n); /// -pure wchar_t* wmemcpy(return wchar_t* s1, scope const wchar_t* s2, size_t n); +pure wchar_t* wmemcpy(return scope wchar_t* s1, scope const wchar_t* s2, size_t n); /// -pure wchar_t* wmemmove(return wchar_t* s1, scope const wchar_t* s2, size_t n); +pure wchar_t* wmemmove(return scope wchar_t* s1, scope const wchar_t* s2, size_t n); /// -pure wchar_t* wmemset(return wchar_t* s, wchar_t c, size_t n); +pure wchar_t* wmemset(return scope wchar_t* s, wchar_t c, size_t n); /// size_t wcsftime(wchar_t* s, size_t maxsize, const scope wchar_t* format, const scope tm* timeptr); diff --git a/libphobos/libdruntime/core/stdcpp/exception.d b/libphobos/libdruntime/core/stdcpp/exception.d index f920057cd06..d65cd8d1832 100644 --- a/libphobos/libdruntime/core/stdcpp/exception.d +++ b/libphobos/libdruntime/core/stdcpp/exception.d @@ -19,6 +19,8 @@ version (CppRuntime_Gcc) version = GenericBaseException; version (CppRuntime_Clang) version = GenericBaseException; +version (CppRuntime_Sun) + version = GenericBaseException; extern (C++, "std"): @nogc: diff --git a/libphobos/libdruntime/core/sync/mutex.d b/libphobos/libdruntime/core/sync/mutex.d index b153ab9aef0..b848a147460 100644 --- a/libphobos/libdruntime/core/sync/mutex.d +++ b/libphobos/libdruntime/core/sync/mutex.d @@ -189,7 +189,7 @@ class Mutex : if (pthread_mutex_lock(&m_hndl) == 0) return; - SyncError syncErr = cast(SyncError) cast(void*) typeid(SyncError).initializer; + SyncError syncErr = cast(SyncError) __traits(initSymbol, SyncError).ptr; syncErr.msg = "Unable to lock mutex."; throw syncErr; } @@ -227,7 +227,7 @@ class Mutex : if (pthread_mutex_unlock(&m_hndl) == 0) return; - SyncError syncErr = cast(SyncError) cast(void*) typeid(SyncError).initializer; + SyncError syncErr = cast(SyncError) __traits(initSymbol, SyncError).ptr; syncErr.msg = "Unable to unlock mutex."; throw syncErr; } diff --git a/libphobos/libdruntime/core/sys/bionic/string.d b/libphobos/libdruntime/core/sys/bionic/string.d index cbee06c4efe..10a5610ac44 100644 --- a/libphobos/libdruntime/core/sys/bionic/string.d +++ b/libphobos/libdruntime/core/sys/bionic/string.d @@ -14,4 +14,4 @@ extern (C): nothrow: @nogc: -pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); +pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); diff --git a/libphobos/libdruntime/core/sys/darwin/mach/nlist.d b/libphobos/libdruntime/core/sys/darwin/mach/nlist.d index 11e5ced26b7..4d400f207c7 100644 --- a/libphobos/libdruntime/core/sys/darwin/mach/nlist.d +++ b/libphobos/libdruntime/core/sys/darwin/mach/nlist.d @@ -222,7 +222,7 @@ enum */ ubyte GET_LIBRARY_ORDINAL(uint n_desc) @safe { return ((n_desc) >> 8) & 0xff; } /// Ditto -ref ushort SET_LIBRARY_ORDINAL(return scope ref ushort n_desc, uint ordinal) @safe +ref ushort SET_LIBRARY_ORDINAL(return ref ushort n_desc, uint ordinal) @safe { return n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8)); } diff --git a/libphobos/libdruntime/core/sys/darwin/string.d b/libphobos/libdruntime/core/sys/darwin/string.d index bd65fde27bc..ac988b58f0d 100644 --- a/libphobos/libdruntime/core/sys/darwin/string.d +++ b/libphobos/libdruntime/core/sys/darwin/string.d @@ -27,5 +27,5 @@ nothrow: static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL) { // ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); - pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); + pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); } diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/string.d b/libphobos/libdruntime/core/sys/dragonflybsd/string.d index b64178f6562..4b8422748b6 100644 --- a/libphobos/libdruntime/core/sys/dragonflybsd/string.d +++ b/libphobos/libdruntime/core/sys/dragonflybsd/string.d @@ -17,6 +17,6 @@ nothrow: static if (__BSD_VISIBLE) { - pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); + pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); } diff --git a/libphobos/libdruntime/core/sys/freebsd/string.d b/libphobos/libdruntime/core/sys/freebsd/string.d index 3602ea8e86b..459e9115878 100644 --- a/libphobos/libdruntime/core/sys/freebsd/string.d +++ b/libphobos/libdruntime/core/sys/freebsd/string.d @@ -17,5 +17,5 @@ nothrow: static if (__BSD_VISIBLE) { - pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); + pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); } diff --git a/libphobos/libdruntime/core/sys/linux/string.d b/libphobos/libdruntime/core/sys/linux/string.d index 1b2c8d86a4a..e3c94cf6a8a 100644 --- a/libphobos/libdruntime/core/sys/linux/string.d +++ b/libphobos/libdruntime/core/sys/linux/string.d @@ -18,5 +18,5 @@ nothrow: static if (__USE_GNU) { - pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); + pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); } diff --git a/libphobos/libdruntime/core/sys/linux/syscalls.d b/libphobos/libdruntime/core/sys/linux/syscalls.d deleted file mode 100644 index 8c653719317..00000000000 --- a/libphobos/libdruntime/core/sys/linux/syscalls.d +++ /dev/null @@ -1,745 +0,0 @@ -module core.sys.linux.syscalls; - -version (linux): -extern (C): -@system: -nothrow: -@nogc: - -import core.stdc.config : c_long; - -version (CoreDdoc) -{ - /// Linux system call number from Linux's asm/unistd.h - enum SystemCall : c_long; -} -else version (X86_64) -{ - // https://github.com/torvalds/linux/blob/v4.14/arch/sh/include/uapi/asm/unistd_64.h - // https://github.com/torvalds/linux/blob/v4.14/arch/x86/entry/syscalls/syscall_64.tbl - enum SystemCall : c_long - { - read = 0, - write = 1, - open = 2, - close = 3, - stat = 4, - fstat = 5, - lstat = 6, - poll = 7, - lseek = 8, - mmap = 9, - mprotect = 10, - munmap = 11, - brk = 12, - rt_sigaction = 13, - rt_sigprocmask = 14, - rt_sigreturn = 15, - ioctl = 16, - pread64 = 17, - pwrite64 = 18, - readv = 19, - writev = 20, - access = 21, - pipe = 22, - select = 23, - sched_yield = 24, - mremap = 25, - msync = 26, - mincore = 27, - madvise = 28, - shmget = 29, - shmat = 30, - shmctl = 31, - dup = 32, - dup2 = 33, - pause = 34, - nanosleep = 35, - getitimer = 36, - alarm = 37, - setitimer = 38, - getpid = 39, - sendfile = 40, - socket = 41, - connect = 42, - accept = 43, - sendto = 44, - recvfrom = 45, - sendmsg = 46, - recvmsg = 47, - shutdown = 48, - bind = 49, - listen = 50, - getsockname = 51, - getpeername = 52, - socketpair = 53, - setsockopt = 54, - getsockopt = 55, - clone = 56, - fork = 57, - vfork = 58, - execve = 59, - exit = 60, - wait4 = 61, - kill = 62, - uname = 63, - semget = 64, - semop = 65, - semctl = 66, - shmdt = 67, - msgget = 68, - msgsnd = 69, - msgrcv = 70, - msgctl = 71, - fcntl = 72, - flock = 73, - fsync = 74, - fdatasync = 75, - truncate = 76, - ftruncate = 77, - getdents = 78, - getcwd = 79, - chdir = 80, - fchdir = 81, - rename = 82, - mkdir = 83, - rmdir = 84, - creat = 85, - link = 86, - unlink = 87, - symlink = 88, - readlink = 89, - chmod = 90, - fchmod = 91, - chown = 92, - fchown = 93, - lchown = 94, - umask = 95, - gettimeofday = 96, - getrlimit = 97, - getrusage = 98, - sysinfo = 99, - times = 100, - ptrace = 101, - getuid = 102, - syslog = 103, - getgid = 104, - setuid = 105, - setgid = 106, - geteuid = 107, - getegid = 108, - setpgid = 109, - getppid = 110, - getpgrp = 111, - setsid = 112, - setreuid = 113, - setregid = 114, - getgroups = 115, - setgroups = 116, - setresuid = 117, - getresuid = 118, - setresgid = 119, - getresgid = 120, - getpgid = 121, - setfsuid = 122, - setfsgid = 123, - getsid = 124, - capget = 125, - capset = 126, - rt_sigpending = 127, - rt_sigtimedwait = 128, - rt_sigqueueinfo = 129, - rt_sigsuspend = 130, - sigaltstack = 131, - utime = 132, - mknod = 133, - uselib = 134, - personality = 135, - ustat = 136, - statfs = 137, - fstatfs = 138, - sysfs = 139, - getpriority = 140, - setpriority = 141, - sched_setparam = 142, - sched_getparam = 143, - sched_setscheduler = 144, - sched_getscheduler = 145, - sched_get_priority_max = 146, - sched_get_priority_min = 147, - sched_rr_get_interval = 148, - mlock = 149, - munlock = 150, - mlockall = 151, - munlockall = 152, - vhangup = 153, - modify_ldt = 154, - pivot_root = 155, - _sysctl = 156, - prctl = 157, - arch_prctl = 158, - adjtimex = 159, - setrlimit = 160, - chroot = 161, - sync = 162, - acct = 163, - settimeofday = 164, - mount = 165, - umount2 = 166, - swapon = 167, - swapoff = 168, - reboot = 169, - sethostname = 170, - setdomainname = 171, - iopl = 172, - ioperm = 173, - create_module = 174, - init_module = 175, - delete_module = 176, - get_kernel_syms = 177, - query_module = 178, - quotactl = 179, - nfsservctl = 180, - getpmsg = 181, - putpmsg = 182, - afs_syscall = 183, - tuxcall = 184, - security = 185, - gettid = 186, - readahead = 187, - setxattr = 188, - lsetxattr = 189, - fsetxattr = 190, - getxattr = 191, - lgetxattr = 192, - fgetxattr = 193, - listxattr = 194, - llistxattr = 195, - flistxattr = 196, - removexattr = 197, - lremovexattr = 198, - fremovexattr = 199, - tkill = 200, - time = 201, - futex = 202, - sched_setaffinity = 203, - sched_getaffinity = 204, - set_thread_area = 205, - io_setup = 206, - io_destroy = 207, - io_getevents = 208, - io_submit = 209, - io_cancel = 210, - get_thread_area = 211, - lookup_dcookie = 212, - epoll_create = 213, - epoll_ctl_old = 214, - epoll_wait_old = 215, - remap_file_pages = 216, - getdents64 = 217, - set_tid_address = 218, - restart_syscall = 219, - semtimedop = 220, - fadvise64 = 221, - timer_create = 222, - timer_settime = 223, - timer_gettime = 224, - timer_getoverrun = 225, - timer_delete = 226, - clock_settime = 227, - clock_gettime = 228, - clock_getres = 229, - clock_nanosleep = 230, - exit_group = 231, - epoll_wait = 232, - epoll_ctl = 233, - tgkill = 234, - utimes = 235, - vserver = 236, - mbind = 237, - set_mempolicy = 238, - get_mempolicy = 239, - mq_open = 240, - mq_unlink = 241, - mq_timedsend = 242, - mq_timedreceive = 243, - mq_notify = 244, - mq_getsetattr = 245, - kexec_load = 246, - waitid = 247, - add_key = 248, - request_key = 249, - keyctl = 250, - ioprio_set = 251, - ioprio_get = 252, - inotify_init = 253, - inotify_add_watch = 254, - inotify_rm_watch = 255, - migrate_pages = 256, - openat = 257, - mkdirat = 258, - mknodat = 259, - fchownat = 260, - futimesat = 261, - newfstatat = 262, - unlinkat = 263, - renameat = 264, - linkat = 265, - symlinkat = 266, - readlinkat = 267, - fchmodat = 268, - faccessat = 269, - pselect6 = 270, - ppoll = 271, - unshare = 272, - set_robust_list = 273, - get_robust_list = 274, - splice = 275, - tee = 276, - sync_file_range = 277, - vmsplice = 278, - move_pages = 279, - utimensat = 280, - epoll_pwait = 281, - signalfd = 282, - timerfd_create = 283, - eventfd = 284, - fallocate = 285, - timerfd_settime = 286, - timerfd_gettime = 287, - accept4 = 288, - signalfd4 = 289, - eventfd2 = 290, - epoll_create1 = 291, - dup3 = 292, - pipe2 = 293, - inotify_init1 = 294, - preadv = 295, - pwritev = 296, - rt_tgsigqueueinfo = 297, - perf_event_open = 298, - recvmmsg = 299, - fanotify_init = 300, - fanotify_mark = 301, - prlimit64 = 302, - name_to_handle_at = 303, - open_by_handle_at = 304, - clock_adjtime = 305, - syncfs = 306, - sendmmsg = 307, - setns = 308, - getcpu = 309, - process_vm_readv = 310, - process_vm_writev = 311, - kcmp = 312, - finit_module = 313, - sched_setattr = 314, - sched_getattr = 315, - renameat2 = 316, - seccomp = 317, - getrandom = 318, - memfd_create = 319, - kexec_file_load = 320, - bpf = 321, - execveat = 322, - userfaultfd = 323, - membarrier = 324, - mlock2 = 325, - copy_file_range = 326, - preadv2 = 327, - pwritev2 = 328, - pkey_mprotect = 329, - pkey_alloc = 330, - pkey_free = 331, - statx = 332, - } -} -else version (X86) -{ - // https://github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_32.tbl - // https://github.com/torvalds/linux/blob/v4.14/arch/sh/include/uapi/asm/unistd_32.h - enum SystemCall : c_long - { - restart_syscall = 0, - exit = 1, - fork = 2, - read = 3, - write = 4, - open = 5, - close = 6, - waitpid = 7, - creat = 8, - link = 9, - unlink = 10, - execve = 11, - chdir = 12, - time = 13, - mknod = 14, - chmod = 15, - lchown = 16, - break_ = 17, - oldstat = 18, - lseek = 19, - getpid = 20, - mount = 21, - umount = 22, - setuid = 23, - getuid = 24, - stime = 25, - ptrace = 26, - alarm = 27, - oldfstat = 28, - pause = 29, - utime = 30, - stty = 31, - gtty = 32, - access = 33, - nice = 34, - ftime = 35, - sync = 36, - kill = 37, - rename = 38, - mkdir = 39, - rmdir = 40, - dup = 41, - pipe = 42, - times = 43, - prof = 44, - brk = 45, - setgid = 46, - getgid = 47, - signal = 48, - geteuid = 49, - getegid = 50, - acct = 51, - umount2 = 52, - lock = 53, - ioctl = 54, - fcntl = 55, - mpx = 56, - setpgid = 57, - ulimit = 58, - oldolduname = 59, - umask = 60, - chroot = 61, - ustat = 62, - dup2 = 63, - getppid = 64, - getpgrp = 65, - setsid = 66, - sigaction = 67, - sgetmask = 68, - ssetmask = 69, - setreuid = 70, - setregid = 71, - sigsuspend = 72, - sigpending = 73, - sethostname = 74, - setrlimit = 75, - getrlimit = 76, - getrusage = 77, - gettimeofday = 78, - settimeofday = 79, - getgroups = 80, - setgroups = 81, - select = 82, - symlink = 83, - oldlstat = 84, - readlink = 85, - uselib = 86, - swapon = 87, - reboot = 88, - readdir = 89, - mmap = 90, - munmap = 91, - truncate = 92, - ftruncate = 93, - fchmod = 94, - fchown = 95, - getpriority = 96, - setpriority = 97, - profil = 98, - statfs = 99, - fstatfs = 100, - ioperm = 101, - socketcall = 102, - syslog = 103, - setitimer = 104, - getitimer = 105, - stat = 106, - lstat = 107, - fstat = 108, - olduname = 109, - iopl = 110, - vhangup = 111, - idle = 112, - vm86old = 113, - wait4 = 114, - swapoff = 115, - sysinfo = 116, - ipc = 117, - fsync = 118, - sigreturn = 119, - clone = 120, - setdomainname = 121, - uname = 122, - modify_ldt = 123, - adjtimex = 124, - mprotect = 125, - sigprocmask = 126, - create_module = 127, - init_module = 128, - delete_module = 129, - get_kernel_syms = 130, - quotactl = 131, - getpgid = 132, - fchdir = 133, - bdflush = 134, - sysfs = 135, - personality = 136, - afs_syscall = 137, - setfsuid = 138, - setfsgid = 139, - _llseek = 140, - getdents = 141, - _newselect = 142, - flock = 143, - msync = 144, - readv = 145, - writev = 146, - getsid = 147, - fdatasync = 148, - _sysctl = 149, - mlock = 150, - munlock = 151, - mlockall = 152, - munlockall = 153, - sched_setparam = 154, - sched_getparam = 155, - sched_setscheduler = 156, - sched_getscheduler = 157, - sched_yield = 158, - sched_get_priority_max = 159, - sched_get_priority_min = 160, - sched_rr_get_interval = 161, - nanosleep = 162, - mremap = 163, - setresuid = 164, - getresuid = 165, - vm86 = 166, - query_module = 167, - poll = 168, - nfsservctl = 169, - setresgid = 170, - getresgid = 171, - prctl = 172, - rt_sigreturn = 173, - rt_sigaction = 174, - rt_sigprocmask = 175, - rt_sigpending = 176, - rt_sigtimedwait = 177, - rt_sigqueueinfo = 178, - rt_sigsuspend = 179, - pread64 = 180, - pwrite64 = 181, - chown = 182, - getcwd = 183, - capget = 184, - capset = 185, - sigaltstack = 186, - sendfile = 187, - getpmsg = 188, - putpmsg = 189, - vfork = 190, - ugetrlimit = 191, - mmap2 = 192, - truncate64 = 193, - ftruncate64 = 194, - stat64 = 195, - lstat64 = 196, - fstat64 = 197, - lchown32 = 198, - getuid32 = 199, - getgid32 = 200, - geteuid32 = 201, - getegid32 = 202, - setreuid32 = 203, - setregid32 = 204, - getgroups32 = 205, - setgroups32 = 206, - fchown32 = 207, - setresuid32 = 208, - getresuid32 = 209, - setresgid32 = 210, - getresgid32 = 211, - chown32 = 212, - setuid32 = 213, - setgid32 = 214, - setfsuid32 = 215, - setfsgid32 = 216, - pivot_root = 217, - mincore = 218, - madvise = 219, - getdents64 = 220, - fcntl64 = 221, - gettid = 224, - readahead = 225, - setxattr = 226, - lsetxattr = 227, - fsetxattr = 228, - getxattr = 229, - lgetxattr = 230, - fgetxattr = 231, - listxattr = 232, - llistxattr = 233, - flistxattr = 234, - removexattr = 235, - lremovexattr = 236, - fremovexattr = 237, - tkill = 238, - sendfile64 = 239, - futex = 240, - sched_setaffinity = 241, - sched_getaffinity = 242, - set_thread_area = 243, - get_thread_area = 244, - io_setup = 245, - io_destroy = 246, - io_getevents = 247, - io_submit = 248, - io_cancel = 249, - fadvise64 = 250, - exit_group = 252, - lookup_dcookie = 253, - epoll_create = 254, - epoll_ctl = 255, - epoll_wait = 256, - remap_file_pages = 257, - set_tid_address = 258, - timer_create = 259, - timer_settime = 260, - timer_gettime = 261, - timer_getoverrun = 262, - timer_delete = 263, - clock_settime = 264, - clock_gettime = 265, - clock_getres = 266, - clock_nanosleep = 267, - statfs64 = 268, - fstatfs64 = 269, - tgkill = 270, - utimes = 271, - fadvise64_64 = 272, - vserver = 273, - mbind = 274, - get_mempolicy = 275, - set_mempolicy = 276, - mq_open = 277, - mq_unlink = 278, - mq_timedsend = 279, - mq_timedreceive = 280, - mq_notify = 281, - mq_getsetattr = 282, - kexec_load = 283, - waitid = 284, - add_key = 286, - request_key = 287, - keyctl = 288, - ioprio_set = 289, - ioprio_get = 290, - inotify_init = 291, - inotify_add_watch = 292, - inotify_rm_watch = 293, - migrate_pages = 294, - openat = 295, - mkdirat = 296, - mknodat = 297, - fchownat = 298, - futimesat = 299, - fstatat64 = 300, - unlinkat = 301, - renameat = 302, - linkat = 303, - symlinkat = 304, - readlinkat = 305, - fchmodat = 306, - faccessat = 307, - pselect6 = 308, - ppoll = 309, - unshare = 310, - set_robust_list = 311, - get_robust_list = 312, - splice = 313, - sync_file_range = 314, - tee = 315, - vmsplice = 316, - move_pages = 317, - getcpu = 318, - epoll_pwait = 319, - utimensat = 320, - signalfd = 321, - timerfd_create = 322, - eventfd = 323, - fallocate = 324, - timerfd_settime = 325, - timerfd_gettime = 326, - signalfd4 = 327, - eventfd2 = 328, - epoll_create1 = 329, - dup3 = 330, - pipe2 = 331, - inotify_init1 = 332, - preadv = 333, - pwritev = 334, - rt_tgsigqueueinfo = 335, - perf_event_open = 336, - recvmmsg = 337, - fanotify_init = 338, - fanotify_mark = 339, - prlimit64 = 340, - name_to_handle_at = 341, - open_by_handle_at = 342, - clock_adjtime = 343, - syncfs = 344, - sendmmsg = 345, - setns = 346, - process_vm_readv = 347, - process_vm_writev = 348, - kcmp = 349, - finit_module = 350, - sched_setattr = 351, - sched_getattr = 352, - renameat2 = 353, - seccomp = 354, - getrandom = 355, - memfd_create = 356, - bpf = 357, - execveat = 358, - socket = 359, - socketpair = 360, - bind = 361, - connect = 362, - listen = 363, - accept4 = 364, - getsockopt = 365, - setsockopt = 366, - getsockname = 367, - getpeername = 368, - sendto = 369, - sendmsg = 370, - recvfrom = 371, - recvmsg = 372, - shutdown = 373, - userfaultfd = 374, - membarrier = 375, - mlock2 = 376, - copy_file_range = 377, - preadv2 = 378, - pwritev2 = 379, - pkey_mprotect = 380, - pkey_alloc = 381, - pkey_free = 382, - statx = 383, - arch_prctl = 384, - } -} diff --git a/libphobos/libdruntime/core/sys/linux/unistd.d b/libphobos/libdruntime/core/sys/linux/unistd.d index 1ef16c12689..48457467005 100644 --- a/libphobos/libdruntime/core/sys/linux/unistd.d +++ b/libphobos/libdruntime/core/sys/linux/unistd.d @@ -1,20 +1,16 @@ module core.sys.linux.unistd; +public import core.sys.posix.unistd; + version (linux): -extern (C): +extern(C): nothrow: @system: -@nogc: - -public import core.sys.posix.unistd; -public import core.sys.linux.syscalls : SystemCall; -import core.stdc.config : c_long; // Additional seek constants for sparse file handling // from Linux's unistd.h, stdio.h, and linux/fs.h // (see http://man7.org/linux/man-pages/man2/lseek.2.html) -enum -{ +enum { /// Offset is relative to the next location containing data SEEK_DATA = 3, /// Offset is relative to the next hole (or EOF if file is not sparse) @@ -26,17 +22,3 @@ char* getpass(const(char)* prompt); // Exit all threads in a process void exit_group(int status); - -/** -Invoke system call specified by number, passing it the remaining arguments. -This is completely system-dependent, and not often useful. - -In Unix, `syscall' sets `errno' for all errors and most calls return -1 -for errors; in many systems you cannot pass arguments or get return -values for all system calls (`pipe', `fork', and `getppid' typically -among them). - -In Mach, all system calls take normal arguments and always return an -error code (zero for success). -*/ -c_long syscall(SystemCall number, ...) @nogc nothrow; diff --git a/libphobos/libdruntime/core/sys/netbsd/string.d b/libphobos/libdruntime/core/sys/netbsd/string.d index ab9ced80cf1..f1281da275b 100644 --- a/libphobos/libdruntime/core/sys/netbsd/string.d +++ b/libphobos/libdruntime/core/sys/netbsd/string.d @@ -17,5 +17,5 @@ nothrow: static if (_NETBSD_SOURCE) { - pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); + pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); } diff --git a/libphobos/libdruntime/core/sys/openbsd/string.d b/libphobos/libdruntime/core/sys/openbsd/string.d index 131e67727e8..4480c94ac37 100644 --- a/libphobos/libdruntime/core/sys/openbsd/string.d +++ b/libphobos/libdruntime/core/sys/openbsd/string.d @@ -18,7 +18,7 @@ nothrow: static if (__BSD_VISIBLE) { void explicit_bzero(void*, size_t); - pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); + pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen); void* memrchr(scope const void*, int, size_t); size_t strlcat(char*, scope const char*, size_t); size_t strlcpy(char*, scope const char*, size_t); diff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d index 0dce8c53f31..32e51561562 100644 --- a/libphobos/libdruntime/core/sys/posix/signal.d +++ b/libphobos/libdruntime/core/sys/posix/signal.d @@ -513,15 +513,21 @@ else version (DragonFlyBSD) } else version (Solaris) { + //SIGABRT (defined in core.stdc.signal) enum SIGALRM = 14; enum SIGBUS = 10; enum SIGCHLD = 18; enum SIGCONT = 25; + //SIGFPE (defined in core.stdc.signal) enum SIGHUP = 1; + //SIGILL (defined in core.stdc.signal) + //SIGINT (defined in core.stdc.signal) enum SIGKILL = 9; enum SIGPIPE = 13; enum SIGQUIT = 3; + //SIGSEGV (defined in core.stdc.signal) enum SIGSTOP = 23; + //SIGTERM (defined in core.stdc.signal) enum SIGTSTP = 24; enum SIGTTIN = 26; enum SIGTTOU = 27; @@ -1339,6 +1345,10 @@ else version (Solaris) uint[4] __bits; } + enum SIG_BLOCK = 1; + enum SIG_UNBLOCK = 2; + enum SIG_SETMASK = 3; + struct siginfo_t { int si_signo; @@ -1427,6 +1437,18 @@ else version (Solaris) ___data __data; } + enum SI_NOINFO = 32767; + enum SI_DTRACE = 2050; + enum SI_RCTL = 2049; + enum SI_USER = 0; + enum SI_LWP = -1; + enum SI_QUEUE = -2; + enum SI_TIMER = -3; + enum SI_ASYNCIO = -4; + enum SI_MESGQ = -5; + + enum SIGIO = SIGPOLL; + int kill(pid_t, int); int sigaction(int, const scope sigaction_t*, sigaction_t*); int sigaddset(sigset_t*, int); @@ -2833,9 +2855,9 @@ else version (Solaris) enum SIGPROF = 29; enum SIGSYS = 12; enum SIGTRAP = 5; - enum SIGVTALRM = 31; + enum SIGVTALRM = 28; enum SIGXCPU = 30; - enum SIGXFSZ = 25; + enum SIGXFSZ = 31; enum { diff --git a/libphobos/libdruntime/core/sys/posix/string.d b/libphobos/libdruntime/core/sys/posix/string.d index b9e1c1c88c2..79d25624e2a 100644 --- a/libphobos/libdruntime/core/sys/posix/string.d +++ b/libphobos/libdruntime/core/sys/posix/string.d @@ -31,11 +31,11 @@ public import core.sys.posix.locale : locale_t; public import core.stdc.string; /// Copy string until character found -void* memccpy(return void* dst, scope const void* src, int c, size_t n) pure; +void* memccpy(return scope void* dst, scope const void* src, int c, size_t n) pure; /// Copy string (including terminating '\0') -char* stpcpy(return char* dst, scope const char* src) pure; +char* stpcpy(return scope char* dst, scope const char* src) pure; /// Ditto -char* stpncpy(return char* dst, const char* src, size_t len) pure; +char* stpncpy(return scope char* dst, const char* src, size_t len) pure; /// Compare strings according to current collation int strcoll_l(scope const char* s1, scope const char* s2, locale_t locale); /// @@ -47,6 +47,6 @@ size_t strnlen(scope const char* str, size_t maxlen) pure; /// System signal messages const(char)* strsignal(int); /// Isolate sequential tokens in a null-terminated string -char* strtok_r(return char* str, scope const char* sep, char** context) pure; +char* strtok_r(return scope char* str, scope const char* sep, char** context) pure; /// Transform a string under locale size_t strxfrm_l(char* s1, scope const char* s2, size_t n, locale_t locale); diff --git a/libphobos/libdruntime/core/sys/posix/sys/socket.d b/libphobos/libdruntime/core/sys/posix/sys/socket.d index de51c6a4746..6e0cfd3ac3d 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/socket.d +++ b/libphobos/libdruntime/core/sys/posix/sys/socket.d @@ -217,7 +217,7 @@ version (CRuntime_Glibc) } else { - extern (D) inout(ubyte)* CMSG_DATA( return inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); } + extern (D) inout(ubyte)* CMSG_DATA( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); } } private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc; diff --git a/libphobos/libdruntime/core/sys/solaris/sys/elf.d b/libphobos/libdruntime/core/sys/solaris/sys/elf.d index 7da26317d35..7a46d520cc3 100644 --- a/libphobos/libdruntime/core/sys/solaris/sys/elf.d +++ b/libphobos/libdruntime/core/sys/solaris/sys/elf.d @@ -393,7 +393,7 @@ enum SHF_LINK_ORDER = 0x80; enum SHF_OS_NONCONFORMING = 0x100; enum SHF_GROUP = 0x200; enum SHF_TLS = 0x400; - +enum SHF_COMPRESSED = 0x800; enum SHF_MASKOS = 0x0ff00000; enum SHF_MASKPROC = 0xf0000000; @@ -656,3 +656,6 @@ enum NT_ZONENAME = 21; enum NT_FDINFO = 22; enum NT_SPYMASTER = 23; enum NT_NUM = 23; + +enum SHF_ORDERED = 0x40000000; +enum SHF_EXCLUDE = 0x80000000; diff --git a/libphobos/libdruntime/core/sys/solaris/sys/elf_386.d b/libphobos/libdruntime/core/sys/solaris/sys/elf_386.d index 0c8198513d0..9927b64aec9 100644 --- a/libphobos/libdruntime/core/sys/solaris/sys/elf_386.d +++ b/libphobos/libdruntime/core/sys/solaris/sys/elf_386.d @@ -52,9 +52,6 @@ enum R_386_NUM = 39; enum ELF_386_MAXPGSZ = 0x10000; -enum SHF_ORDERED = 0x40000000; -enum SHF_EXCLUDE = 0x80000000; - enum SHN_BEFORE = 0xff00; enum SHN_AFTER = 0xff01; diff --git a/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d b/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d index 81d02347598..e43bd405b8a 100644 --- a/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d +++ b/libphobos/libdruntime/core/sys/solaris/sys/elf_SPARC.d @@ -118,9 +118,6 @@ enum ELF_SPARCV9_MAXPGSZ = 0x100000; enum SHT_SPARC_GOTDATA = 0x70000000; -enum SHF_ORDERED = 0x40000000; -enum SHF_EXCLUDE = 0x80000000; - enum SHN_BEFORE = 0xff00; enum SHN_AFTER = 0xff01; diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d index 9848fb99115..96698e8f0f9 100644 --- a/libphobos/libdruntime/core/sys/windows/dbghelp.d +++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d @@ -39,7 +39,8 @@ extern(Windows) alias BOOL function(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, IMAGEHLP_SYMBOLA64 *Symbol) SymGetSymFromAddr64Func; alias DWORD function(PCSTR DecoratedName, PSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc; alias DWORD64 function(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) SymLoadModule64Func; - alias BOOL function(HANDLE HProcess, PTSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc; + alias BOOL function(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc; + alias BOOL function(HANDLE hProcess, PCSTR SearchPath) SymSetSearchPathFunc; alias BOOL function(HANDLE hProcess, DWORD64 Address) SymUnloadModule64Func; alias BOOL function(HANDLE hProcess, ULONG ActionCode, ulong CallbackContext, ulong UserContext) PSYMBOL_REGISTERED_CALLBACK64; alias BOOL function(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ulong UserContext) SymRegisterCallback64Func; @@ -61,6 +62,7 @@ struct DbgHelp UnDecorateSymbolNameFunc UnDecorateSymbolName; SymLoadModule64Func SymLoadModule64; SymGetSearchPathFunc SymGetSearchPath; + SymSetSearchPathFunc SymSetSearchPath; SymUnloadModule64Func SymUnloadModule64; SymRegisterCallback64Func SymRegisterCallback64; ImagehlpApiVersionFunc ImagehlpApiVersion; @@ -84,6 +86,7 @@ struct DbgHelp sm_inst.UnDecorateSymbolName = cast(UnDecorateSymbolNameFunc) GetProcAddress(sm_hndl,"UnDecorateSymbolName"); sm_inst.SymLoadModule64 = cast(SymLoadModule64Func) GetProcAddress(sm_hndl,"SymLoadModule64"); sm_inst.SymGetSearchPath = cast(SymGetSearchPathFunc) GetProcAddress(sm_hndl,"SymGetSearchPath"); + sm_inst.SymSetSearchPath = cast(SymSetSearchPathFunc) GetProcAddress(sm_hndl,"SymSetSearchPath"); sm_inst.SymUnloadModule64 = cast(SymUnloadModule64Func) GetProcAddress(sm_hndl,"SymUnloadModule64"); sm_inst.SymRegisterCallback64 = cast(SymRegisterCallback64Func) GetProcAddress(sm_hndl, "SymRegisterCallback64"); sm_inst.ImagehlpApiVersion = cast(ImagehlpApiVersionFunc) GetProcAddress(sm_hndl, "ImagehlpApiVersion"); @@ -91,7 +94,8 @@ struct DbgHelp sm_inst.SymSetOptions && sm_inst.SymFunctionTableAccess64 && sm_inst.SymGetLineFromAddr64 && sm_inst.SymGetModuleBase64 && sm_inst.SymGetModuleInfo64 && sm_inst.SymGetSymFromAddr64 && sm_inst.UnDecorateSymbolName && sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath && - sm_inst.SymUnloadModule64 && sm_inst.SymRegisterCallback64 && sm_inst.ImagehlpApiVersion); + sm_inst.SymSetSearchPath && sm_inst.SymUnloadModule64 && sm_inst.SymRegisterCallback64 && + sm_inst.ImagehlpApiVersion); return &sm_inst; } diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d index b7dde9387af..fe4d24fafce 100644 --- a/libphobos/libdruntime/core/thread/osthread.d +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -719,7 +719,7 @@ class Thread : ThreadBase // the effective maximum. // maxupri - result.PRIORITY_MIN = -clinfo[0]; + result.PRIORITY_MIN = -cast(int)(clinfo[0]); // by definition result.PRIORITY_DEFAULT = 0; } @@ -2196,8 +2196,7 @@ extern (C) void thread_init() @nogc status = sem_init( &suspendCount, 0, 0 ); assert( status == 0 ); } - if (typeid(Thread).initializer.ptr) - _mainThreadStore[] = typeid(Thread).initializer[]; + _mainThreadStore[] = __traits(initSymbol, Thread)[]; Thread.sm_main = attachThread((cast(Thread)_mainThreadStore.ptr).__ctor()); } diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d index 4592bf1d975..9cee4d8d77d 100644 --- a/libphobos/libdruntime/core/thread/threadbase.d +++ b/libphobos/libdruntime/core/thread/threadbase.d @@ -771,10 +771,7 @@ package void thread_term_tpl(ThreadT, MainThreadStore)(ref MainThreadStore _main // destruct manually as object.destroy is not @nogc (cast(ThreadT) cast(void*) ThreadBase.sm_main).__dtor(); _d_monitordelete_nogc(ThreadBase.sm_main); - if (typeid(ThreadT).initializer.ptr) - _mainThreadStore[] = typeid(ThreadT).initializer[]; - else - (cast(ubyte[])_mainThreadStore)[] = 0; + _mainThreadStore[] = __traits(initSymbol, ThreadT)[]; ThreadBase.sm_main = null; assert(ThreadBase.sm_tbeg && ThreadBase.sm_tlen == 1); diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index a079e0e73e9..fee19ae65f0 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -3485,7 +3485,7 @@ enum immutable(void)* rtinfoHasPointers = cast(void*)1; // Helper functions -private inout(TypeInfo) getElement(return inout TypeInfo value) @trusted pure nothrow +private inout(TypeInfo) getElement(return scope inout TypeInfo value) @trusted pure nothrow { TypeInfo element = cast() value; for (;;) @@ -4215,8 +4215,8 @@ void destroy(bool initialize = true, T)(T obj) if (is(T == class)) static if (initialize) { - enum classSize = __traits(classInstanceSize, T); - (cast(void*)obj)[0 .. classSize] = typeid(T).initializer[]; + const initializer = __traits(initSymbol, T); + (cast(void*)obj)[0 .. initializer.length] = initializer[]; } } else @@ -4651,6 +4651,8 @@ public import core.internal.array.construction : _d_arrayctor; public import core.internal.array.construction : _d_arraysetctor; public import core.internal.array.capacity: _d_arraysetlengthTImpl; +public import core.lifetime : _d_delstruct; + public import core.internal.dassert: _d_assert_fail; public import core.internal.destruction: __ArrayDtor; diff --git a/libphobos/libdruntime/rt/aaA.d b/libphobos/libdruntime/rt/aaA.d index 6ff93f76da4..0c38622a879 100644 --- a/libphobos/libdruntime/rt/aaA.d +++ b/libphobos/libdruntime/rt/aaA.d @@ -287,7 +287,7 @@ TypeInfo_Struct fakeEntryTI(ref Impl aa, const TypeInfo keyti, const TypeInfo va void* p = GC.malloc(sizeti + (2 + rtisize) * (void*).sizeof); import core.stdc.string : memcpy; - memcpy(p, typeid(TypeInfo_Struct).initializer().ptr, sizeti); + memcpy(p, __traits(initSymbol, TypeInfo_Struct).ptr, sizeti); auto ti = cast(TypeInfo_Struct) p; auto extra = cast(TypeInfo*)(p + sizeti); @@ -853,7 +853,7 @@ struct Range extern (C) pure nothrow @nogc @safe { - Range _aaRange(return AA aa) + Range _aaRange(return scope AA aa) { if (!aa) return Range(); diff --git a/libphobos/libdruntime/rt/cast_.d b/libphobos/libdruntime/rt/cast_.d index dcb4438c700..1604510b427 100644 --- a/libphobos/libdruntime/rt/cast_.d +++ b/libphobos/libdruntime/rt/cast_.d @@ -36,7 +36,7 @@ extern (D) private bool areClassInfosEqual(scope const ClassInfo a, scope const * If it is null, return null. * Else, undefined crash */ -Object _d_toObject(return void* p) +Object _d_toObject(return scope void* p) { if (!p) return null; diff --git a/libphobos/libdruntime/rt/config.d b/libphobos/libdruntime/rt/config.d index f7682f31b63..a6605f4d603 100644 --- a/libphobos/libdruntime/rt/config.d +++ b/libphobos/libdruntime/rt/config.d @@ -101,6 +101,9 @@ string rt_cmdlineOption(string opt, scope rt_configCallBack dg) @nogc nothrow { foreach (a; rt_args) { + if (a == "--") + break; + if (a.length >= opt.length + 7 && a[0..6] == "--DRT-" && a[6 .. 6 + opt.length] == opt && a[6 + opt.length] == '=') { diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d index f1a9d873860..1f7a81de80f 100644 --- a/libphobos/libdruntime/rt/lifetime.d +++ b/libphobos/libdruntime/rt/lifetime.d @@ -181,7 +181,7 @@ extern (C) void _d_delstruct(void** p, TypeInfo_Struct inf) @weak } // strip const/immutable/shared/inout from type info -inout(TypeInfo) unqualify(return inout(TypeInfo) cti) pure nothrow @nogc +inout(TypeInfo) unqualify(return scope inout(TypeInfo) cti) pure nothrow @nogc { TypeInfo ti = cast() cti; while (ti) @@ -381,7 +381,7 @@ size_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure nothrow /** get the start of the array for the given block */ -void *__arrayStart(return BlkInfo info) nothrow pure +void *__arrayStart(return scope BlkInfo info) nothrow pure { return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0); } diff --git a/libphobos/libdruntime/rt/monitor_.d b/libphobos/libdruntime/rt/monitor_.d index 6bfce635c72..763f4392822 100644 --- a/libphobos/libdruntime/rt/monitor_.d +++ b/libphobos/libdruntime/rt/monitor_.d @@ -264,7 +264,7 @@ struct Monitor private: -@property ref shared(Monitor*) monitor(return Object h) pure nothrow @nogc +@property ref shared(Monitor*) monitor(return scope Object h) pure nothrow @nogc { return *cast(shared Monitor**)&h.__monitor; } diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 29bcf33c01f..68fefcb1ae4 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -574bf883b790340fb753d6542ec48a3ba3e6cb82 +12329adb67fb43891d6e4e543e7257bc34db0aa7 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d index 9e728e4622f..af665c41197 100644 --- a/libphobos/src/std/algorithm/iteration.d +++ b/libphobos/src/std/algorithm/iteration.d @@ -3595,7 +3595,6 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR) assert(res.equal("cba")); } - /// Ditto auto joiner(RoR)(RoR r) if (isInputRange!RoR && isInputRange!(ElementType!RoR)) @@ -3621,14 +3620,32 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) _currentBack = typeof(_currentBack).init; } + void replaceCurrent(typeof(_current) current) @trusted + { + import core.lifetime : move; + + current.move(_current); + } + + static if (isBidirectional) + { + void replaceCurrentBack(typeof(_currentBack) currentBack) @trusted + { + import core.lifetime : move; + + currentBack.move(_currentBack); + } + } + public: this(RoR r) { _items = r; + // field _current must be initialized in constructor, because it is nested struct + _current = typeof(_current).init; static if (isBidirectional && hasNested!Result) _currentBack = typeof(_currentBack).init; - // field _current must be initialized in constructor, because it is nested struct mixin(popFrontEmptyElements); static if (isBidirectional) mixin(popBackEmptyElements); @@ -3673,13 +3690,13 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) // consumed when a .save'd copy of ourselves is iterated over. So // we need to .save each subrange we traverse. static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR)) - _current = _items.front.save; + replaceCurrent(_items.front.save); else - _current = _items.front; + replaceCurrent(_items.front); } else { - _current = typeof(_current).init; + replaceCurrent(typeof(_current).init); } }; @@ -3696,9 +3713,9 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) static if (isBidirectional) { static if (is(typeof(null) : typeof(_currentBack))) - r._currentBack = _currentBack is null ? null : _currentBack.save; + r.replaceCurrentBack(_currentBack is null ? null : _currentBack.save); else - r._currentBack = _currentBack.save; + r.replaceCurrentBack(_currentBack.save); r.reachedFinalElement = reachedFinalElement; } return r; @@ -3784,22 +3801,22 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR)) { if (reachedFinalElement) - _current = _items.back.save; + replaceCurrent(_items.back.save); else - _currentBack = _items.back.save; + replaceCurrentBack(_items.back.save); } else { if (reachedFinalElement) - _current = _items.back; + replaceCurrent(_items.back); else - _currentBack = _items.back; + replaceCurrentBack(_items.back); } } else { - _current = typeof(_current).init; - _currentBack = typeof(_currentBack).init; + replaceCurrent(typeof(_current).init); + replaceCurrentBack(typeof(_currentBack).init); } }; @@ -4232,6 +4249,15 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) assert([[0]].joiner.save.back == 0); } +// https://issues.dlang.org/show_bug.cgi?id=22561 +@safe pure unittest +{ + import std.range : only; + + static immutable struct S { int[] array; } + assert([only(S(null))].joiner.front == S(null)); +} + /++ Implements the homonym function (also known as `accumulate`, $(D compress), `inject`, or `foldl`) present in various programming diff --git a/libphobos/src/std/algorithm/mutation.d b/libphobos/src/std/algorithm/mutation.d index 07cbb9b9823..22b7b98c229 100644 --- a/libphobos/src/std/algorithm/mutation.d +++ b/libphobos/src/std/algorithm/mutation.d @@ -886,31 +886,13 @@ if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range static if (hasElaborateAssign!T) { import std.algorithm.internal : addressOf; - //Elaborate opAssign. Must go the memcpy road. - //We avoid calling emplace here, because our goal is to initialize to - //the static state of T.init, - //So we want to avoid any un-necassarilly CC'ing of T.init + //Elaborate opAssign. Must go the memcpy/memset road. static if (!__traits(isZeroInit, T)) { - auto p = typeid(T).initializer(); for ( ; !range.empty ; range.popFront() ) { - static if (__traits(isStaticArray, T)) - { - // static array initializer only contains initialization - // for one element of the static array. - auto elemp = cast(void *) addressOf(range.front); - auto endp = elemp + T.sizeof; - while (elemp < endp) - { - memcpy(elemp, p.ptr, p.length); - elemp += p.length; - } - } - else - { - memcpy(addressOf(range.front), p.ptr, T.sizeof); - } + import core.internal.lifetime : emplaceInitializer; + emplaceInitializer(range.front); } } else @@ -1456,10 +1438,7 @@ private void moveEmplaceImpl(T)(ref scope T target, ref return scope T source) static if (__traits(isZeroInit, T)) () @trusted { memset(&source, 0, sz); }(); else - { - auto init = typeid(T).initializer(); - () @trusted { memcpy(&source, init.ptr, sz); }(); - } + () @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }(); } } else static if (isStaticArray!T) diff --git a/libphobos/src/std/algorithm/sorting.d b/libphobos/src/std/algorithm/sorting.d index f2877ccbdf4..ee68b234b15 100644 --- a/libphobos/src/std/algorithm/sorting.d +++ b/libphobos/src/std/algorithm/sorting.d @@ -3121,14 +3121,14 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R && else static assert(false, "`transform` returns an unsortable qualified type: " ~ TB.stringof); - static trustedMalloc(size_t len) @trusted + static trustedMalloc()(size_t len) @trusted { import core.checkedint : mulu; - import core.stdc.stdlib : malloc; + import core.memory : pureMalloc; bool overflow; const nbytes = mulu(len, T.sizeof, overflow); if (overflow) assert(false, "multiplication overflowed"); - T[] result = (cast(T*) malloc(nbytes))[0 .. len]; + T[] result = (cast(T*) pureMalloc(nbytes))[0 .. len]; static if (hasIndirections!T) { import core.memory : GC; @@ -3145,15 +3145,15 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R && { foreach (i; 0 .. length) collectException(destroy(xform1[i])); } - static void trustedFree(T[] p) @trusted + static void trustedFree()(T[] p) @trusted { - import core.stdc.stdlib : free; + import core.memory : pureFree; static if (hasIndirections!T) { import core.memory : GC; GC.removeRange(p.ptr); } - free(p.ptr); + pureFree(p.ptr); } trustedFree(xform1); } @@ -3186,7 +3186,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } /// -@safe unittest +@safe pure unittest { import std.algorithm.iteration : map; import std.numeric : entropy; @@ -3207,7 +3207,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) assert(isSorted!("a > b")(map!(entropy)(arr))); } -@safe unittest +@safe pure unittest { import std.algorithm.iteration : map; import std.numeric : entropy; @@ -3228,7 +3228,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) assert(isSorted!("a < b")(map!(entropy)(arr))); } -@safe unittest +@safe pure unittest { // binary transform function string[] strings = [ "one", "two", "three" ]; @@ -3237,7 +3237,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } // https://issues.dlang.org/show_bug.cgi?id=4909 -@safe unittest +@safe pure unittest { import std.typecons : Tuple; Tuple!(char)[] chars; @@ -3245,7 +3245,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } // https://issues.dlang.org/show_bug.cgi?id=5924 -@safe unittest +@safe pure unittest { import std.typecons : Tuple; Tuple!(char)[] chars; @@ -3253,7 +3253,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } // https://issues.dlang.org/show_bug.cgi?id=13965 -@safe unittest +@safe pure unittest { import std.typecons : Tuple; Tuple!(char)[] chars; @@ -3261,7 +3261,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R) } // https://issues.dlang.org/show_bug.cgi?id=13965 -@safe unittest +@safe pure unittest { import std.algorithm.iteration : map; import std.numeric : entropy; diff --git a/libphobos/src/std/concurrency.d b/libphobos/src/std/concurrency.d index a9830af61a2..fb383ae3f2e 100644 --- a/libphobos/src/std/concurrency.d +++ b/libphobos/src/std/concurrency.d @@ -2149,14 +2149,16 @@ private if (msg.convertsTo!(Args)) { - static if (is(ReturnType!(t) == bool)) + alias RT = ReturnType!(t); + static if (is(RT == bool)) { return msg.map(op); } else { msg.map(op); - return true; + static if (!is(immutable RT == immutable noreturn)) + return true; } } } @@ -2745,7 +2747,8 @@ auto ref initOnce(alias var)(lazy typeof(var) init, shared Mutex mutex) if (!atomicLoad!(MemoryOrder.raw)(flag)) { var = init; - atomicStore!(MemoryOrder.rel)(flag, true); + static if (!is(immutable typeof(var) == immutable noreturn)) + atomicStore!(MemoryOrder.rel)(flag, true); } } } @@ -2827,3 +2830,26 @@ auto ref initOnce(alias var)(lazy typeof(var) init, Mutex mutex) immutable expected = Aggregate(42, [1, 2, 3, 4, 5]); assert(result1 == expected); } + +// Noreturn support +@system unittest +{ + static noreturn foo(int) { throw new Exception(""); } + + if (false) spawn(&foo, 1); + if (false) spawnLinked(&foo, 1); + + if (false) receive(&foo); + if (false) receiveTimeout(Duration.init, &foo); + + // Wrapped in __traits(compiles) to skip codegen which crashes dmd's backend + static assert(__traits(compiles, receiveOnly!noreturn() )); + static assert(__traits(compiles, send(Tid.init, noreturn.init) )); + static assert(__traits(compiles, prioritySend(Tid.init, noreturn.init) )); + static assert(__traits(compiles, yield(noreturn.init) )); + + static assert(__traits(compiles, { + __gshared noreturn n; + initOnce!n(noreturn.init); + })); +} diff --git a/libphobos/src/std/container/dlist.d b/libphobos/src/std/container/dlist.d index cc3e2e85dbc..32d56ecc733 100644 --- a/libphobos/src/std/container/dlist.d +++ b/libphobos/src/std/container/dlist.d @@ -196,6 +196,12 @@ struct DList(T) T _payload = T.init; + this (BaseNode _base, T _payload) + { + this._base = _base; + this._payload = _payload; + } + inout(BaseNode)* asBaseNode() inout @trusted { return &_base; diff --git a/libphobos/src/std/container/rbtree.d b/libphobos/src/std/container/rbtree.d index f8e70fc0882..0b0a0b2f59f 100644 --- a/libphobos/src/std/container/rbtree.d +++ b/libphobos/src/std/container/rbtree.d @@ -887,7 +887,7 @@ if (is(typeof(binaryFun!less(T.init, T.init)))) * Returns: * true if node was added */ - private bool _add(return Elem n) + private bool _add(return scope Elem n) { Node result; static if (!allowDuplicates) diff --git a/libphobos/src/std/datetime/interval.d b/libphobos/src/std/datetime/interval.d index 741088a72dc..ba2a21056c7 100644 --- a/libphobos/src/std/datetime/interval.d +++ b/libphobos/src/std/datetime/interval.d @@ -8349,7 +8349,7 @@ private: } { - SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; } + SysTime stFunc(scope const SysTime st) { return SysTime.init; } auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)), SysTime(DateTime(2012, 1, 7, 14, 0, 0))); auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc); @@ -8794,7 +8794,7 @@ private: } { - SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; } + SysTime stFunc(scope const SysTime st) { return SysTime.init; } auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7))); auto ir = PosInfIntervalRange!SysTime(posInfInterval, &stFunc); } @@ -9076,7 +9076,7 @@ private: } { - SysTime stFunc(scope const SysTime st) { return cast(SysTime)(st); } + SysTime stFunc(scope const SysTime st) { return SysTime.init; } auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0))); auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc); } diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d index 4da1281f98a..9b2a8443fdd 100644 --- a/libphobos/src/std/datetime/systime.d +++ b/libphobos/src/std/datetime/systime.d @@ -503,7 +503,7 @@ public: given $(REF DateTime,std,datetime,date) is assumed to be in the given time zone. +/ - this(DateTime dateTime, immutable TimeZone tz = null) @safe nothrow + this(DateTime dateTime, return scope immutable TimeZone tz = null) return scope @safe nothrow { try this(dateTime, Duration.zero, tz); @@ -554,7 +554,7 @@ public: $(REF DateTimeException,std,datetime,date) if `fracSecs` is negative or if it's greater than or equal to one second. +/ - this(DateTime dateTime, Duration fracSecs, immutable TimeZone tz = null) @safe + this(DateTime dateTime, Duration fracSecs, return scope immutable TimeZone tz = null) return scope @safe { enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); @@ -611,7 +611,7 @@ public: given $(REF Date,std,datetime,date) is assumed to be in the given time zone. +/ - this(Date date, immutable TimeZone tz = null) @safe nothrow + this(Date date, return scope immutable TimeZone tz = null) return scope @safe nothrow { _timezone = tz is null ? LocalTime() : tz; @@ -664,7 +664,7 @@ public: $(LREF SysTime). If null, $(REF LocalTime,std,datetime,timezone) will be used. +/ - this(long stdTime, immutable TimeZone tz = null) @safe pure nothrow + this(long stdTime, return scope immutable TimeZone tz = null) return scope @safe pure nothrow { _stdTime = stdTime; _timezone = tz is null ? LocalTime() : tz; @@ -693,7 +693,7 @@ public: Returns: The `this` of this `SysTime`. +/ - ref SysTime opAssign()(auto ref const(SysTime) rhs) return @safe pure nothrow scope + ref SysTime opAssign()(auto ref const(SysTime) rhs) return scope @safe pure nothrow { _stdTime = rhs._stdTime; _timezone = rhs._timezone; @@ -710,6 +710,7 @@ public: st = other; assert(st == other); + version (none) // https://issues.dlang.org/show_bug.cgi?id=21175 static void testScope(scope ref SysTime left, const scope SysTime right) @safe { left = right; @@ -2184,7 +2185,7 @@ public: hours - adjust the time to this $(LREF SysTime)'s time zone before returning. +/ - @property immutable(TimeZone) timezone() @safe const pure nothrow scope + @property immutable(TimeZone) timezone() @safe const pure nothrow return scope { return _timezone; } @@ -2238,7 +2239,7 @@ public: /++ Returns whether DST is in effect for this $(LREF SysTime). +/ - @property bool dstInEffect() @safe const nothrow scope + @property bool dstInEffect() @safe const nothrow return scope { return _timezone.dstInEffect(_stdTime); } @@ -2261,7 +2262,7 @@ public: Returns what the offset from UTC is for this $(LREF SysTime). It includes the DST offset in effect at that time (if any). +/ - @property Duration utcOffset() @safe const nothrow scope + @property Duration utcOffset() @safe const nothrow return scope { return _timezone.utcOffsetAt(_stdTime); } @@ -9586,13 +9587,13 @@ private: @property override bool hasDST() @safe const nothrow @nogc { return false; } - override bool dstInEffect(long stdTime) @safe const nothrow @nogc { return false; } + override bool dstInEffect(long stdTime) @safe const scope nothrow @nogc { return false; } - override long utcToTZ(long stdTime) @safe const nothrow @nogc { return 0; } + override long utcToTZ(long stdTime) @safe const scope nothrow @nogc { return 0; } - override long tzToUTC(long adjTime) @safe const nothrow @nogc { return 0; } + override long tzToUTC(long adjTime) @safe const scope nothrow @nogc { return 0; } - override Duration utcOffsetAt(long stdTime) @safe const nothrow @nogc { return Duration.zero; } + override Duration utcOffsetAt(long stdTime) @safe const scope nothrow @nogc { return Duration.zero; } private: @@ -9628,7 +9629,7 @@ private: return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage; } - pragma(inline, true) @property void _timezone(immutable TimeZone tz) @safe pure nothrow @nogc scope + pragma(inline, true) @property void _timezone(return scope immutable TimeZone tz) @safe pure nothrow @nogc scope { _timezoneStorage = tz; } diff --git a/libphobos/src/std/datetime/timezone.d b/libphobos/src/std/datetime/timezone.d index 052758097a9..a55411b02d5 100644 --- a/libphobos/src/std/datetime/timezone.d +++ b/libphobos/src/std/datetime/timezone.d @@ -100,7 +100,7 @@ public: However, on Windows, it may be the unabbreviated name (e.g. Pacific Standard Time). Regardless, it is not the same as name. +/ - @property string stdName() @safe const nothrow + @property string stdName() @safe const scope nothrow { return _stdName; } @@ -113,7 +113,7 @@ public: However, on Windows, it may be the unabbreviated name (e.g. Pacific Daylight Time). Regardless, it is not the same as name. +/ - @property string dstName() @safe const nothrow + @property string dstName() @safe const scope nothrow { return _dstName; } @@ -137,7 +137,7 @@ public: stdTime = The UTC time that needs to be checked for DST in this time zone. +/ - abstract bool dstInEffect(long stdTime) @safe const nothrow; + abstract bool dstInEffect(long stdTime) @safe const scope nothrow; /++ @@ -148,7 +148,7 @@ public: stdTime = The UTC time that needs to be adjusted to this time zone's time. +/ - abstract long utcToTZ(long stdTime) @safe const nothrow; + abstract long utcToTZ(long stdTime) @safe const scope nothrow; /++ @@ -159,7 +159,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - abstract long tzToUTC(long adjTime) @safe const nothrow; + abstract long tzToUTC(long adjTime) @safe const scope nothrow; /++ @@ -170,7 +170,7 @@ public: stdTime = The UTC time for which to get the offset from UTC for this time zone. +/ - Duration utcOffsetAt(long stdTime) @safe const nothrow + Duration utcOffsetAt(long stdTime) @safe const scope nothrow { return dur!"hnsecs"(utcToTZ(stdTime) - stdTime); } @@ -580,7 +580,7 @@ public: dynamically rather than it being fixed like it would be with most time zones. +/ - @property override string stdName() @trusted const nothrow + @property override string stdName() @trusted const scope nothrow { version (Posix) { @@ -665,7 +665,7 @@ public: dynamically rather than it being fixed like it would be with most time zones. +/ - @property override string dstName() @trusted const nothrow + @property override string dstName() @trusted const scope nothrow { version (Posix) { @@ -809,7 +809,7 @@ public: stdTime = The UTC time that needs to be checked for DST in this time zone. +/ - override bool dstInEffect(long stdTime) @trusted const nothrow + override bool dstInEffect(long stdTime) @trusted const scope nothrow { import core.stdc.time : tm; @@ -863,7 +863,7 @@ public: See_Also: `TimeZone.utcToTZ` +/ - override long utcToTZ(long stdTime) @trusted const nothrow + override long utcToTZ(long stdTime) @trusted const scope nothrow { version (Solaris) return stdTime + convert!("seconds", "hnsecs")(tm_gmtoff(stdTime)); @@ -904,7 +904,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @trusted const nothrow + override long tzToUTC(long adjTime) @trusted const scope nothrow { version (Posix) { @@ -1159,7 +1159,7 @@ public: /++ Always returns false. +/ - override bool dstInEffect(long stdTime) @safe const nothrow + override bool dstInEffect(long stdTime) @safe const scope nothrow { return false; } @@ -1175,7 +1175,7 @@ public: See_Also: `TimeZone.utcToTZ` +/ - override long utcToTZ(long stdTime) @safe const nothrow + override long utcToTZ(long stdTime) @safe const scope nothrow { return stdTime; } @@ -1208,7 +1208,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @safe const nothrow + override long tzToUTC(long adjTime) @safe const scope nothrow { return adjTime; } @@ -1238,7 +1238,7 @@ public: stdTime = The UTC time for which to get the offset from UTC for this time zone. +/ - override Duration utcOffsetAt(long stdTime) @safe const nothrow + override Duration utcOffsetAt(long stdTime) @safe const scope nothrow { return dur!"hnsecs"(0); } @@ -1285,7 +1285,7 @@ public: /++ Always returns false. +/ - override bool dstInEffect(long stdTime) @safe const nothrow + override bool dstInEffect(long stdTime) @safe const scope nothrow { return false; } @@ -1299,7 +1299,7 @@ public: stdTime = The UTC time that needs to be adjusted to this time zone's time. +/ - override long utcToTZ(long stdTime) @safe const nothrow + override long utcToTZ(long stdTime) @safe const scope nothrow { return stdTime + _utcOffset.total!"hnsecs"; } @@ -1326,7 +1326,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @safe const nothrow + override long tzToUTC(long adjTime) @safe const scope nothrow { return adjTime - _utcOffset.total!"hnsecs"; } @@ -1352,7 +1352,7 @@ public: stdTime = The UTC time for which to get the offset from UTC for this time zone. +/ - override Duration utcOffsetAt(long stdTime) @safe const nothrow + override Duration utcOffsetAt(long stdTime) @safe const scope nothrow { return _utcOffset; } @@ -1919,7 +1919,7 @@ public: stdTime = The UTC time that needs to be checked for DST in this time zone. +/ - override bool dstInEffect(long stdTime) @safe const nothrow + override bool dstInEffect(long stdTime) @safe const scope nothrow { assert(!_transitions.empty); @@ -1943,7 +1943,7 @@ public: stdTime = The UTC time that needs to be adjusted to this time zone's time. +/ - override long utcToTZ(long stdTime) @safe const nothrow + override long utcToTZ(long stdTime) @safe const scope nothrow { assert(!_transitions.empty); @@ -1968,7 +1968,7 @@ public: adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @safe const nothrow + override long tzToUTC(long adjTime) @safe const scope nothrow { assert(!_transitions.empty, "UTC offset's not available"); @@ -2691,7 +2691,7 @@ private: } - int calculateLeapSeconds(long stdTime) @safe const pure nothrow + int calculateLeapSeconds(long stdTime) @safe const scope pure nothrow { if (_leapSeconds.empty) return 0; @@ -2864,7 +2864,7 @@ version (StdDdoc) current dates but will still return true for `hasDST` because the time zone did at some point have DST. +/ - @property override bool hasDST() @safe const nothrow; + @property override bool hasDST() @safe const scope nothrow; /++ @@ -2876,7 +2876,7 @@ version (StdDdoc) stdTime = The UTC time that needs to be checked for DST in this time zone. +/ - override bool dstInEffect(long stdTime) @safe const nothrow; + override bool dstInEffect(long stdTime) @safe const scope nothrow; /++ @@ -2888,7 +2888,7 @@ version (StdDdoc) stdTime = The UTC time that needs to be adjusted to this time zone's time. +/ - override long utcToTZ(long stdTime) @safe const nothrow; + override long utcToTZ(long stdTime) @safe const scope nothrow; /++ @@ -2900,7 +2900,7 @@ version (StdDdoc) adjTime = The time in this time zone that needs to be adjusted to UTC time. +/ - override long tzToUTC(long adjTime) @safe const nothrow; + override long tzToUTC(long adjTime) @safe const scope nothrow; /++ @@ -2945,9 +2945,9 @@ version (StdDdoc) else alias TIME_ZONE_INFORMATION = void*; - static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow; - static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow; - static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow; + static bool _dstInEffect(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow; + static long _utcToTZ(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow; + static long _tzToUTC(const scope TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow; this() immutable pure { @@ -2967,25 +2967,25 @@ else version (Windows) public: - @property override bool hasDST() @safe const nothrow + @property override bool hasDST() @safe const scope nothrow { return _tzInfo.DaylightDate.wMonth != 0; } - override bool dstInEffect(long stdTime) @safe const nothrow + override bool dstInEffect(long stdTime) @safe const scope nothrow { return _dstInEffect(&_tzInfo, stdTime); } - override long utcToTZ(long stdTime) @safe const nothrow + override long utcToTZ(long stdTime) @safe const scope nothrow { return _utcToTZ(&_tzInfo, stdTime, hasDST); } - override long tzToUTC(long adjTime) @safe const nothrow + override long tzToUTC(long adjTime) @safe const scope nothrow { return _tzToUTC(&_tzInfo, adjTime, hasDST); } @@ -3071,7 +3071,7 @@ else version (Windows) private: - static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) @trusted nothrow + static bool _dstInEffect(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime) @trusted nothrow { try { @@ -3155,7 +3155,7 @@ else version (Windows) } - static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) @safe nothrow + static long _utcToTZ(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) @safe nothrow { if (hasDST && WindowsTimeZone._dstInEffect(tzInfo, stdTime)) return stdTime - convert!("minutes", "hnsecs")(tzInfo.Bias + tzInfo.DaylightBias); @@ -3164,7 +3164,7 @@ else version (Windows) } - static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) @trusted nothrow + static long _tzToUTC(const scope TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) @trusted nothrow { if (hasDST) { diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d index 1bfed64eae5..315e054cbab 100644 --- a/libphobos/src/std/file.d +++ b/libphobos/src/std/file.d @@ -1124,7 +1124,7 @@ version (Windows) private ulong makeUlong(DWORD dwLow, DWORD dwHigh) @safe pure } version (Posix) private extern (C) pragma(mangle, stat.mangleof) -int trustedStat(const(FSChar)* namez, ref stat_t buf) @nogc nothrow @trusted; +int trustedStat(scope const(FSChar)* namez, ref stat_t buf) @nogc nothrow @trusted; /** Get size of file `name` in bytes. @@ -1928,7 +1928,7 @@ if (isConvertibleToString!R) assert(!f.exists); } -private bool existsImpl(const(FSChar)* namez) @trusted nothrow @nogc +private bool existsImpl(scope const(FSChar)* namez) @trusted nothrow @nogc { version (Windows) { @@ -2010,7 +2010,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { auto namez = name.tempCString!FSChar(); - static auto trustedGetFileAttributesW(const(FSChar)* namez) @trusted + static auto trustedGetFileAttributesW(scope const(FSChar)* namez) @trusted { return GetFileAttributesW(namez); } @@ -2220,7 +2220,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { auto namez = name.tempCString!FSChar(); - static auto trustedSetFileAttributesW(const(FSChar)* namez, uint dwFileAttributes) @trusted + static auto trustedSetFileAttributesW(scope const(FSChar)* namez, uint dwFileAttributes) @trusted { return SetFileAttributesW(namez, dwFileAttributes); } @@ -2233,7 +2233,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && else version (Posix) { auto namez = name.tempCString!FSChar(); - static auto trustedChmod(const(FSChar)* namez, mode_t mode) @trusted + static auto trustedChmod(scope const(FSChar)* namez, mode_t mode) @trusted { return chmod(namez, mode); } @@ -2868,14 +2868,14 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { - static auto trustedChdir(const(FSChar)* pathz) @trusted + static auto trustedChdir(scope const(FSChar)* pathz) @trusted { return SetCurrentDirectoryW(pathz); } } else version (Posix) { - static auto trustedChdir(const(FSChar)* pathz) @trusted + static auto trustedChdir(scope const(FSChar)* pathz) @trusted { return core.sys.posix.unistd.chdir(pathz) == 0; } @@ -2939,7 +2939,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { - static auto trustedCreateDirectoryW(const(FSChar)* pathz) @trusted + static auto trustedCreateDirectoryW(scope const(FSChar)* pathz) @trusted { return CreateDirectoryW(pathz, null); } @@ -2953,7 +2953,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && { import std.conv : octal; - static auto trustedMkdir(const(FSChar)* pathz, mode_t mode) @trusted + static auto trustedMkdir(scope const(FSChar)* pathz, mode_t mode) @trusted { return core.sys.posix.sys.stat.mkdir(pathz, mode); } @@ -3143,14 +3143,14 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && version (Windows) { - static auto trustedRmdir(const(FSChar)* pathz) @trusted + static auto trustedRmdir(scope const(FSChar)* pathz) @trusted { return RemoveDirectoryW(pathz); } } else version (Posix) { - static auto trustedRmdir(const(FSChar)* pathz) @trusted + static auto trustedRmdir(scope const(FSChar)* pathz) @trusted { return core.sys.posix.unistd.rmdir(pathz) == 0; } @@ -3859,17 +3859,17 @@ else version (Windows) return _size; } - @property SysTime timeCreated() const pure nothrow scope + @property SysTime timeCreated() const pure nothrow return scope { return cast(SysTime)_timeCreated; } - @property SysTime timeLastAccessed() const pure nothrow scope + @property SysTime timeLastAccessed() const pure nothrow return scope { return cast(SysTime)_timeLastAccessed; } - @property SysTime timeLastModified() const pure nothrow scope + @property SysTime timeLastModified() const pure nothrow return scope { return cast(SysTime)_timeLastModified; } diff --git a/libphobos/src/std/internal/cstring.d b/libphobos/src/std/internal/cstring.d index a61ee81cc45..b21f58d602e 100644 --- a/libphobos/src/std/internal/cstring.d +++ b/libphobos/src/std/internal/cstring.d @@ -227,7 +227,7 @@ private struct TempCStringBuffer(To = char) @disable this(this); alias ptr this; /// implicitly covert to raw pointer - @property inout(To)* buffPtr() inout + @property inout(To)* buffPtr() return inout { return _ptr == useStack ? _buff.ptr : _ptr; } diff --git a/libphobos/src/std/internal/math/biguintcore.d b/libphobos/src/std/internal/math/biguintcore.d index 79446756fa6..6a93e0a16b0 100644 --- a/libphobos/src/std/internal/math/biguintcore.d +++ b/libphobos/src/std/internal/math/biguintcore.d @@ -879,7 +879,7 @@ public: } // return x / y - static BigUint divInt(T)(scope return BigUint x, T y_) pure nothrow @safe + static BigUint divInt(T)(return scope BigUint x, T y_) pure nothrow @safe if ( is(immutable T == immutable uint) ) { uint y = y_; @@ -942,7 +942,7 @@ public: } // return x / y - static BigUint div(scope return BigUint x, scope BigUint y) pure nothrow @safe + static BigUint div(return scope BigUint x, scope BigUint y) pure nothrow @safe { if (y.data.length > x.data.length) return BigUint(ZERO); @@ -954,7 +954,7 @@ public: } // return x % y - static BigUint mod(scope return BigUint x, scope BigUint y) pure nothrow @safe + static BigUint mod(return scope BigUint x, scope BigUint y) pure nothrow @safe { if (y.data.length > x.data.length) return x; if (y.data.length == 1) @@ -1020,7 +1020,7 @@ public: * exponentiation is used. * Memory allocation is minimized: at most one temporary BigUint is used. */ - static BigUint pow(scope return BigUint x, ulong y) pure nothrow @safe + static BigUint pow(return scope BigUint x, ulong y) pure nothrow @safe { // Deal with the degenerate cases first. if (y == 0) return BigUint(ONE); @@ -1259,7 +1259,7 @@ public: } // Remove leading zeros from x, to restore the BigUint invariant -inout(BigDigit) [] removeLeadingZeros(scope return inout(BigDigit) [] x) pure nothrow @safe +inout(BigDigit) [] removeLeadingZeros(return scope inout(BigDigit) [] x) pure nothrow @safe { size_t k = x.length; while (k>1 && x[k - 1]==0) --k; @@ -1916,7 +1916,7 @@ pure @safe unittest // every 8 digits. // buff.length must be data.length*8 if separator is zero, // or data.length*9 if separator is non-zero. It will be completely filled. -char [] biguintToHex(scope return char [] buff, const scope BigDigit [] data, char separator=0, +char [] biguintToHex(return scope char [] buff, const scope BigDigit [] data, char separator=0, LetterCase letterCase = LetterCase.upper) pure nothrow @safe { int x=0; diff --git a/libphobos/src/std/json.d b/libphobos/src/std/json.d index af7aa383d8e..ea22d635766 100644 --- a/libphobos/src/std/json.d +++ b/libphobos/src/std/json.d @@ -159,7 +159,7 @@ struct JSONValue return store.str; } /// ditto - @property string str(return string v) pure nothrow @nogc @trusted return // TODO make @safe + @property string str(return scope string v) pure nothrow @nogc @trusted return // TODO make @safe { assign(v); return v; @@ -282,7 +282,7 @@ struct JSONValue return store.object; } /// ditto - @property JSONValue[string] object(return JSONValue[string] v) pure nothrow @nogc @trusted // TODO make @safe + @property JSONValue[string] object(return scope JSONValue[string] v) pure nothrow @nogc @trusted // TODO make @safe { assign(v); return v; @@ -321,14 +321,14 @@ struct JSONValue (*a)[0] = "world"; // segmentation fault --- */ - @property ref inout(JSONValue[]) array() inout pure @system + @property ref inout(JSONValue[]) array() return scope inout pure @system { enforce!JSONException(type == JSONType.array, "JSONValue is not an array"); return store.array; } /// ditto - @property JSONValue[] array(return JSONValue[] v) pure nothrow @nogc @trusted scope // TODO make @safe + @property JSONValue[] array(return scope JSONValue[] v) pure nothrow @nogc @trusted scope // TODO make @safe { assign(v); return v; @@ -635,7 +635,7 @@ struct JSONValue * Hash syntax for json objects. * Throws: `JSONException` if `type` is not `JSONType.object`. */ - ref inout(JSONValue) opIndex(return string k) inout pure @safe + ref inout(JSONValue) opIndex(return scope string k) inout pure @safe { auto o = this.objectNoRef; return *enforce!JSONException(k in o, diff --git a/libphobos/src/std/net/isemail.d b/libphobos/src/std/net/isemail.d index f2a8ff3025d..12a29fe44c9 100644 --- a/libphobos/src/std/net/isemail.d +++ b/libphobos/src/std/net/isemail.d @@ -1893,7 +1893,7 @@ Note that only the first item of "matchAll" was ever used in practice so we can return `const(Char)[]` instead of `const(Char)[][]` using a zero-length string to indicate no match. +/ -const(Char)[] matchIPSuffix(Char)(return const(Char)[] s) @nogc nothrow pure @safe +const(Char)[] matchIPSuffix(Char)(return scope const(Char)[] s) @nogc nothrow pure @safe { size_t end = s.length; if (end < 7) return null; diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d index 98c5b946748..958f606ff52 100644 --- a/libphobos/src/std/process.d +++ b/libphobos/src/std/process.d @@ -276,7 +276,7 @@ static: multi-threaded programs. See e.g. $(LINK2 https://www.gnu.org/software/libc/manual/html_node/Environment-Access.html#Environment-Access, glibc). */ - inout(char)[] opIndexAssign(return inout char[] value, scope const(char)[] name) @trusted + inout(char)[] opIndexAssign(return scope inout char[] value, scope const(char)[] name) @trusted { version (Posix) { @@ -4385,6 +4385,7 @@ else version (Posix) void browse(scope const(char)[] url) nothrow @nogc @safe { + const buffer = url.tempCString(); // Retain buffer until end of scope const(char)*[3] args; // Trusted because it's called with a zero-terminated literal @@ -4408,7 +4409,6 @@ else version (Posix) } } - const buffer = url.tempCString(); // Retain buffer until end of scope args[1] = buffer; args[2] = null; diff --git a/libphobos/src/std/random.d b/libphobos/src/std/random.d index a3483561134..106e51ceedb 100644 --- a/libphobos/src/std/random.d +++ b/libphobos/src/std/random.d @@ -166,12 +166,16 @@ version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any; assert(10.iota.randomSample(3, rnd2).equal([7, 8, 9])); // Cover all elements in an array in random order - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 - assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5])); + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 + assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5])); + else + assert(10.iota.randomCover(rnd2).equal([4, 8, 7, 3, 5, 9, 2, 6, 0, 1])); // Shuffle an array - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 - assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1])); + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 + assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1])); + else + assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([4, 2, 5, 0, 1])); } version (StdUnittest) diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d index d3097d548ce..f30ea80ae44 100644 --- a/libphobos/src/std/stdio.d +++ b/libphobos/src/std/stdio.d @@ -4650,7 +4650,7 @@ if ((isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) || isSomeString!R1) auto namez = name.tempCString!FSChar(); auto modez = mode.tempCString!FSChar(); - static _fopenImpl(const(FSChar)* namez, const(FSChar)* modez) @trusted nothrow @nogc + static _fopenImpl(scope const(FSChar)* namez, scope const(FSChar)* modez) @trusted nothrow @nogc { version (Windows) { diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index db0e3da304c..6dee863521d 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -2239,7 +2239,7 @@ if (is(T == class) || is(T == interface) || isAssociativeArray!T) U stripped; } - void opAssign(T another) pure nothrow @nogc + void opAssign(return scope T another) pure nothrow @nogc { // If `T` defines `opCast` we must infer the safety static if (hasMember!(T, "opCast")) @@ -2271,7 +2271,7 @@ if (is(T == class) || is(T == interface) || isAssociativeArray!T) opAssign(initializer); } - @property inout(T) get() @trusted pure nothrow @nogc inout + @property inout(T) get() @trusted pure nothrow @nogc return scope inout { return original; } @@ -2792,6 +2792,15 @@ struct Nullable(T) } } + this (ref return scope inout Nullable!T rhs) inout + { + _isNull = rhs._isNull; + if (!_isNull) + _value.payload = rhs._value.payload; + else + _value = DontCallDestructorT.init; + } + /** * If they are both null, then they are equal. If one is null and the other * is not, then they are not equal. If they are both non-null, then they are @@ -3284,11 +3293,11 @@ auto nullable(T)(T t) static struct S2 //inspired from 9404 { Nullable!int ni; - this(S2 other) + this(ref S2 other) { ni = other.ni; } - void opAssign(S2 other) + void opAssign(ref S2 other) { ni = other.ni; } @@ -9566,3 +9575,21 @@ unittest assert((a ^ true) == Ternary.no); assert((a ^ false) == Ternary.yes); } + +// https://issues.dlang.org/show_bug.cgi?id=22511 +@safe unittest +{ + static struct S + { + int b; + @disable this(this); + this (ref return scope inout S rhs) inout + { + this.b = rhs.b + 1; + } + } + + Nullable!S s1 = S(1); + Nullable!S s2 = s1; + assert(s2.get().b > s1.get().b); +} diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d index 45b7207c1f1..a27cbea177b 100644 --- a/libphobos/src/std/uni/package.d +++ b/libphobos/src/std/uni/package.d @@ -1987,8 +1987,8 @@ pure: { return this[0] == val[0] && this[1] == val[1]; } - @property ref inout(uint) a() inout { return _tuple[0]; } - @property ref inout(uint) b() inout { return _tuple[1]; } + @property ref inout(uint) a() return inout { return _tuple[0]; } + @property ref inout(uint) b() return inout { return _tuple[1]; } } /** diff --git a/libphobos/src/std/utf.d b/libphobos/src/std/utf.d index be60e7a8f3a..866ec48cbdc 100644 --- a/libphobos/src/std/utf.d +++ b/libphobos/src/std/utf.d @@ -4315,12 +4315,12 @@ if (isSomeChar!C) { enum Empty = uint.max; // range is empty or just constructed - this(return R r) + this(return scope R r) { this.r = r; } - this(return R r, uint buff) + this(return scope R r, uint buff) { this.r = r; this.buff = buff; @@ -4328,7 +4328,7 @@ if (isSomeChar!C) static if (isBidirectionalRange!R) { - this(return R r, uint frontBuff, uint backBuff) + this(return scope R r, uint frontBuff, uint backBuff) { this.r = r; this.buff = frontBuff; @@ -4436,12 +4436,12 @@ if (isSomeChar!C) { static struct Result { - this(return R r) + this(return scope R r) { this.r = r; } - this(return R r, ushort pos, ushort fill, C[4 / C.sizeof] buf) + this(return scope R r, ushort pos, ushort fill, C[4 / C.sizeof] buf) { this.r = r; this.pos = pos; @@ -4451,7 +4451,7 @@ if (isSomeChar!C) static if (isBidirectionalRange!R) { - this(return R r, ushort frontPos, ushort frontFill, + this(return scope R r, ushort frontPos, ushort frontFill, ushort backPos, ushort backFill, C[4 / C.sizeof] buf) { this.r = r; diff --git a/libphobos/testsuite/libphobos.config/config.exp b/libphobos/testsuite/libphobos.config/config.exp index e8f4d943ff3..544caa204b3 100644 --- a/libphobos/testsuite/libphobos.config/config.exp +++ b/libphobos/testsuite/libphobos.config/config.exp @@ -22,6 +22,7 @@ set dg-output-text [list] set config_test_list [list \ { test19433 "--DRT-dont-eat-me" 0 } \ { test20459 "foo bar -- --DRT-gcopts=profile:1" 0 } \ + { test22523 "-- --DRT-testmode=run-main" 0 } \ ] # Initialize dg. diff --git a/libphobos/testsuite/libphobos.config/test22523.d b/libphobos/testsuite/libphobos.config/test22523.d new file mode 100644 index 00000000000..f3086963f2e --- /dev/null +++ b/libphobos/testsuite/libphobos.config/test22523.d @@ -0,0 +1,11 @@ +// https://issues.dlang.org/show_bug.cgi?id=22523 + +import core.stdc.stdio; + +int main() +{ + puts("Executed main although it should be skipped!"); + return 1; +} + +unittest {}