From patchwork Thu Apr 28 11:08:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1623593 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=JhDe0uk0; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KptDy4Tn8z9s0r for ; Thu, 28 Apr 2022 21:09:53 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E8C7A3858405 for ; Thu, 28 Apr 2022 11:09:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E8C7A3858405 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1651144190; bh=+h2fpIHwuQuuG3IBoDXuSePYjvksgQPXBQLxuuq9+CM=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=JhDe0uk0vniqH5E3LP1be+vTk6fdMoq4v0oIMdt9o5p6+jD12etpNxNeEH+mLJXcW XrWAaRxlBqWqBlw/3RJwmsDIH7gLyJTonFWkNIT5gpsrSu1+hTPDunigCIf6VkuKGN rWGCMfvmINDkDlxN4eB/8MmZU00m7cuatR8ebgXU= 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:0:465::101]) by sourceware.org (Postfix) with ESMTPS id E39FF3857357 for ; Thu, 28 Apr 2022 11:08:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E39FF3857357 Received: from smtp202.mailbox.org (smtp202.mailbox.org [10.196.197.202]) (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 4KptCh6K4Fz9sVt; Thu, 28 Apr 2022 13:08:48 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Merge upstream dmd 313d28b3d, druntime e361d200. Date: Thu, 28 Apr 2022 13:08:42 +0200 Message-Id: <20220428110842.371285-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Hi, This patches merges the D front-end with upstream dmd 313d28b3d, and the D runtime library with upstream druntime e361d200. D front-end changes: - Import latest bug fixes from the 2.100 release branch. - Fix signatures of extern C++ functions that have size_t parameters. Bootstrapped and regression tested on x86_64-linux-gnu, and i686-apple-darwin14. Committed to mainline. Regards, Iain. --- gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 313d28b3d. * d-port.cc (Port::memicmp): Use d_size_t instead of size_t. (Port::valcpy): Likewise. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime e361d200. --- gcc/d/d-port.cc | 8 +- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/cparse.d | 95 +++++++++++++++---- gcc/d/dmd/dscope.d | 2 + gcc/d/dmd/expression.h | 6 +- gcc/d/dmd/expressionsem.d | 29 ++++-- gcc/d/dmd/root/port.h | 5 +- .../gdc.test/compilable/revert_dip1000.d | 7 ++ libphobos/libdruntime/MERGE | 2 +- 9 files changed, 121 insertions(+), 35 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/revert_dip1000.d diff --git a/gcc/d/d-port.cc b/gcc/d/d-port.cc index a0e06b37683..a908cc8dbb0 100644 --- a/gcc/d/d-port.cc +++ b/gcc/d/d-port.cc @@ -31,11 +31,11 @@ along with GCC; see the file COPYING3. If not see /* Compare the first N bytes of S1 and S2 without regard to the case. */ int -Port::memicmp (const char *s1, const char *s2, size_t n) +Port::memicmp (const char *s1, const char *s2, d_size_t n) { int result = 0; - for (size_t i = 0; i < n; i++) + for (d_size_t i = 0; i < n; i++) { char c1 = s1[i]; char c2 = s2[i]; @@ -143,9 +143,9 @@ Port::readlongBE (const void *buffer) /* Write an SZ-byte sized VALUE to BUFFER, ignoring endian-ness. */ void -Port::valcpy (void *buffer, uint64_t value, size_t sz) +Port::valcpy (void *buffer, uint64_t value, d_size_t sz) { - gcc_assert (((size_t) buffer) % sz == 0); + gcc_assert (((d_size_t) buffer) % sz == 0); switch (sz) { diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 2bc9b95b5e2..d18119193d4 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -eb7bee331a13026eeb4dcbf9d43d5d4e744a4d26 +313d28b3db7523e67880ae3baf8ef28ce9abe9bd The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index 53bf26ec927..2b2046f3da3 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -213,16 +213,12 @@ final class CParser(AST) : Parser!AST goto Lexp; case TOK.leftParenthesis: - { - /* If tokens look like a function call, assume it is one, - * As any type-name won't be resolved until semantic, this - * could be rewritten later. - */ - auto tk = &token; - if (isFunctionCall(tk)) - goto Lexp; - goto default; - } + if (auto pt = lookupTypedef(token.ident)) + { + if (*pt) + goto Ldeclaration; + } + goto Lexp; // function call default: { @@ -1626,10 +1622,21 @@ final class CParser(AST) : Parser!AST */ if (token.value == TOK.semicolon) { - nextToken(); if (!tspec) + { + nextToken(); return; // accept empty declaration as an extension + } + + if (auto ti = tspec.isTypeIdentifier()) + { + // C11 6.7.2-2 + error("type-specifier missing for declaration of `%s`", ti.ident.toChars()); + nextToken(); + return; + } + nextToken(); auto tt = tspec.isTypeTag(); if (!tt || !tt.id && (tt.tok == TOK.struct_ || tt.tok == TOK.union_)) @@ -1661,6 +1668,22 @@ final class CParser(AST) : Parser!AST specifier.mod &= ~MOD.xnone; // 'used' it } + void scanPastSemicolon() + { + while (token.value != TOK.semicolon && token.value != TOK.endOfFile) + nextToken(); + nextToken(); + } + + if (token.value == TOK.assign && tspec && tspec.isTypeIdentifier()) + { + /* C11 6.7.2-2 + * Special check for `const b = 1;` because some compilers allow it + */ + error("type-specifier omitted for declaration of `%s`", tspec.isTypeIdentifier().ident.toChars()); + return scanPastSemicolon(); + } + bool first = true; while (1) { @@ -1880,10 +1903,7 @@ final class CParser(AST) : Parser!AST default: error("`=`, `;` or `,` expected to end declaration instead of `%s`", token.toChars()); Lend: - while (token.value != TOK.semicolon && token.value != TOK.endOfFile) - nextToken(); - nextToken(); - return; + return scanPastSemicolon(); } } } @@ -2528,7 +2548,14 @@ final class CParser(AST) : Parser!AST default: if (declarator == DTR.xdirect) { - error("identifier or `(` expected"); // ) + if (!t || t.isTypeIdentifier()) + { + // const arr[1]; + error("no type-specifier for declarator"); + t = AST.Type.tint32; + } + else + error("identifier or `(` expected"); // ) panic(); } ts = t; @@ -2744,6 +2771,11 @@ final class CParser(AST) : Parser!AST Specifier specifier; specifier.packalign.setDefault(); auto tspec = cparseSpecifierQualifierList(LVL.global, specifier); + if (!tspec) + { + error("type-specifier is missing"); + tspec = AST.Type.tint32; + } if (tspec && specifier.mod & MOD.xconst) { tspec = toConst(tspec); @@ -2829,8 +2861,18 @@ final class CParser(AST) : Parser!AST Specifier specifier; specifier.packalign.setDefault(); auto tspec = cparseDeclarationSpecifiers(LVL.prototype, specifier); - if (tspec && specifier.mod & MOD.xconst) + if (!tspec) { + error("no type-specifier for parameter"); + tspec = AST.Type.tint32; + } + + if (specifier.mod & MOD.xconst) + { + if ((token.value == TOK.rightParenthesis || token.value == TOK.comma) && + tspec.isTypeIdentifier()) + error("type-specifier omitted for parameter `%s`", tspec.isTypeIdentifier().ident.toChars()); + tspec = toConst(tspec); specifier.mod = MOD.xnone; // 'used' it } @@ -3400,7 +3442,12 @@ final class CParser(AST) : Parser!AST Specifier specifier; specifier.packalign = this.packalign; auto tspec = cparseSpecifierQualifierList(LVL.member, specifier); - if (tspec && specifier.mod & MOD.xconst) + if (!tspec) + { + error("no type-specifier for struct member"); + tspec = AST.Type.tint32; + } + if (specifier.mod & MOD.xconst) { tspec = toConst(tspec); specifier.mod = MOD.xnone; // 'used' it @@ -3413,7 +3460,13 @@ final class CParser(AST) : Parser!AST nextToken(); auto tt = tspec.isTypeTag(); if (!tt) + { + if (auto ti = tspec.isTypeIdentifier()) + { + error("type-specifier omitted before declaration of `%s`", ti.ident.toChars()); + } return; // legal but meaningless empty declaration + } /* If anonymous struct declaration * struct { ... members ... }; @@ -3453,6 +3506,12 @@ final class CParser(AST) : Parser!AST AST.Type dt; if (token.value == TOK.colon) { + if (auto ti = tspec.isTypeIdentifier()) + { + error("type-specifier omitted before bit field declaration of `%s`", ti.ident.toChars()); + tspec = AST.Type.tint32; + } + // C11 6.7.2.1-12 unnamed bit-field id = Identifier.generateAnonymousId("BitField"); dt = tspec; diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d index c3a1d05cd7b..6339a9e36ba 100644 --- a/gcc/d/dmd/dscope.d +++ b/gcc/d/dmd/dscope.d @@ -457,6 +457,8 @@ struct Scope if (sc.scopesym.isModule()) flags |= SearchUnqualifiedModule; // tell Module.search() that SearchLocalsOnly is to be obeyed + else if (sc.flags & SCOPE.Cfile && sc.scopesym.isStructDeclaration()) + continue; // C doesn't have struct scope if (Dsymbol s = sc.scopesym.search(loc, ident, flags)) { diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index a0d63e0023d..330dcdb77ec 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -373,11 +373,11 @@ public: OwnedBy ownedByCtfe; static StringExp *create(const Loc &loc, const char *s); - static StringExp *create(const Loc &loc, const void *s, size_t len); + static StringExp *create(const Loc &loc, const void *s, d_size_t len); static void emplace(UnionExp *pue, const Loc &loc, const char *s); bool equals(const RootObject *o) const; - char32_t getCodeUnit(size_t i) const; - void setCodeUnit(size_t i, char32_t c); + char32_t getCodeUnit(d_size_t i) const; + void setCodeUnit(d_size_t i, char32_t c); StringExp *toStringExp(); StringExp *toUTF8(Scope *sc); Optional toBool(); diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 22a1f45f4e8..d4e96bb0f09 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -5216,13 +5216,30 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (s.ident) { VarDeclaration v = s.isVarDeclaration(); - if (v && !(sc.flags & SCOPE.Cfile)) + if (v) { - /* Do semantic() on initializer first so this will be illegal: - * int a = a; - */ - e.declaration.dsymbolSemantic(sc); - s.parent = sc.parent; + if (sc.flags & SCOPE.Cfile) + { + /* Do semantic() on the type before inserting v into the symbol table + */ + if (!v.originalType) + v.originalType = v.type.syntaxCopy(); + Scope* sc2 = sc.push(); + sc2.stc |= v.storage_class & STC.FUNCATTR; + sc2.linkage = LINK.c; // account for the extern(C) in front of the declaration + v.inuse++; + v.type = v.type.typeSemantic(v.loc, sc2); + v.inuse--; + sc2.pop(); + } + else + { + /* Do semantic() on initializer first so this will be illegal: + * int a = a; + */ + e.declaration.dsymbolSemantic(sc); + s.parent = sc.parent; + } } if (!sc.insert(s)) diff --git a/gcc/d/dmd/root/port.h b/gcc/d/dmd/root/port.h index 069a365addf..66a67605b5c 100644 --- a/gcc/d/dmd/root/port.h +++ b/gcc/d/dmd/root/port.h @@ -13,12 +13,13 @@ // The idea is to minimize #ifdef's in the app code. #include "dsystem.h" +#include "dcompat.h" typedef unsigned char utf8_t; struct Port { - static int memicmp(const char *s1, const char *s2, size_t n); + static int memicmp(const char *s1, const char *s2, d_size_t n); static char *strupr(char *s); static bool isFloat32LiteralOutOfRange(const char *s); @@ -30,5 +31,5 @@ struct Port static unsigned readlongBE(const void *buffer); static unsigned readwordLE(const void *buffer); static unsigned readwordBE(const void *buffer); - static void valcpy(void *dst, uint64_t val, size_t size); + static void valcpy(void *dst, uint64_t val, d_size_t size); }; diff --git a/gcc/testsuite/gdc.test/compilable/revert_dip1000.d b/gcc/testsuite/gdc.test/compilable/revert_dip1000.d new file mode 100644 index 00000000000..ad6a6d8aade --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/revert_dip1000.d @@ -0,0 +1,7 @@ +/* +REQUIRED_ARGS: -revert=dip1000 +TEST_OUTPUT: +--- +--- +*/ +int* oops(scope int* p) @safe { return p; } diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index e08d9cdc0fd..c94634f4770 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -27834edb5e1613e3abd43e09880c36d9fc961938 +e361d200b287a68344095f306cf5ea3a63c080e1 The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository.