[committed] d: Merge upstream dmd cb4a96fae

Iain Buclaw ibuclaw@gdcproject.org
Wed Aug 26 08:15:07 GMT 2020


Hi,

This patch merges the D front-end implementation with upstream dmd
cb4a96fae.  Fixes both a bug where compilation would hang, and an issue
where recursive template limits are hit too early.

Regstrapped on x86_64-linux-gnu/-m32/-mx32, committed to mainline, and
cherry-picked to the releases/gcc-10 branch.

Regards
Iain

---
gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd cb4a96fae
---
 gcc/d/dmd/MERGE                              |  2 +-
 gcc/d/dmd/dmacro.c                           |  7 +++----
 gcc/d/dmd/dtemplate.c                        | 19 +++++++++++++------
 gcc/d/dmd/expressionsem.c                    |  2 +-
 gcc/d/dmd/globals.h                          |  2 ++
 gcc/d/dmd/mtype.c                            |  4 ++--
 gcc/d/dmd/optimize.c                         | 11 ++++++++++-
 gcc/testsuite/gdc.test/compilable/ice20092.d | 10 ++++++++++
 8 files changed, 42 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gdc.test/compilable/ice20092.d

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 8445bfaf343..2dc2ef3d622 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-2cc25c2191928f865e1b711f30b6a4268d6a0d9a
+cb4a96faecb6b521ac4749581bcfa39f61143db0
 
 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/dmacro.c b/gcc/d/dmd/dmacro.c
index 07187612616..cefd3b037aa 100644
--- a/gcc/d/dmd/dmacro.c
+++ b/gcc/d/dmd/dmacro.c
@@ -226,11 +226,10 @@ void Macro::expand(OutBuffer *buf, size_t start, size_t *pend,
 {
     // limit recursive expansion
     static int nest;
-    static const int nestLimit = 1000;
-    if (nest > nestLimit)
+    if (nest > global.recursionLimit)
     {
-        error(Loc(), "DDoc macro expansion limit exceeded; more than %d "
-            "expansions.", nestLimit);
+        error(Loc(), "DDoc macro expansion limit exceeded; more than %d expansions.",
+              global.recursionLimit);
         return;
     }
     nest++;
diff --git a/gcc/d/dmd/dtemplate.c b/gcc/d/dmd/dtemplate.c
index a35721cc9cd..a86daeee633 100644
--- a/gcc/d/dmd/dtemplate.c
+++ b/gcc/d/dmd/dtemplate.c
@@ -4337,6 +4337,13 @@ MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *par
 
         void visit(ArrayLiteralExp *e)
         {
+            // https://issues.dlang.org/show_bug.cgi?id=20092
+            if (e->elements && e->elements->length &&
+                e->type->toBasetype()->nextOf()->ty == Tvoid)
+            {
+                result = deduceEmptyArrayElement();
+                return;
+            }
             if ((!e->elements || !e->elements->length) &&
                 e->type->toBasetype()->nextOf()->ty == Tvoid &&
                 tparam->ty == Tarray)
@@ -5932,10 +5939,10 @@ void TemplateInstance::tryExpandMembers(Scope *sc2)
     static int nest;
     // extracted to a function to allow windows SEH to work without destructors in the same function
     //printf("%d\n", nest);
-    if (++nest > 500)
+    if (++nest > global.recursionLimit)
     {
         global.gag = 0;                 // ensure error message gets printed
-        error("recursive expansion");
+        error("recursive expansion exceeded allowed nesting limit");
         fatal();
     }
 
@@ -5949,10 +5956,10 @@ void TemplateInstance::trySemantic3(Scope *sc2)
     // extracted to a function to allow windows SEH to work without destructors in the same function
     static int nest;
     //printf("%d\n", nest);
-    if (++nest > 300)
+    if (++nest > global.recursionLimit)
     {
         global.gag = 0;            // ensure error message gets printed
-        error("recursive expansion");
+        error("recursive expansion exceeded allowed nesting limit");
         fatal();
     }
     semantic3(sc2);
@@ -6353,7 +6360,7 @@ Lerror:
         while (ti && !ti->deferred && ti->tinst)
         {
             ti = ti->tinst;
-            if (++nest > 500)
+            if (++nest > global.recursionLimit)
             {
                 global.gag = 0;            // ensure error message gets printed
                 error("recursive expansion");
@@ -8440,7 +8447,7 @@ void TemplateMixin::semantic(Scope *sc)
 
     static int nest;
     //printf("%d\n", nest);
-    if (++nest > 500)
+    if (++nest > global.recursionLimit)
     {
         global.gag = 0;                 // ensure error message gets printed
         error("recursive expansion");
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 9f21dabb7e4..d2519969a2c 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -2896,7 +2896,7 @@ public:
             else
             {
                 static int nest;
-                if (++nest > 500)
+                if (++nest > global.recursionLimit)
                 {
                     exp->error("recursive evaluation of %s", exp->toChars());
                     --nest;
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 9e1a5b2d15a..9d6e1ec37a9 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -244,6 +244,8 @@ struct Global
     Array<class Identifier*>* versionids; // command line versions and predefined versions
     Array<class Identifier*>* debugids;   // command line debug versions and predefined versions
 
+    enum { recursionLimit = 500 }; // number of recursive template expansions before abort
+
     /* Start gagging. Return the current number of gagged errors
      */
     unsigned startGagging();
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index de39ecb02b2..36471557dfc 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -2189,7 +2189,7 @@ Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident, int flag
 
     static int nest;      // https://issues.dlang.org/show_bug.cgi?id=17380
 
-    if (++nest > 500)
+    if (++nest > global.recursionLimit)
     {
       ::error(e->loc, "cannot resolve identifier `%s`", ident->toChars());
       --nest;
@@ -5536,7 +5536,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
 
     bool errors = false;
 
-    if (inuse > 500)
+    if (inuse > global.recursionLimit)
     {
         inuse = 0;
         ::error(loc, "recursive type");
diff --git a/gcc/d/dmd/optimize.c b/gcc/d/dmd/optimize.c
index e907229be4c..45d94df577d 100644
--- a/gcc/d/dmd/optimize.c
+++ b/gcc/d/dmd/optimize.c
@@ -19,6 +19,7 @@
 #include "init.h"
 #include "enum.h"
 #include "ctfe.h"
+#include "errors.h"
 
 Expression *semantic(Expression *e, Scope *sc);
 
@@ -1214,10 +1215,18 @@ Expression *Expression_optimize(Expression *e, int result, bool keepLvalue)
     v.ret = e;
 
     // Optimize the expression until it can no longer be simplified.
-    while (ex != v.ret)
+    size_t b = 0;
+    while (1)
     {
+        if (b++ == global.recursionLimit)
+        {
+            e->error("infinite loop while optimizing expression");
+            fatal();
+        }
         ex = v.ret;
         ex->accept(&v);
+        if (ex == v.ret)
+            break;
     }
     return ex;
 }
diff --git a/gcc/testsuite/gdc.test/compilable/ice20092.d b/gcc/testsuite/gdc.test/compilable/ice20092.d
new file mode 100644
index 00000000000..ff2be374bd2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/ice20092.d
@@ -0,0 +1,10 @@
+void foo()
+{
+    (void[1]).init.front;
+}
+
+void front(T)(T[] a)
+{
+    static assert(is(T == void));
+}
+
-- 
2.25.1



More information about the Gcc-patches mailing list