diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-07-06 19:45:28 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-07-06 19:51:38 +0200 |
commit | 208fbc779c713715da1465a1a2c6710c084c9b05 (patch) | |
tree | f8698626e4c2fd65701eddf36918ebf4f2cc6763 /gcc | |
parent | c785204735b2cace9a676969de0967105a06438d (diff) | |
download | gcc-208fbc779c713715da1465a1a2c6710c084c9b05.zip gcc-208fbc779c713715da1465a1a2c6710c084c9b05.tar.gz gcc-208fbc779c713715da1465a1a2c6710c084c9b05.tar.bz2 |
d: Merge upstream dmd 56589f0f4, druntime 651389b5, phobos 1516ecad9.
D front-end changes:
- Import latest bug fixes to mainline.
D runtime changes:
- Import latest bug fixes to mainline.
Phobos changes:
- Import latest bug fixes to mainline.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 56589f0f4.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 651389b5.
* src/MERGE: Merge upstream phobos 1516ecad9.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/d/dmd/MERGE | 2 | ||||
-rw-r--r-- | gcc/d/dmd/cparse.d | 118 | ||||
-rw-r--r-- | gcc/d/dmd/dmodule.d | 2 | ||||
-rw-r--r-- | gcc/d/dmd/expressionsem.d | 8 | ||||
-rw-r--r-- | gcc/d/dmd/globals.d | 2 | ||||
-rw-r--r-- | gcc/d/dmd/globals.h | 2 | ||||
-rw-r--r-- | gcc/d/dmd/hdrgen.d | 17 | ||||
-rw-r--r-- | gcc/d/dmd/mtype.d | 15 | ||||
-rw-r--r-- | gcc/d/dmd/tokens.d | 5 | ||||
-rw-r--r-- | gcc/d/dmd/tokens.h | 1 | ||||
-rw-r--r-- | gcc/d/dmd/typesem.d | 9 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/compilable/test3004.d | 4 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/compilable/vcg-ast.d | 3 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/fail_compilation/diag_in_array.d | 20 |
14 files changed, 173 insertions, 35 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index f5c42f0..8324c1c 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -529110f66d7d301d62d943a4e4482edaddeb46ea +56589f0f4d724c1c8022c57509a243f16a04228a 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 dff7634..a3bebb7 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -1619,6 +1619,12 @@ final class CParser(AST) : Parser!AST return; } + if (token.value == TOK.__pragma) + { + uupragmaDirective(scanloc); + return; + } + if (token.value == TOK._import) // import declaration extension { auto a = parseImport(); @@ -2322,6 +2328,14 @@ final class CParser(AST) : Parser!AST break; } + case TOK.__declspec: + { + /* Microsoft extension + */ + cparseDeclspec(specifier); + break; + } + case TOK.typeof_: { nextToken(); @@ -3042,9 +3056,13 @@ final class CParser(AST) : Parser!AST * extended-decl-modifier: * dllimport * dllexport + * noreturn + * Params: + * specifier = filled in with the attribute(s) */ - private void cparseDeclspec() + private void cparseDeclspec(ref Specifier specifier) { + //printf("cparseDeclspec()\n"); /* Check for dllexport, dllimport * Ignore the rest */ @@ -3073,6 +3091,11 @@ final class CParser(AST) : Parser!AST dllexport = true; nextToken(); } + else if (token.ident == Id.noreturn) + { + specifier.noreturn = true; + nextToken(); + } else { nextToken(); @@ -3083,8 +3106,8 @@ final class CParser(AST) : Parser!AST else { error("extended-decl-modifier expected"); + break; } - break; } } @@ -4789,6 +4812,8 @@ final class CParser(AST) : Parser!AST // type function itself. if (auto tf = t.isTypeFunction()) tf.next = tf.next.addSTC(STC.const_); + else if (auto tt = t.isTypeTag()) + tt.mod |= MODFlags.const_; else t = t.addSTC(STC.const_); return t; @@ -4961,11 +4986,41 @@ final class CParser(AST) : Parser!AST return true; } } - error("C preprocessor directive `#%s` is not supported", n.toChars()); + if (n.ident != Id.undef) + error("C preprocessor directive `#%s` is not supported", n.toChars()); return false; } /********************************************* + * VC __pragma + * https://docs.microsoft.com/en-us/cpp/preprocessor/pragma-directives-and-the-pragma-keyword?view=msvc-170 + * Scanner is on the `__pragma` + * Params: + * startloc = location to use for error messages + */ + private void uupragmaDirective(const ref Loc startloc) + { + const loc = startloc; + nextToken(); + if (token.value != TOK.leftParenthesis) + { + error(loc, "left parenthesis expected to follow `__pragma`"); + return; + } + nextToken(); + if (token.value == TOK.identifier && token.ident == Id.pack) + pragmaPack(startloc, false); + else + error(loc, "unrecognized __pragma"); + if (token.value != TOK.rightParenthesis) + { + error(loc, "right parenthesis expected to close `__pragma(...)`"); + return; + } + nextToken(); + } + + /********************************************* * C11 6.10.6 Pragma directive * # pragma pp-tokens(opt) new-line * The C preprocessor sometimes leaves pragma directives in @@ -4977,7 +5032,7 @@ final class CParser(AST) : Parser!AST Token n; scan(&n); if (n.value == TOK.identifier && n.ident == Id.pack) - return pragmaPack(loc); + return pragmaPack(loc, true); if (n.value != TOK.endOfLine) skipToNextLine(); } @@ -4989,10 +5044,27 @@ final class CParser(AST) : Parser!AST * Scanner is on the `pack` * Params: * startloc = location to use for error messages + * useScan = use scan() to retrieve next token, instead of nextToken() */ - private void pragmaPack(const ref Loc startloc) + private void pragmaPack(const ref Loc startloc, bool useScan) { const loc = startloc; + + /* Pull tokens from scan() or nextToken() + */ + void scan(Token* t) + { + if (useScan) + { + Lexer.scan(t); + } + else + { + nextToken(); + *t = token; + } + } + Token n; scan(&n); if (n.value != TOK.leftParenthesis) @@ -5155,13 +5227,35 @@ final class CParser(AST) : Parser!AST { if (!defines || defines.length < 10) // minimum length of a #define line return; - const length = defines.length; - defines.writeByte(0); - auto slice = defines.peekChars()[0 .. length]; + OutBuffer* buf = defines; + defines = null; // prevent skipToNextLine() and parseSpecialTokenSequence() + // from appending to slice[] + const length = buf.length; + buf.writeByte(0); + auto slice = buf.peekChars()[0 .. length]; resetDefineLines(slice); // reset lexer const(char)* endp = &slice[length - 7]; + size_t[void*] defineTab; // hash table of #define's turned into Symbol's + // indexed by Identifier, returns index into symbols[] + // The memory for this is leaked + + void addVar(AST.VarDeclaration v) + { + /* If it's already defined, replace the earlier + * definition + */ + if (size_t* pd = cast(void*)v.ident in defineTab) + { + //printf("replacing %s\n", v.toChars()); + (*symbols)[*pd] = v; + return; + } + defineTab[cast(void*)v.ident] = symbols.length; + symbols.push(v); + } + Token n; while (p < endp) @@ -5200,7 +5294,7 @@ final class CParser(AST) : Parser!AST */ AST.Expression e = new AST.IntegerExp(scanloc, intvalue, t); auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest); - symbols.push(v); + addVar(v); nextDefineLine(); continue; } @@ -5223,7 +5317,7 @@ final class CParser(AST) : Parser!AST */ AST.Expression e = new AST.RealExp(scanloc, floatvalue, t); auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest); - symbols.push(v); + addVar(v); nextDefineLine(); continue; } @@ -5241,7 +5335,7 @@ final class CParser(AST) : Parser!AST */ AST.Expression e = new AST.StringExp(scanloc, str[0 .. len], len, 1, postfix); auto v = new AST.VarDeclaration(scanloc, null, id, new AST.ExpInitializer(scanloc, e), STC.manifest); - symbols.push(v); + addVar(v); nextDefineLine(); continue; } @@ -5263,6 +5357,8 @@ final class CParser(AST) : Parser!AST } nextDefineLine(); } + + defines = buf; } //} diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index f8e5073a..0be938f 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -680,7 +680,7 @@ extern (C++) final class Module : Package FileName.equalsExt(srcfile.toString(), c_ext) && FileName.exists(srcfile.toString())) { - filename = global.preprocess(srcfile, loc, global.params.cppswitches, ifile, &defines); // run C preprocessor + filename = global.preprocess(srcfile, loc, ifile, &defines); // run C preprocessor } if (auto result = global.fileManager.lookup(filename)) diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 99e003b..35ba5fa 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -11689,6 +11689,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor case Terror: return setError(); + case Tarray, Tsarray: + result = exp.incompatibleTypes(); + exp.errorSupplemental("`in` is only allowed on associative arrays"); + const(char)* slice = (t2b.ty == Tsarray) ? "[]" : ""; + exp.errorSupplemental("perhaps use `std.algorithm.find(%s, %s%s)` instead", + exp.e1.toChars(), exp.e2.toChars(), slice); + return; + default: result = exp.incompatibleTypes(); return; diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 3766a0b..05886f9 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -299,7 +299,7 @@ extern (C++) struct Global enum recursionLimit = 500; /// number of recursive template expansions before abort - extern (C++) FileName function(FileName, ref const Loc, ref Array!(const(char)*) cppswitches, out bool, OutBuffer* defines) preprocess; + extern (C++) FileName function(FileName, ref const Loc, out bool, OutBuffer*) preprocess; nothrow: diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 07298dd..41472b2 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -272,7 +272,7 @@ struct Global FileManager* fileManager; - FileName (*preprocess)(FileName, const Loc&, Array<const char *>& cppswitches, bool&, OutBuffer&); + FileName (*preprocess)(FileName, const Loc&, bool&, OutBuffer&); /* Start gagging. Return the current number of gagged errors */ diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index fcc9b61..680d9c8 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -1449,7 +1449,20 @@ public: buf.writestring(" = "); if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); - d.aliassym.accept(this); + /* + https://issues.dlang.org/show_bug.cgi?id=23223 + https://issues.dlang.org/show_bug.cgi?id=23222 + This special case (initially just for modules) avoids some segfaults + and nicer -vcg-ast output. + */ + if (d.aliassym.isModule()) + { + buf.writestring(d.aliassym.ident.toString()); + } + else + { + d.aliassym.accept(this); + } } else if (d.type.ty == Tfunction) { @@ -3916,6 +3929,8 @@ private void typeToBufferx(Type t, OutBuffer* buf, HdrGenState* hgs) void visitTag(TypeTag t) { + if (t.mod & MODFlags.const_) + buf.writestring("const "); buf.writestring(Token.toChars(t.tok)); buf.writeByte(' '); if (t.id) diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 6b5389d..860cfa9 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -4437,15 +4437,7 @@ extern (C++) final class TypeFunction : TypeNext // Check escaping through `this` if (tthis && tthis.isMutable()) { - auto tb = tthis.toBasetype(); - AggregateDeclaration ad; - if (auto tc = tb.isTypeClass()) - ad = tc.sym; - else if (auto ts = tb.isTypeStruct()) - ad = ts.sym; - else - assert(0); - foreach (VarDeclaration v; ad.fields) + foreach (VarDeclaration v; isAggregate(tthis).fields) { if (v.hasPointers()) return stc; @@ -6655,16 +6647,18 @@ extern (C++) final class TypeTag : Type Type resolved; /// type after semantic() in case there are more others /// pointing to this instance, which can happen with /// struct S { int a; } s1, *s2; + MOD mod; /// modifiers to apply after type is resolved (only MODFlags.const_ at the moment) extern (D) this(const ref Loc loc, TOK tok, Identifier id, Type base, Dsymbols* members) { - //printf("TypeTag %p\n", this); + //printf("TypeTag ctor %s %p\n", id ? id.toChars() : "null".ptr, this); super(Ttag); this.loc = loc; this.tok = tok; this.id = id; this.base = base; this.members = members; + this.mod = 0; } override const(char)* kind() const @@ -6674,6 +6668,7 @@ extern (C++) final class TypeTag : Type override TypeTag syntaxCopy() { + //printf("TypeTag syntaxCopy()\n"); // No semantic analysis done, no need to copy return this; } diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d index 170a534..86abedf 100644 --- a/gcc/d/dmd/tokens.d +++ b/gcc/d/dmd/tokens.d @@ -273,6 +273,7 @@ enum TOK : ubyte __cdecl, __declspec, __stdcall, + __pragma, __attribute__, } @@ -582,6 +583,7 @@ private immutable TOK[] keywords = TOK.__cdecl, TOK.__declspec, TOK.__stdcall, + TOK.__pragma, TOK.__attribute__, ]; @@ -610,7 +612,7 @@ static immutable TOK[TOK.max + 1] Ckeywords = restrict, return_, int16, signed, sizeof_, static_, struct_, switch_, typedef_, union_, unsigned, void_, volatile, while_, asm_, typeof_, _Alignas, _Alignof, _Atomic, _Bool, _Complex, _Generic, _Imaginary, _Noreturn, - _Static_assert, _Thread_local, _import, __cdecl, __declspec, __stdcall, __attribute__ ]; + _Static_assert, _Thread_local, _import, __cdecl, __declspec, __stdcall, __pragma, __attribute__ ]; foreach (kw; Ckwds) tab[kw] = cast(TOK) kw; @@ -880,6 +882,7 @@ extern (C++) struct Token TOK.__cdecl : "__cdecl", TOK.__declspec : "__declspec", TOK.__stdcall : "__stdcall", + TOK.__pragma : "__pragma", TOK.__attribute__ : "__attribute__", ]; diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h index f9b6062..35fd68b 100644 --- a/gcc/d/dmd/tokens.h +++ b/gcc/d/dmd/tokens.h @@ -282,6 +282,7 @@ enum class TOK : unsigned char cdecl_, declspec, stdcall, + pragma, attribute__, MAX, diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index 8cacdb1..0469b92 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -1778,8 +1778,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) { /* struct S s, *p; */ - //printf("already resolved\n"); - return mtype.resolved; + return mtype.resolved.addSTC(mtype.mod); } /* Find the current scope by skipping tag scopes. @@ -1850,7 +1849,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) { mtype.id = Identifier.generateId("__tag"[]); declareTag(); - return mtype.resolved; + return mtype.resolved.addSTC(mtype.mod); } /* look for pre-existing declaration @@ -1863,7 +1862,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) if (mtype.tok == TOK.enum_ && !mtype.members) .error(mtype.loc, "`enum %s` is incomplete without members", mtype.id.toChars()); // C11 6.7.2.3-3 declareTag(); - return mtype.resolved; + return mtype.resolved.addSTC(mtype.mod); } /* A redeclaration only happens if both declarations are in @@ -1963,7 +1962,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) declareTag(); } } - return mtype.resolved; + return mtype.resolved.addSTC(mtype.mod); } switch (type.ty) diff --git a/gcc/testsuite/gdc.test/compilable/test3004.d b/gcc/testsuite/gdc.test/compilable/test3004.d index 9912b88..23ec46f 100644 --- a/gcc/testsuite/gdc.test/compilable/test3004.d +++ b/gcc/testsuite/gdc.test/compilable/test3004.d @@ -1,15 +1,13 @@ // https://issues.dlang.org/show_bug.cgi?id=3004 /* REQUIRED_ARGS: -ignore -v -TRANSFORM_OUTPUT: remove_lines("^(predefs|binary|version|config|DFLAG|parse|import|semantic|entry|library|function object|\s*$)") +TRANSFORM_OUTPUT: remove_lines("^(predefs|binary|version|config|DFLAG|parse|import|semantic|entry|library|function object|function core|\s*$)") TEST_OUTPUT: --- pragma GNU_attribute (__error) pragma GNU_attribute (__error) code test3004 function test3004.test -function core.internal.array.appending._d_arrayappendcTXImpl!(char[], char)._d_arrayappendcTX -function core.internal.array.utils._d_HookTraceImpl!(char[], _d_arrayappendcTX, "Cannot append to array if compiling without support for runtime type information!")._d_HookTraceImpl --- */ diff --git a/gcc/testsuite/gdc.test/compilable/vcg-ast.d b/gcc/testsuite/gdc.test/compilable/vcg-ast.d index cbb150c..4a7b8bc 100644 --- a/gcc/testsuite/gdc.test/compilable/vcg-ast.d +++ b/gcc/testsuite/gdc.test/compilable/vcg-ast.d @@ -7,6 +7,9 @@ TEST_OUTPUT_FILE: extra-files/vcg-ast.d.cg module vcg; +alias xyz = __traits(parent, {}); +alias named = vcg; + template Seq(A...) { alias Seq = A; diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_in_array.d b/gcc/testsuite/gdc.test/fail_compilation/diag_in_array.d new file mode 100644 index 0000000..f869b32 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/diag_in_array.d @@ -0,0 +1,20 @@ +/** +TEST_OUTPUT: +--- +fail_compilation/diag_in_array.d(17): Error: incompatible types for `(3) in (a)`: `int` and `int[4]` +fail_compilation/diag_in_array.d(17): `in` is only allowed on associative arrays +fail_compilation/diag_in_array.d(17): perhaps use `std.algorithm.find(3, a[])` instead +fail_compilation/diag_in_array.d(19): Error: incompatible types for `("s") in (b)`: `string` and `string[]` +fail_compilation/diag_in_array.d(19): `in` is only allowed on associative arrays +fail_compilation/diag_in_array.d(19): perhaps use `std.algorithm.find("s", b)` instead +--- +*/ + +void main() +{ + int[4] a; + string[] b; + if (3 in a) + return; + auto c = "s" in b; +} |