* [committed][GCC 12] d: Fix internal compiler error: in layout_aggregate_type, at d/types.cc:574
@ 2023-08-15 15:18 Iain Buclaw
0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2023-08-15 15:18 UTC (permalink / raw)
To: gcc-patches; +Cc: Iain Buclaw
Hi,
This patch fixes an ICE that is specific to the D front-end language
version in GDC 12.
Bootstrapped and regression tested on x86_64-linux-gnu/-m32, committed
to releases/gcc-12.
The pr110959.d test case has also been committed to mainline to catch
the unlikely event of a regression.
Regards,
Iain.
---
PR d/110959
gcc/d/ChangeLog:
* dmd/canthrow.d (Dsymbol_canThrow): Use foreachVar.
* dmd/declaration.d (TupleDeclaration::needThis): Likewise.
(TupleDeclaration::foreachVar): New function.
(VarDeclaration::setFieldOffset): Use foreachVar.
* dmd/dinterpret.d (Interpreter::visit (DeclarationExp)): Likewise.
* dmd/dsymbolsem.d (DsymbolSemanticVisitor::visit (VarDeclaration)):
Don't push tuple field members to the scope symbol table.
(determineFields): Handle pushing tuple field members here instead.
* dmd/dtoh.d (ToCppBuffer::visit (VarDeclaration)): Visit all tuple
fields.
(ToCppBuffer::visit (TupleDeclaration)): New function.
* dmd/expression.d (expandAliasThisTuples): Use foreachVar.
* dmd/foreachvar.d (VarWalker::visit (DeclarationExp)): Likewise.
* dmd/ob.d (genKill): Likewise.
(checkObErrors): Likewise.
* dmd/semantic2.d (Semantic2Visitor::visit (TupleDeclaration)): Visit
all tuple fields.
gcc/testsuite/ChangeLog:
* gdc.dg/pr110959.d: New test.
* gdc.test/runnable/test23010.d: New test.
---
gcc/d/dmd/canthrow.d | 13 +----
gcc/d/dmd/declaration.d | 63 +++++++++++++--------
gcc/d/dmd/dinterpret.d | 17 +++---
gcc/d/dmd/dsymbolsem.d | 17 +++---
gcc/d/dmd/dtoh.d | 11 ++++
gcc/d/dmd/expression.d | 8 ++-
gcc/d/dmd/foreachvar.d | 14 +----
gcc/d/dmd/ob.d | 22 +------
gcc/d/dmd/semantic2.d | 5 ++
gcc/testsuite/gdc.dg/pr110959.d | 32 +++++++++++
gcc/testsuite/gdc.test/runnable/test23010.d | 43 ++++++++++++++
11 files changed, 153 insertions(+), 92 deletions(-)
create mode 100644 gcc/testsuite/gdc.dg/pr110959.d
create mode 100644 gcc/testsuite/gdc.test/runnable/test23010.d
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index a38cbb1610b..fe6e1e344b9 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -270,18 +270,7 @@ private CT Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow)
}
else if (auto td = s.isTupleDeclaration())
{
- for (size_t i = 0; i < td.objects.dim; i++)
- {
- RootObject o = (*td.objects)[i];
- if (o.dyncast() == DYNCAST.expression)
- {
- Expression eo = cast(Expression)o;
- if (auto se = eo.isDsymbolExp())
- {
- result |= Dsymbol_canThrow(se.s, func, mustNotThrow);
- }
- }
- }
+ td.foreachVar(&symbolDg);
}
return result;
}
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 7b50c050487..6c83c196f72 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -656,23 +656,46 @@ extern (C++) final class TupleDeclaration : Declaration
override bool needThis()
{
//printf("TupleDeclaration::needThis(%s)\n", toChars());
- for (size_t i = 0; i < objects.dim; i++)
+ return isexp ? foreachVar((s) { return s.needThis(); }) != 0 : false;
+ }
+
+ /***********************************************************
+ * Calls dg(Dsymbol) for each Dsymbol, which should be a VarDeclaration
+ * inside DsymbolExp (isexp == true).
+ * Params:
+ * dg = delegate to call for each Dsymbol
+ */
+ extern (D) void foreachVar(scope void delegate(Dsymbol) dg)
+ {
+ assert(isexp);
+ foreach (o; *objects)
{
- RootObject o = (*objects)[i];
- if (o.dyncast() == DYNCAST.expression)
- {
- Expression e = cast(Expression)o;
- if (DsymbolExp ve = e.isDsymbolExp())
- {
- Declaration d = ve.s.isDeclaration();
- if (d && d.needThis())
- {
- return true;
- }
- }
- }
+ if (auto e = o.isExpression())
+ if (auto se = e.isDsymbolExp())
+ dg(se.s);
}
- return false;
+ }
+
+ /***********************************************************
+ * Calls dg(Dsymbol) for each Dsymbol, which should be a VarDeclaration
+ * inside DsymbolExp (isexp == true).
+ * If dg returns !=0, stops and returns that value else returns 0.
+ * Params:
+ * dg = delegate to call for each Dsymbol
+ * Returns:
+ * last value returned by dg()
+ */
+ extern (D) int foreachVar(scope int delegate(Dsymbol) dg)
+ {
+ assert(isexp);
+ foreach (o; *objects)
+ {
+ if (auto e = o.isExpression())
+ if (auto se = e.isDsymbolExp())
+ if(auto ret = dg(se.s))
+ return ret;
+ }
+ return 0;
}
override inout(TupleDeclaration) isTupleDeclaration() inout
@@ -1142,15 +1165,7 @@ extern (C++) class VarDeclaration : Declaration
// If this variable was really a tuple, set the offsets for the tuple fields
TupleDeclaration v2 = aliassym.isTupleDeclaration();
assert(v2);
- for (size_t i = 0; i < v2.objects.dim; i++)
- {
- RootObject o = (*v2.objects)[i];
- assert(o.dyncast() == DYNCAST.expression);
- Expression e = cast(Expression)o;
- assert(e.op == EXP.dSymbol);
- DsymbolExp se = e.isDsymbolExp();
- se.s.setFieldOffset(ad, fieldState, isunion);
- }
+ v2.foreachVar((s) { s.setFieldOffset(ad, fieldState, isunion); });
return;
}
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index e96f1806982..485b2dec1a1 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -2291,16 +2291,12 @@ public:
result = null;
// Reserve stack space for all tuple members
- if (!td.objects)
- return;
- foreach (o; *td.objects)
+ td.foreachVar((s)
{
- Expression ex = isExpression(o);
- DsymbolExp ds = ex ? ex.isDsymbolExp() : null;
- VarDeclaration v2 = ds ? ds.s.isVarDeclaration() : null;
+ VarDeclaration v2 = s.isVarDeclaration();
assert(v2);
if (v2.isDataseg() && !v2.isCTFE())
- continue;
+ return 0;
ctfeGlobals.stack.push(v2);
if (v2._init)
@@ -2310,7 +2306,7 @@ public:
{
einit = interpretRegion(ie.exp, istate, goal);
if (exceptionOrCant(einit))
- return;
+ return 1;
}
else if (v2._init.isVoidInitializer())
{
@@ -2320,11 +2316,12 @@ public:
{
e.error("declaration `%s` is not yet implemented in CTFE", e.toChars());
result = CTFEExp.cantexp;
- return;
+ return 1;
}
setValue(v2, einit);
}
- }
+ return 0;
+ });
return;
}
if (v.isStatic())
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index c5766787bf0..dfaaff93d35 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -650,7 +650,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
else
ti = dsym._init ? dsym._init.syntaxCopy() : null;
- StorageClass storage_class = STC.temp | STC.local | dsym.storage_class;
+ StorageClass storage_class = STC.temp | dsym.storage_class;
if ((dsym.storage_class & STC.parameter) && (arg.storageClass & STC.parameter))
storage_class |= arg.storageClass;
auto v = new VarDeclaration(dsym.loc, arg.type, id, ti, storage_class);
@@ -659,14 +659,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
v.dsymbolSemantic(sc);
- if (sc.scopesym)
- {
- //printf("adding %s to %s\n", v.toChars(), sc.scopesym.toChars());
- if (sc.scopesym.members)
- // Note this prevents using foreach() over members, because the limits can change
- sc.scopesym.members.push(v);
- }
-
Expression e = new DsymbolExp(dsym.loc, v);
(*exps)[i] = e;
}
@@ -6819,7 +6811,12 @@ bool determineFields(AggregateDeclaration ad)
return 1;
if (v.aliassym)
- return 0; // If this variable was really a tuple, skip it.
+ {
+ // If this variable was really a tuple, process each element.
+ if (auto tup = v.aliassym.isTupleDeclaration())
+ return tup.foreachVar(tv => tv.apply(&func, ad));
+ return 0;
+ }
if (v.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.ctfe | STC.templateparameter))
return 0;
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index 17abb7d3b00..ecc637eff53 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -877,7 +877,11 @@ public:
// Tuple field are expanded into multiple VarDeclarations
// (we'll visit them later)
if (vd.type && vd.type.isTypeTuple())
+ {
+ assert(vd.aliassym);
+ vd.toAlias().accept(this);
return;
+ }
if (vd.originalType && vd.type == AST.Type.tsize_t)
origType = vd.originalType;
@@ -1667,6 +1671,13 @@ public:
assert(false, "This node type should be handled in the EnumDeclaration");
}
+ override void visit(AST.TupleDeclaration tup)
+ {
+ debug (Debug_DtoH) mixin(traceVisit!tup);
+
+ tup.foreachVar((s) { s.accept(this); });
+ }
+
/**
* Prints a member/parameter/variable declaration into `buf`.
*
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 107e85b0793..832ab7dda37 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -348,14 +348,16 @@ int expandAliasThisTuples(Expressions* exps, size_t starti = 0)
if (TupleDeclaration td = exp.isAliasThisTuple)
{
exps.remove(u);
- foreach (i, o; *td.objects)
+ size_t i;
+ td.foreachVar((s)
{
- auto d = o.isExpression().isDsymbolExp().s.isDeclaration();
+ auto d = s.isDeclaration();
auto e = new DotVarExp(exp.loc, exp, d);
assert(d.type);
e.type = d.type;
exps.insert(u + i, e);
- }
+ ++i;
+ });
version (none)
{
printf("expansion ->\n");
diff --git a/gcc/d/dmd/foreachvar.d b/gcc/d/dmd/foreachvar.d
index 53ed62efd70..63281b5760c 100644
--- a/gcc/d/dmd/foreachvar.d
+++ b/gcc/d/dmd/foreachvar.d
@@ -75,19 +75,7 @@ void foreachVar(Expression e, void delegate(VarDeclaration) dgVar)
if (!v)
return;
if (TupleDeclaration td = v.toAlias().isTupleDeclaration())
- {
- if (!td.objects)
- return;
- foreach (o; *td.objects)
- {
- Expression ex = isExpression(o);
- DsymbolExp s = ex ? ex.isDsymbolExp() : null;
- assert(s);
- VarDeclaration v2 = s.s.isVarDeclaration();
- assert(v2);
- dgVar(v2);
- }
- }
+ td.foreachVar((s) { dgVar(s.isVarDeclaration()); });
else
dgVar(v);
Dsymbol s = v.toAlias();
diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d
index 121a266b428..5ff73c983f0 100644
--- a/gcc/d/dmd/ob.d
+++ b/gcc/d/dmd/ob.d
@@ -1407,16 +1407,7 @@ void genKill(ref ObState obstate, ObNode* ob)
}
else if (auto td = s.isTupleDeclaration())
{
- foreach (o; *td.objects)
- {
- if (auto eo = o.isExpression())
- {
- if (auto se = eo.isDsymbolExp())
- {
- Dsymbol_visit(se.s);
- }
- }
- }
+ td.foreachVar(&Dsymbol_visit);
}
}
@@ -2107,16 +2098,7 @@ void checkObErrors(ref ObState obstate)
}
else if (auto td = s.isTupleDeclaration())
{
- foreach (o; *td.objects)
- {
- if (auto eo = o.isExpression())
- {
- if (auto se = eo.isDsymbolExp())
- {
- Dsymbol_visit(se.s);
- }
- }
- }
+ td.foreachVar(&Dsymbol_visit);
}
}
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index 73dcaa6c960..bf18a2140fb 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -677,6 +677,11 @@ private extern(C++) final class Semantic2Visitor : Visitor
{
visit(cast(AggregateDeclaration) cd);
}
+
+ override void visit(TupleDeclaration td)
+ {
+ td.foreachVar((s) { s.accept(this); });
+ }
}
/**
diff --git a/gcc/testsuite/gdc.dg/pr110959.d b/gcc/testsuite/gdc.dg/pr110959.d
new file mode 100644
index 00000000000..b1da90fad83
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110959.d
@@ -0,0 +1,32 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110959
+// { dg-do compile }
+class ArsdExceptionBase : object.Exception {
+ this(string operation, string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
+ super(operation, file, line, next);
+ }
+}
+
+template ArsdException(alias Type, DataTuple...) {
+ static if(DataTuple.length)
+ alias Parent = ArsdException!(Type, DataTuple[0 .. $-1]);
+ else
+ alias Parent = ArsdExceptionBase;
+
+ class ArsdException : Parent {
+ DataTuple data;
+
+ this(DataTuple data, string file = __FILE__, size_t line = __LINE__) {
+ this.data = data;
+ static if(is(Parent == ArsdExceptionBase))
+ super(null, file, line);
+ else
+ super(data[0 .. $-1], file, line);
+ }
+
+ static opCall(R...)(R r, string file = __FILE__, size_t line = __LINE__) {
+ return new ArsdException!(Type, DataTuple, R)(r, file, line);
+ }
+ }
+}
+
+__gshared pr110959 = ArsdException!"Test"(4, "four");
diff --git a/gcc/testsuite/gdc.test/runnable/test23010.d b/gcc/testsuite/gdc.test/runnable/test23010.d
new file mode 100644
index 00000000000..1cbacfc9279
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test23010.d
@@ -0,0 +1,43 @@
+// https://issues.dlang.org/show_bug.cgi?id=23010
+
+alias AliasSeq(T...) = T;
+
+mixin template faz() {
+ alias T = AliasSeq!(int);
+ T bar = 12345;
+
+ void write1() {
+ assert(bar[0] == 12345);
+ }
+
+ AliasSeq!(string, float) foo = AliasSeq!("qwerty", 1.25f);
+
+ void write2() {
+ assert(foo == AliasSeq!("qwerty", 1.25f));
+ foo = AliasSeq!("asdfg", 2.5f); // this even crashed before
+ assert(foo == AliasSeq!("asdfg", 2.5f));
+ }
+}
+
+void main() {
+ mixin faz!();
+ write1;
+ write2;
+ fun;
+}
+
+// Testing static symbol generation ('toobj.d' changes)
+
+static AliasSeq!(int, string) tup;
+
+void fun()
+{
+ auto v = tup;
+
+ struct S(T...) {
+ static T b;
+ }
+
+ alias T = S!(int, float);
+ auto p = T.b;
+}
--
2.39.2
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-08-15 15:18 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-15 15:18 [committed][GCC 12] d: Fix internal compiler error: in layout_aggregate_type, at d/types.cc:574 Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).