aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-07-06 19:45:28 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2022-07-06 19:51:38 +0200
commit208fbc779c713715da1465a1a2c6710c084c9b05 (patch)
treef8698626e4c2fd65701eddf36918ebf4f2cc6763 /gcc
parentc785204735b2cace9a676969de0967105a06438d (diff)
downloadgcc-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/MERGE2
-rw-r--r--gcc/d/dmd/cparse.d118
-rw-r--r--gcc/d/dmd/dmodule.d2
-rw-r--r--gcc/d/dmd/expressionsem.d8
-rw-r--r--gcc/d/dmd/globals.d2
-rw-r--r--gcc/d/dmd/globals.h2
-rw-r--r--gcc/d/dmd/hdrgen.d17
-rw-r--r--gcc/d/dmd/mtype.d15
-rw-r--r--gcc/d/dmd/tokens.d5
-rw-r--r--gcc/d/dmd/tokens.h1
-rw-r--r--gcc/d/dmd/typesem.d9
-rw-r--r--gcc/testsuite/gdc.test/compilable/test3004.d4
-rw-r--r--gcc/testsuite/gdc.test/compilable/vcg-ast.d3
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag_in_array.d20
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;
+}