diff mbox series

[d] Committed merge with upstream dmd

Message ID CABOHX+cB7OLfZxV0XeMwLFqZqzRgFT8ck7mJZNvfb3RYWFX59A@mail.gmail.com
State New
Headers show
Series [d] Committed merge with upstream dmd | expand

Commit Message

Iain Buclaw March 1, 2019, 10:22 a.m. UTC
Hi,

This patch merges the D front-end implementation with dmd upstream ed71446aa.

Backports support for extern(C++, "namespace"), which makes the
core.stdcpp package compilable.

Added predefined condition for CppRuntime_Gcc unconditionally, as it
is unlikely that D code will be linking to anything other than
libstdc++ when extern(C++) is used.

Bootstrapped and regression tested on x86_64-linux-gnu.

Committed to trunk as r269304.
diff mbox series

Patch

diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index b0a315a3ed9..f263aafbd59 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -452,6 +452,8 @@  d_init_versions (void)
   /* Emit all target-specific version identifiers.  */
   targetdm.d_cpu_versions ();
   targetdm.d_os_versions ();
+
+  VersionCondition::addPredefinedGlobalIdent ("CppRuntime_Gcc");
 }
 
 /* A helper for d_build_builtins_module.  Return a new ALIAS for TYPE.
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 8b377015129..97aa40d1ace 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@ 
-39edbe17e7b5c761d780c9d1d4376a06df7bf3d8
+ed71446aaa2bd0e548c3bf2154a638826dfe3db0
 
 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/cond.c b/gcc/d/dmd/cond.c
index 8df226fa9b6..9d7df5fd240 100644
--- a/gcc/d/dmd/cond.c
+++ b/gcc/d/dmd/cond.c
@@ -171,6 +171,8 @@  static bool isReserved(const char *ident)
         "SysV4",
         "Hurd",
         "Android",
+        "PlayStation",
+        "PlayStation4",
         "Cygwin",
         "MinGW",
         "FreeStanding",
@@ -197,8 +199,11 @@  static bool isReserved(const char *ident)
         "MIPS_EABI",
         "MIPS_SoftFloat",
         "MIPS_HardFloat",
+        "MSP430",
         "NVPTX",
         "NVPTX64",
+        "RISCV32",
+        "RISCV64",
         "SPARC",
         "SPARC_V8Plus",
         "SPARC_SoftFloat",
@@ -219,6 +224,13 @@  static bool isReserved(const char *ident)
         "CRuntime_Digitalmars",
         "CRuntime_Glibc",
         "CRuntime_Microsoft",
+        "CRuntime_Musl",
+        "CRuntime_UClibc",
+        "CppRuntime_Clang",
+        "CppRuntime_DigitalMars",
+        "CppRuntime_Gcc",
+        "CppRuntime_Microsoft",
+        "CppRuntime_Sun",
         "D_Coverage",
         "D_Ddoc",
         "D_InlineAsm_X86",
diff --git a/gcc/d/dmd/cppmangle.c b/gcc/d/dmd/cppmangle.c
index e26f7647d3c..b991417c35e 100644
--- a/gcc/d/dmd/cppmangle.c
+++ b/gcc/d/dmd/cppmangle.c
@@ -196,8 +196,8 @@  class CppMangleVisitor : public Visitor
                 Expression *e = isExpression(o);
                 if (d && d->isFuncDeclaration())
                 {
-                    bool is_nested = d->toParent() &&
-                        !d->toParent()->isModule() &&
+                    bool is_nested = d->toParent3() &&
+                        !d->toParent3()->isModule() &&
                         ((TypeFunction*)d->isFuncDeclaration()->type)->linkage == LINKcpp;
                     if (is_nested)
                         buf->writeByte('X');
@@ -271,7 +271,7 @@  class CppMangleVisitor : public Visitor
      */
     Dsymbol *getInstance(Dsymbol *s)
     {
-        Dsymbol *p = s->toParent();
+        Dsymbol *p = s->toParent3();
         if (p)
         {
             if (TemplateInstance *ti = p->isTemplateInstance())
@@ -292,7 +292,7 @@  class CppMangleVisitor : public Visitor
      */
     static Dsymbol *getQualifier(Dsymbol *s)
     {
-        Dsymbol *p = s->toParent();
+        Dsymbol *p = s->toParent3();
         return (p && !p->isModule()) ? p : NULL;
     }
 
@@ -324,7 +324,7 @@  class CppMangleVisitor : public Visitor
         Dsymbol *s = ((TypeStruct*)t)->toDsymbol(NULL);
         if (s->ident != ident)
             return false;
-        Dsymbol *p = s->toParent();
+        Dsymbol *p = s->toParent3();
         if (!p)
             return false;
         TemplateInstance *ti = p->isTemplateInstance();
@@ -427,7 +427,7 @@  class CppMangleVisitor : public Visitor
     void cpp_mangle_name(Dsymbol *s, bool qualified)
     {
         //printf("cpp_mangle_name(%s, %d)\n", s->toChars(), qualified);
-        Dsymbol *p = s->toParent();
+        Dsymbol *p = s->toParent3();
         Dsymbol *se = s;
         bool write_prefix = true;
         if (p && p->isTemplateInstance())
@@ -435,7 +435,7 @@  class CppMangleVisitor : public Visitor
             se = p;
             if (find(p->isTemplateInstance()->tempdecl) >= 0)
                 write_prefix = false;
-            p = p->toParent();
+            p = p->toParent3();
         }
 
         if (p && !p->isModule())
@@ -521,7 +521,7 @@  class CppMangleVisitor : public Visitor
             fatal();
         }
 
-        Dsymbol *p = d->toParent();
+        Dsymbol *p = d->toParent3();
         if (p && !p->isModule()) //for example: char Namespace1::beta[6] should be mangled as "_ZN10Namespace14betaE"
         {
             buf->writestring("_ZN");
@@ -561,7 +561,7 @@  class CppMangleVisitor : public Visitor
              */
             TemplateInstance *ti = d->parent->isTemplateInstance();
             assert(ti);
-            Dsymbol *p = ti->toParent();
+            Dsymbol *p = ti->toParent3();
             if (p && !p->isModule() && tf->linkage == LINKcpp)
             {
                 buf->writeByte('N');
@@ -581,7 +581,7 @@  class CppMangleVisitor : public Visitor
         }
         else
         {
-            Dsymbol *p = d->toParent();
+            Dsymbol *p = d->toParent3();
             if (p && !p->isModule() && tf->linkage == LINKcpp)
             {
                 /* <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
@@ -997,7 +997,7 @@  public:
         else
         {
             Dsymbol *s = t->toDsymbol(NULL);
-            Dsymbol *p = s->toParent();
+            Dsymbol *p = s->toParent3();
             if (p && p->isTemplateInstance())
             {
                 /* https://issues.dlang.org/show_bug.cgi?id=17947
@@ -1044,7 +1044,7 @@  public:
 
         {
             Dsymbol *s = t->toDsymbol(NULL);
-            Dsymbol *p = s->toParent();
+            Dsymbol *p = s->toParent3();
             if (p && p->isTemplateInstance())
             {
                  /* https://issues.dlang.org/show_bug.cgi?id=17947
diff --git a/gcc/d/dmd/dsymbol.c b/gcc/d/dmd/dsymbol.c
index 4d82d7217e1..9aec87a04f5 100644
--- a/gcc/d/dmd/dsymbol.c
+++ b/gcc/d/dmd/dsymbol.c
@@ -30,6 +30,7 @@ 
 #include "attrib.h"
 #include "enum.h"
 #include "lexer.h"
+#include "nspace.h"
 
 bool symbolIsVisible(Dsymbol *origin, Dsymbol *s);
 typedef int (*ForeachDg)(void *ctx, size_t idx, Dsymbol *s);
@@ -310,6 +311,14 @@  Dsymbol *Dsymbol::toAlias2()
     return toAlias();
 }
 
+/**
+ * `pastMixin` returns the enclosing symbol if this is a template mixin.
+ *
+ * `pastMixinAndNspace` does likewise, additionally skipping over Nspaces that
+ * are mangleOnly.
+ *
+ * See also `parent`, `toParent`, `toParent2` and `toParent3`.
+ */
 Dsymbol *Dsymbol::pastMixin()
 {
     Dsymbol *s = this;
@@ -320,16 +329,31 @@  Dsymbol *Dsymbol::pastMixin()
     return s;
 }
 
+/// ditto
+Dsymbol *Dsymbol::pastMixinAndNspace()
+{
+    //printf("Dsymbol::pastMixinAndNspace() %s\n", toChars());
+    Nspace *ns = isNspace();
+    if (!(ns && ns->mangleOnly) && !isTemplateMixin() && !isForwardingAttribDeclaration())
+        return this;
+    if (!parent)
+        return NULL;
+    return parent->pastMixinAndNspace();
+}
+
 /**********************************
  * `parent` field returns a lexically enclosing scope symbol this is a member of.
  *
  * `toParent()` returns a logically enclosing scope symbol this is a member of.
- * It skips over TemplateMixin's.
+ * It skips over TemplateMixin's and Nspaces that are mangleOnly.
  *
  * `toParent2()` returns an enclosing scope symbol this is living at runtime.
  * It skips over both TemplateInstance's and TemplateMixin's.
  * It's used when looking for the 'this' pointer of the enclosing function/class.
  *
+ * `toParent3()` returns a logically enclosing scope symbol this is a member of.
+ * It skips over TemplateMixin's.
+ *
  * Examples:
  *  module mod;
  *  template Foo(alias a) { mixin Bar!(); }
@@ -352,7 +376,7 @@  Dsymbol *Dsymbol::pastMixin()
  */
 Dsymbol *Dsymbol::toParent()
 {
-    return parent ? parent->pastMixin() : NULL;
+    return parent ? parent->pastMixinAndNspace() : NULL;
 }
 
 /// ditto
@@ -364,6 +388,12 @@  Dsymbol *Dsymbol::toParent2()
     return s;
 }
 
+/// ditto
+Dsymbol *Dsymbol::toParent3()
+{
+    return parent ? parent->pastMixin() : NULL;
+}
+
 TemplateInstance *Dsymbol::isInstantiated()
 {
     for (Dsymbol *s = parent; s; s = s->parent)
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index bfed31d3f22..a840261c0bf 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -180,8 +180,10 @@  public:
     Module *getModule();
     Module *getAccessModule();
     Dsymbol *pastMixin();
+    Dsymbol *pastMixinAndNspace();
     Dsymbol *toParent();
     Dsymbol *toParent2();
+    Dsymbol *toParent3();
     TemplateInstance *isInstantiated();
     TemplateInstance *isSpeculative();
     Ungag ungagSpeculative();
diff --git a/gcc/d/dmd/nspace.c b/gcc/d/dmd/nspace.c
index 3068bfc225d..dc785418db8 100644
--- a/gcc/d/dmd/nspace.c
+++ b/gcc/d/dmd/nspace.c
@@ -17,23 +17,29 @@ 
 /* This implements namespaces.
  */
 
-Nspace::Nspace(Loc loc, Identifier *ident, Dsymbols *members)
+Nspace::Nspace(Loc loc, Identifier *ident, Dsymbols *members, bool mangleOnly)
     : ScopeDsymbol(ident)
 {
     //printf("Nspace::Nspace(ident = %s)\n", ident->toChars());
     this->loc = loc;
     this->members = members;
+    // Determines whether the symbol for this namespace should be included in
+    // the symbol table.
+    this->mangleOnly = mangleOnly;
 }
 
 Dsymbol *Nspace::syntaxCopy(Dsymbol *)
 {
-    Nspace *ns = new Nspace(loc, ident, NULL);
+    Nspace *ns = new Nspace(loc, ident, NULL, mangleOnly);
     return ScopeDsymbol::syntaxCopy(ns);
 }
 
 void Nspace::addMember(Scope *sc, ScopeDsymbol *sds)
 {
-    ScopeDsymbol::addMember(sc, sds);
+    if (mangleOnly)
+        parent = sds;
+    else
+        ScopeDsymbol::addMember(sc, sds);
     if (members)
     {
         if (!symtab)
diff --git a/gcc/d/dmd/nspace.h b/gcc/d/dmd/nspace.h
index c045b9657f6..851f800707d 100644
--- a/gcc/d/dmd/nspace.h
+++ b/gcc/d/dmd/nspace.h
@@ -19,7 +19,8 @@ 
 class Nspace : public ScopeDsymbol
 {
   public:
-    Nspace(Loc loc, Identifier *ident, Dsymbols *members);
+    bool mangleOnly;
+    Nspace(Loc loc, Identifier *ident, Dsymbols *members, bool mangleOnly);
 
     Dsymbol *syntaxCopy(Dsymbol *s);
     void addMember(Scope *sc, ScopeDsymbol *sds);
diff --git a/gcc/d/dmd/parse.c b/gcc/d/dmd/parse.c
index 171ed14f132..701c3141031 100644
--- a/gcc/d/dmd/parse.c
+++ b/gcc/d/dmd/parse.c
@@ -676,7 +676,8 @@  Dsymbols *Parser::parseDeclDefs(int once, Dsymbol **pLastDecl, PrefixAttributes
                 Loc linkLoc = token.loc;
                 Identifiers *idents = NULL;
                 CPPMANGLE cppmangle = CPPMANGLEdefault;
-                LINK link = parseLinkage(&idents, &cppmangle);
+                bool cppMangleOnly = false;
+                LINK link = parseLinkage(&idents, &cppmangle, &cppMangleOnly);
                 if (pAttrs->link != LINKdefault)
                 {
                     if (pAttrs->link != link)
@@ -709,7 +710,7 @@  Dsymbols *Parser::parseDeclDefs(int once, Dsymbol **pLastDecl, PrefixAttributes
                             a = new Dsymbols();
                             a->push(s);
                         }
-                        s = new Nspace(linkLoc, id, a);
+                        s = new Nspace(linkLoc, id, a, cppMangleOnly);
                     }
                     delete idents;
                     pAttrs->link = LINKdefault;
@@ -1271,13 +1272,15 @@  Type *Parser::parseVector()
  * Parse:
  *      extern (linkage)
  *      extern (C++, namespaces)
+ *      extern (C++, "namespace", "namespaces", ...)
  * The parser is on the 'extern' token.
  */
 
-LINK Parser::parseLinkage(Identifiers **pidents, CPPMANGLE *pcppmangle)
+LINK Parser::parseLinkage(Identifiers **pidents, CPPMANGLE *pcppmangle, bool *pcppMangleOnly)
 {
     Identifiers *idents = NULL;
     CPPMANGLE cppmangle = CPPMANGLEdefault;
+    bool cppMangleOnly = false;
     LINK link = LINKdefault;
     nextToken();
     assert(token.value == TOKlparen);
@@ -1307,6 +1310,42 @@  LINK Parser::parseLinkage(Identifiers **pidents, CPPMANGLE *pcppmangle)
                         cppmangle = token.value == TOKclass ? CPPMANGLEclass : CPPMANGLEstruct;
                         nextToken();
                     }
+                    else if (token.value == TOKstring)  // extern(C++, "namespace", "namespaces")
+                    {
+                        cppMangleOnly = true;
+                        idents = new Identifiers();
+
+                        while (1)
+                        {
+                            StringExp *stringExp = (StringExp *)parsePrimaryExp();
+                            const char *name = stringExp->toPtr();
+                            if (stringExp->len == 0)
+                            {
+                                error("invalid zero length C++ namespace");
+                                idents = NULL;
+                                break;
+                            }
+                            else if (!Identifier::isValidIdentifier(name))
+                            {
+                                error("expected valid identifer for C++ namespace but got `%s`", name);
+                                idents = NULL;
+                                break;
+                            }
+                            idents->push(Identifier::idPool(name));
+                            if (token.value == TOKcomma)
+                            {
+                                nextToken();
+                                if (token.value != TOKstring)
+                                {
+                                    error("string expected following `,` for C++ namespace, not `%s`", token.toChars());
+                                    idents = NULL;
+                                    break;
+                                }
+                            }
+                            else
+                                break;
+                        }
+                    }
                     else
                     {
                         idents = new Identifiers();
@@ -1368,6 +1407,7 @@  LINK Parser::parseLinkage(Identifiers **pidents, CPPMANGLE *pcppmangle)
     check(TOKrparen);
     *pidents = idents;
     *pcppmangle = cppmangle;
+    *pcppMangleOnly = cppMangleOnly;
     return link;
 }
 
@@ -3604,7 +3644,8 @@  void Parser::parseStorageClasses(StorageClass &storage_class, LINK &link,
                 sawLinkage = true;
                 Identifiers *idents = NULL;
                 CPPMANGLE cppmangle = CPPMANGLEdefault;
-                link = parseLinkage(&idents, &cppmangle);
+                bool cppMangleOnly = false;
+                link = parseLinkage(&idents, &cppmangle, &cppMangleOnly);
                 if (idents)
                 {
                     error("C++ name spaces not allowed here");
diff --git a/gcc/d/dmd/parse.h b/gcc/d/dmd/parse.h
index a77d5e5e436..97630dc3c4d 100644
--- a/gcc/d/dmd/parse.h
+++ b/gcc/d/dmd/parse.h
@@ -88,7 +88,7 @@  public:
     StaticAssert *parseStaticAssert();
     TypeQualified *parseTypeof();
     Type *parseVector();
-    LINK parseLinkage(Identifiers **, CPPMANGLE *);
+    LINK parseLinkage(Identifiers **, CPPMANGLE *, bool *);
     Identifiers *parseQualifiedIdentifier(const char *entity);
     Condition *parseDebugCondition();
     Condition *parseVersionCondition();
diff --git a/gcc/testsuite/gdc.test/compilable/cppmangle3.d b/gcc/testsuite/gdc.test/compilable/cppmangle3.d
new file mode 100644
index 00000000000..4c48012a3d6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/cppmangle3.d
@@ -0,0 +1,37 @@ 
+module cppmangle3;
+
+
+extern(C++, "true")
+{
+}
+
+extern(C++, "__traits")
+{
+}
+
+extern(C++, "foo")
+{
+}
+
+int foo; // no name clashing with above namespace
+
+extern(C++, "std", "chrono")
+{
+    void func();
+}
+
+version(Windows) static assert(func.mangleof == "?func@chrono@std@@YAXXZ");
+else             static assert(func.mangleof == "_ZNSt6chrono4funcEv");
+
+struct Foo
+{
+    extern(C++, "namespace")
+    {
+        static void bar();
+    }
+}
+
+alias Alias(alias a) = a;
+alias Alias(T) = T;
+
+static assert(is(Alias!(__traits(parent, bar)) == Foo));
diff --git a/gcc/testsuite/gdc.test/compilable/test19574.d b/gcc/testsuite/gdc.test/compilable/test19574.d
new file mode 100644
index 00000000000..907bb3b8edf
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test19574.d
@@ -0,0 +1,18 @@ 
+
+static assert( Foo(10).bar.value == 10 );
+
+extern(C++, "ns") {
+    struct Foo {
+        Bar!Foo bar;
+
+        this( int v ) {
+            bar.value = v;
+        }
+    }
+}
+
+extern(C++, "ns") {
+    struct Bar(T) {
+        int value;
+    }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/cppmangle.d b/gcc/testsuite/gdc.test/fail_compilation/cppmangle.d
new file mode 100644
index 00000000000..b8b2f03f019
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/cppmangle.d
@@ -0,0 +1,20 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/cppmangle.d(10): Error: invalid zero length C++ namespace
+fail_compilation/cppmangle.d(14): Error: expected valid identifer for C++ namespace but got `0num`
+fail_compilation/cppmangle.d(18): Error: string expected following `,` for C++ namespace, not `)`
+---
+*/
+
+extern(C++, "")
+{
+}
+
+extern(C++, "0num")
+{
+}
+
+extern(C++, "std", )
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
index de23c461e4a..1fe47282959 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
@@ -97,11 +97,17 @@  fail_compilation/reserved_version.d(196): Error: version identifier `D_Version2`
 fail_compilation/reserved_version.d(197): Error: version identifier `D_NoBoundsChecks` is reserved and cannot be set
 fail_compilation/reserved_version.d(200): Error: version identifier `all` is reserved and cannot be set
 fail_compilation/reserved_version.d(201): Error: version identifier `none` is reserved and cannot be set
+fail_compilation/reserved_version.d(202): Error: version identifier `CppRuntime_Clang` is reserved and cannot be set
+fail_compilation/reserved_version.d(203): Error: version identifier `CppRuntime_DigitalMars` is reserved and cannot be set
+fail_compilation/reserved_version.d(204): Error: version identifier `CppRuntime_Gcc` is reserved and cannot be set
+fail_compilation/reserved_version.d(205): Error: version identifier `CppRuntime_Microsoft` is reserved and cannot be set
+fail_compilation/reserved_version.d(206): Error: version identifier `CppRuntime_Sun` is reserved and cannot be set
 ---
 */
 
 // Some extra empty lines to help fixup the manual line numbering after adding new version identifiers
 
+#line 105
 version = MSP430;
 version = D_P16;
 version = DigitalMars;
@@ -199,6 +205,11 @@  version = D_NoBoundsChecks;
 //version = assert;
 version = all;
 version = none;
+version = CppRuntime_Clang;
+version = CppRuntime_DigitalMars;
+version = CppRuntime_Gcc;
+version = CppRuntime_Microsoft;
+version = CppRuntime_Sun;
 
 // This should work though
 debug = DigitalMars;
@@ -278,6 +289,11 @@  debug = CRuntime_Glibc;
 debug = CRuntime_Microsoft;
 debug = CRuntime_Musl;
 debug = CRuntime_UClibc;
+debug = CppRuntime_Clang;
+debug = CppRuntime_DigitalMars;
+debug = CppRuntime_Gcc;
+debug = CppRuntime_Microsoft;
+debug = CppRuntime_Sun;
 debug = D_Coverage;
 debug = D_Ddoc;
 debug = D_InlineAsm_X86;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d
index eb794d2ac42..0259273f89e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d
@@ -77,6 +77,11 @@ 
 // REQUIRED_ARGS: -version=CRuntime_Microsoft
 // REQUIRED_ARGS: -version=CRuntime_Musl
 // REQUIRED_ARGS: -version=CRuntime_UClibc
+// REQUIRED_ARGS: -version=CppRuntime_Clang
+// REQUIRED_ARGS: -version=CppRuntime_DigitalMars
+// REQUIRED_ARGS: -version=CppRuntime_Gcc
+// REQUIRED_ARGS: -version=CppRuntime_Microsoft
+// REQUIRED_ARGS: -version=CppRuntime_Sun
 // REQUIRED_ARGS: -version=D_Coverage
 // REQUIRED_ARGS: -version=D_Ddoc
 // REQUIRED_ARGS: -version=D_InlineAsm_X86
@@ -168,6 +173,11 @@ 
 // REQUIRED_ARGS: -debug=CRuntime_Microsoft
 // REQUIRED_ARGS: -debug=CRuntime_Musl
 // REQUIRED_ARGS: -debug=CRuntime_UClibc
+// REQUIRED_ARGS: -debug=CppRuntime_Clang
+// REQUIRED_ARGS: -debug=CppRuntime_DigitalMars
+// REQUIRED_ARGS: -debug=CppRuntime_Gcc
+// REQUIRED_ARGS: -debug=CppRuntime_Microsoft
+// REQUIRED_ARGS: -debug=CppRuntime_Sun
 // REQUIRED_ARGS: -debug=D_Coverage
 // REQUIRED_ARGS: -debug=D_Ddoc
 // REQUIRED_ARGS: -debug=D_InlineAsm_X86
@@ -264,6 +274,11 @@  Error: version identifier `CRuntime_Glibc` is reserved and cannot be set
 Error: version identifier `CRuntime_Microsoft` is reserved and cannot be set
 Error: version identifier `CRuntime_Musl` is reserved and cannot be set
 Error: version identifier `CRuntime_UClibc` is reserved and cannot be set
+Error: version identifier `CppRuntime_Clang` is reserved and cannot be set
+Error: version identifier `CppRuntime_DigitalMars` is reserved and cannot be set
+Error: version identifier `CppRuntime_Gcc` is reserved and cannot be set
+Error: version identifier `CppRuntime_Microsoft` is reserved and cannot be set
+Error: version identifier `CppRuntime_Sun` is reserved and cannot be set
 Error: version identifier `D_Coverage` is reserved and cannot be set
 Error: version identifier `D_Ddoc` is reserved and cannot be set
 Error: version identifier `D_InlineAsm_X86` is reserved and cannot be set