diff mbox series

testsuite: Add check_effective_target_d_runtime_has_std_library procedure

Message ID 20200414163847.11838-1-ibuclaw@gdcproject.org
State New
Headers show
Series testsuite: Add check_effective_target_d_runtime_has_std_library procedure | expand

Commit Message

Iain Buclaw April 14, 2020, 4:38 p.m. UTC
Hi,

This patch adds an effect target d_runtime_has_std_library to
target-supports.exp, and some preliminary uses of it.

The current check_effective_target_d_runtime procedure returns false if
the target is without any core runtime library for D.  This additional
procedure is for targets where the core runtime library exists, but is
without the higher level standard D library.

OK for master?

Regards
Iain.

---
gcc/testsuite/ChangeLog:

	* gdc.dg/link.d: Use d_runtime_has_std_library effective target.
	* gdc.dg/runnable.d: Move phobos tests to...
	* gdc.dg/runnable2.d: ...here.  New test.
	* lib/target-supports.exp
	(check_effective_target_d_runtime_has_std_library): New.

libphobos/ChangeLog:

	* testsuite/libphobos.phobos/phobos.exp: Skip if effective target is
	not d_runtime_has_std_library.
	* testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise.
---
 gcc/testsuite/gdc.dg/link.d                   |   2 +-
 gcc/testsuite/gdc.dg/runnable.d               | 229 ----------------
 gcc/testsuite/gdc.dg/runnable2.d              | 244 ++++++++++++++++++
 gcc/testsuite/lib/target-supports.exp         |  15 ++
 .../testsuite/libphobos.phobos/phobos.exp     |   5 +
 .../libphobos.phobos_shared/phobos_shared.exp |   5 +
 6 files changed, 270 insertions(+), 230 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/runnable2.d

Comments

Richard Sandiford April 15, 2020, 3:17 p.m. UTC | #1
Iain Buclaw via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> Hi,
>
> This patch adds an effect target d_runtime_has_std_library to
> target-supports.exp, and some preliminary uses of it.
>
> The current check_effective_target_d_runtime procedure returns false if
> the target is without any core runtime library for D.  This additional
> procedure is for targets where the core runtime library exists, but is
> without the higher level standard D library.
>
> OK for master?

OK.  FAOD though, D-related effective-target keywords are covered by the
D frontend maintainership.

Thanks,
Richard


>
> Regards
> Iain.
>
> ---
> gcc/testsuite/ChangeLog:
>
> 	* gdc.dg/link.d: Use d_runtime_has_std_library effective target.
> 	* gdc.dg/runnable.d: Move phobos tests to...
> 	* gdc.dg/runnable2.d: ...here.  New test.
> 	* lib/target-supports.exp
> 	(check_effective_target_d_runtime_has_std_library): New.
>
> libphobos/ChangeLog:
>
> 	* testsuite/libphobos.phobos/phobos.exp: Skip if effective target is
> 	not d_runtime_has_std_library.
> 	* testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise.
> ---
>  gcc/testsuite/gdc.dg/link.d                   |   2 +-
>  gcc/testsuite/gdc.dg/runnable.d               | 229 ----------------
>  gcc/testsuite/gdc.dg/runnable2.d              | 244 ++++++++++++++++++
>  gcc/testsuite/lib/target-supports.exp         |  15 ++
>  .../testsuite/libphobos.phobos/phobos.exp     |   5 +
>  .../libphobos.phobos_shared/phobos_shared.exp |   5 +
>  6 files changed, 270 insertions(+), 230 deletions(-)
>  create mode 100644 gcc/testsuite/gdc.dg/runnable2.d
>
> diff --git a/gcc/testsuite/gdc.dg/link.d b/gcc/testsuite/gdc.dg/link.d
> index a8ca4ed5cb6..5efd0ad347f 100644
> --- a/gcc/testsuite/gdc.dg/link.d
> +++ b/gcc/testsuite/gdc.dg/link.d
> @@ -1,4 +1,4 @@
> -// { dg-do link { target d_runtime } }
> +// { dg-do link { target d_runtime_has_std_library } }
>  
>  /******************************************/
>  
> diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d
> index 484a9709bf3..7307e09a645 100644
> --- a/gcc/testsuite/gdc.dg/runnable.d
> +++ b/gcc/testsuite/gdc.dg/runnable.d
> @@ -9,20 +9,6 @@ import core.stdc.stdio;
>  import gcc.attribute;
>  
>  
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=2
> -
> -struct S
> -{
> -    string toString() { return "foo"; }
> -}
> -
> -void test2()
> -{
> -    import std.string : format;
> -    assert(format("%s", S()) == "foo");
> -}
> -
>  /******************************************/
>  // https://bugzilla.gdcproject.org/show_bug.cgi?id=4
>  
> @@ -33,35 +19,6 @@ void test4()
>      static assert(!__traits(compiles, str.sort));
>  }
>  
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=15
> -
> -class B
> -{
> -    class A { }
> -    A a;
> -}
> -
> -class C
> -{
> -    void visit(B b)
> -    {
> -        import std.algorithm : map;
> -        auto as = [b.a];
> -        as.map!(d => d);
> -    }
> -}
> -
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=16
> -
> -void test16()
> -{
> -    import std.parallelism : taskPool;
> -
> -    taskPool.reduce!"a+b"([0, 1, 2, 3]);
> -}
> -
>  /******************************************/
>  // https://bugzilla.gdcproject.org/show_bug.cgi?id=17
>  
> @@ -99,59 +56,6 @@ void test17()
>    (new ModuleWriter()).save ("test.0.mci");
>  }
>  
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=18
> -
> -class C18
> -{
> -    struct Link
> -    {
> -        int x;
> -        int y;
> -    }
> -
> -    void sort_links()
> -    {
> -        import std.algorithm : sort;
> -        import std.array : empty;
> -        import std.exception : enforce;
> -
> -        enforce(!_link.empty);
> -
> -        bool lt(Link a, Link b)
> -        {
> -            if(a.x > b.x)
> -                return false;
> -            if(a.x < b.x)
> -                return true;
> -            if(a.y >= b.y)
> -                return false;
> -            else
> -                return true;
> -        }
> -        sort!(lt)(_link);
> -    }
> -
> -    this()
> -    {
> -        _link ~= Link(8, 3);
> -        _link ~= Link(4, 7);
> -        _link ~= Link(4, 6);
> -        _link ~= Link(3, 7);
> -        _link ~= Link(2, 7);
> -        _link ~= Link(2, 2);
> -        _link ~= Link(4, 1);
> -    }
> -
> -    Link[] _link;
> -}
> -
> -void test18()
> -{
> -    C18 foo = new C18;
> -    foo.sort_links();
> -}
> -
>  /******************************************/
>  // https://bugzilla.gdcproject.org/show_bug.cgi?id=19
>  
> @@ -177,22 +81,6 @@ void test24()
>          return;
>  }
>  
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=29
> -
> -void test29()
> -{
> -    import std.string : format;
> -    import std.conv : text;
> -
> -    string s;
> -    for (auto i = 0; i < 100000; i++)
> -    {
> -        s = format("%d", i);
> -        s = text(i);
> -    }
> -}
> -
>  /******************************************/
>  // https://bugzilla.gdcproject.org/show_bug.cgi?id=31
>  
> @@ -499,54 +387,6 @@ void test51()
>      assert (s.x == 0);
>  }
>  
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=52
> -
> -class C52
> -{
> -    C52 a;
> -
> -    this()
> -    {
> -        printf("Construct: this=%p\n", cast(void*)this);
> -        a = this;
> -    }
> -
> -    bool check()
> -    {
> -        printf("Check: this=%p a=%p\n", cast(void*)this, cast(void*)a);
> -        return this is a;
> -    }
> -}
> -
> -auto test52a()
> -{
> -    import std.conv, std.traits;
> -
> -    struct Scoped
> -    {
> -        void[__traits (classInstanceSize, C52) ] Scoped_store = void;
> -
> -        inout(C52) Scoped_payload() inout
> -        {
> -            void* alignedStore = cast(void*) Scoped_store.ptr;
> -            return cast(inout (C52)) alignedStore;
> -        }
> -        alias Scoped_payload this;
> -    }
> -
> -    Scoped result;
> -    emplace!(Unqual!C52)(result.Scoped_store);
> -    assert(result.Scoped_payload().check);
> -    return result;
> -}
> -
> -void test52()
> -{
> -    auto a1 = test52a();
> -    assert(a1.Scoped_payload().check);
> -}
> -
>  /******************************************/
>  // https://bugzilla.gdcproject.org/show_bug.cgi?id=57
>  
> @@ -588,54 +428,6 @@ void test66()
>  __vector(float[4]) d[2];  // ICE
>  
>  
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=71
> -
> -struct Leaf
> -{
> -    ubyte symbol;
> -    ubyte codeLen;
> -}
> -
> -struct CanonicalHuffman
> -{
> -    Leaf[] table;
> -
> -    void print()
> -    {
> -        import std.algorithm;
> -        import std.range;
> -
> -        auto list = zip(iota(table.length), table.dup).array
> -            .sort!((a, b) => a[1].symbol < b[1].symbol)
> -            .uniq!((a, b) => (a[0] & (1 << a[1].codeLen) - 1) == (b[0] & (1 << b[1].codeLen) - 1));
> -    }
> -}
> -
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=77
> -
> -void fun(ubyte[3] buf)
> -{
> -    import std.bitmanip : bigEndianToNative;
> -    bigEndianToNative!ushort(buf[0..2]);
> -}
> -
> -void test77()
> -{
> -    fun([1,2,3]);
> -}
> -
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=108
> -
> -@attribute("forceinline")
> -void test108()
> -{
> -    import std.stdio : writeln;
> -    writeln("Here");
> -}
> -
>  /******************************************/
>  // https://bugzilla.gdcproject.org/show_bug.cgi?id=115
>  
> @@ -657,21 +449,6 @@ void test115()
>  
>  immutable char C121 = void; // ICE
>  
> -/******************************************/
> -// https://bugzilla.gdcproject.org/show_bug.cgi?id=122
> -
> -void test122()
> -{
> -    import std.algorithm : map;
> -    import std.parallelism : taskPool;
> -    import std.range : iota;
> -
> -    immutable n = 10000;
> -    enum delta = 1.0 / n;       // XBUG: was 'immutable delta' https://issues.dlang.org/show_bug.cgi?id=17092
> -    immutable pi = 4.0 * delta * taskPool.reduce!"a + b"(
> -        map!((int i) { immutable x = (i - 0.5) * delta; return 1.0 / (1.0 + x * x); })(iota(n)));
> -}
> -
>  /******************************************/
>  // https://bugzilla.gdcproject.org/show_bug.cgi?id=127
>  
> @@ -1584,20 +1361,14 @@ void test309()
>  
>  void main()
>  {
> -    test2();
>      test4();
> -    test16();
>      test17();
> -    test18();
>      test35();
>      test36();
>      test43();
>      test51();
> -    test52();
>      test57();
>      test66();
> -    test77();
> -    test108();
>      test115();
>      test131();
>      test133();
> diff --git a/gcc/testsuite/gdc.dg/runnable2.d b/gcc/testsuite/gdc.dg/runnable2.d
> new file mode 100644
> index 00000000000..d9463e337c1
> --- /dev/null
> +++ b/gcc/testsuite/gdc.dg/runnable2.d
> @@ -0,0 +1,244 @@
> +// { dg-do run { target { hw && d_runtime_has_std_library } } }
> +
> +module runnable;
> +
> +import core.stdc.stdio;
> +import gcc.attribute;
> +
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=2
> +
> +struct S
> +{
> +    string toString() { return "foo"; }
> +}
> +
> +void test2()
> +{
> +    import std.string : format;
> +    assert(format("%s", S()) == "foo");
> +}
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=15
> +
> +class B
> +{
> +    class A { }
> +    A a;
> +}
> +
> +class C
> +{
> +    void visit(B b)
> +    {
> +        import std.algorithm : map;
> +        auto as = [b.a];
> +        as.map!(d => d);
> +    }
> +}
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=16
> +
> +void test16()
> +{
> +    import std.parallelism : taskPool;
> +
> +    taskPool.reduce!"a+b"([0, 1, 2, 3]);
> +}
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=18
> +
> +class C18
> +{
> +    struct Link
> +    {
> +        int x;
> +        int y;
> +    }
> +
> +    void sort_links()
> +    {
> +        import std.algorithm : sort;
> +        import std.array : empty;
> +        import std.exception : enforce;
> +
> +        enforce(!_link.empty);
> +
> +        bool lt(Link a, Link b)
> +        {
> +            if(a.x > b.x)
> +                return false;
> +            if(a.x < b.x)
> +                return true;
> +            if(a.y >= b.y)
> +                return false;
> +            else
> +                return true;
> +        }
> +        sort!(lt)(_link);
> +    }
> +
> +    this()
> +    {
> +        _link ~= Link(8, 3);
> +        _link ~= Link(4, 7);
> +        _link ~= Link(4, 6);
> +        _link ~= Link(3, 7);
> +        _link ~= Link(2, 7);
> +        _link ~= Link(2, 2);
> +        _link ~= Link(4, 1);
> +    }
> +
> +    Link[] _link;
> +}
> +
> +void test18()
> +{
> +    C18 foo = new C18;
> +    foo.sort_links();
> +}
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=29
> +
> +void test29()
> +{
> +    import std.string : format;
> +    import std.conv : text;
> +
> +    string s;
> +    for (auto i = 0; i < 100000; i++)
> +    {
> +        s = format("%d", i);
> +        s = text(i);
> +    }
> +}
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=52
> +
> +class C52
> +{
> +    C52 a;
> +
> +    this()
> +    {
> +        printf("Construct: this=%p\n", cast(void*)this);
> +        a = this;
> +    }
> +
> +    bool check()
> +    {
> +        printf("Check: this=%p a=%p\n", cast(void*)this, cast(void*)a);
> +        return this is a;
> +    }
> +}
> +
> +auto test52a()
> +{
> +    import std.conv, std.traits;
> +
> +    struct Scoped
> +    {
> +        void[__traits (classInstanceSize, C52) ] Scoped_store = void;
> +
> +        inout(C52) Scoped_payload() inout
> +        {
> +            void* alignedStore = cast(void*) Scoped_store.ptr;
> +            return cast(inout (C52)) alignedStore;
> +        }
> +        alias Scoped_payload this;
> +    }
> +
> +    Scoped result;
> +    emplace!(Unqual!C52)(result.Scoped_store);
> +    assert(result.Scoped_payload().check);
> +    return result;
> +}
> +
> +void test52()
> +{
> +    auto a1 = test52a();
> +    assert(a1.Scoped_payload().check);
> +}
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=71
> +
> +struct Leaf
> +{
> +    ubyte symbol;
> +    ubyte codeLen;
> +}
> +
> +struct CanonicalHuffman
> +{
> +    Leaf[] table;
> +
> +    void print()
> +    {
> +        import std.algorithm;
> +        import std.range;
> +
> +        auto list = zip(iota(table.length), table.dup).array
> +            .sort!((a, b) => a[1].symbol < b[1].symbol)
> +            .uniq!((a, b) => (a[0] & (1 << a[1].codeLen) - 1) == (b[0] & (1 << b[1].codeLen) - 1));
> +    }
> +}
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=77
> +
> +void fun(ubyte[3] buf)
> +{
> +    import std.bitmanip : bigEndianToNative;
> +    bigEndianToNative!ushort(buf[0..2]);
> +}
> +
> +void test77()
> +{
> +    fun([1,2,3]);
> +}
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=108
> +
> +@attribute("forceinline")
> +void test108()
> +{
> +    import std.stdio : writeln;
> +    writeln("Here");
> +}
> +
> +/******************************************/
> +// https://bugzilla.gdcproject.org/show_bug.cgi?id=122
> +
> +void test122()
> +{
> +    import std.algorithm : map;
> +    import std.parallelism : taskPool;
> +    import std.range : iota;
> +
> +    immutable n = 10000;
> +    enum delta = 1.0 / n;       // XBUG: was 'immutable delta' https://issues.dlang.org/show_bug.cgi?id=17092
> +    immutable pi = 4.0 * delta * taskPool.reduce!"a + b"(
> +        map!((int i) { immutable x = (i - 0.5) * delta; return 1.0 / (1.0 + x * x); })(iota(n)));
> +}
> +
> +/******************************************/
> +
> +void main()
> +{
> +    test2();
> +    test16();
> +    test18();
> +    test52();
> +    test77();
> +    test108();
> +
> +    printf("Success!\n");
> +}
> diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
> index 3758bb3a91d..5704a2fc583 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -8069,6 +8069,21 @@ proc check_effective_target_d_runtime { } {
>      }]
>  }
>  
> +# Return 1 if the target provides the D standard library.
> +
> +proc check_effective_target_d_runtime_has_std_library { } {
> +    return [check_no_compiler_messages d_runtime_has_std_library executable {
> +	// D
> +	module mod;
> +
> +	extern(C) int main() {
> +	    import std.math;
> +	    real function(real) pcos = &cos;
> +	    return 0;
> +	}
> +    }]
> +}
> +
>  # Return 1 if  target wchar_t is at least 4 bytes.
>  
>  proc check_effective_target_4byte_wchar_t { } {
> diff --git a/libphobos/testsuite/libphobos.phobos/phobos.exp b/libphobos/testsuite/libphobos.phobos/phobos.exp
> index 3d876acf27b..aad877c24c2 100644
> --- a/libphobos/testsuite/libphobos.phobos/phobos.exp
> +++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
> @@ -19,6 +19,11 @@ if { ![isnative] || ![is-effective-target static] } {
>      return
>  }
>  
> +# Skip running test if phobos was not built on the target.
> +if { ![is-effective-target d_runtime_has_std_library] } {
> +    return
> +}
> +
>  # Gather a list of all tests.
>  set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]
>  
> diff --git a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
> index 43b9772d6f2..a00ecf11ac9 100644
> --- a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
> +++ b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
> @@ -19,6 +19,11 @@ if { ![isnative] || ![is-effective-target shared] } {
>      return
>  }
>  
> +# Skip running test if phobos was not built on the target.
> +if { ![is-effective-target d_runtime_has_std_library] } {
> +    return
> +}
> +
>  # Gather a list of all tests.
>  set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]
Rainer Orth April 15, 2020, 3:26 p.m. UTC | #2
Hi Richard,

> Iain Buclaw via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
>> Hi,
>>
>> This patch adds an effect target d_runtime_has_std_library to
>> target-supports.exp, and some preliminary uses of it.
>>
>> The current check_effective_target_d_runtime procedure returns false if
>> the target is without any core runtime library for D.  This additional
>> procedure is for targets where the core runtime library exists, but is
>> without the higher level standard D library.
>>
>> OK for master?
>
> OK.  FAOD though, D-related effective-target keywords are covered by the
> D frontend maintainership.

indeed.  However, they still need documenting in sourcebuild.texi.  Iain,
please do so before committing.

Thanks.
        Rainer
Iain Buclaw April 15, 2020, 8:13 p.m. UTC | #3
On 15/04/2020 17:17, Richard Sandiford wrote:
> Iain Buclaw via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
>> Hi,
>>
>> This patch adds an effect target d_runtime_has_std_library to
>> target-supports.exp, and some preliminary uses of it.
>>
>> The current check_effective_target_d_runtime procedure returns false if
>> the target is without any core runtime library for D.  This additional
>> procedure is for targets where the core runtime library exists, but is
>> without the higher level standard D library.
>>
>> OK for master?
> 
> OK.  FAOD though, D-related effective-target keywords are covered by the
> D frontend maintainership.
> 

Ah, thanks for clarifying that, I wasn't sure, but thought it best to pass it by for review just in case.

Iain.
Iain Buclaw April 18, 2020, 12:05 p.m. UTC | #4
On 15/04/2020 17:26, Rainer Orth wrote:
> Hi Richard,
> 
>> Iain Buclaw via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
>>> Hi,
>>>
>>> This patch adds an effect target d_runtime_has_std_library to
>>> target-supports.exp, and some preliminary uses of it.
>>>
>>> The current check_effective_target_d_runtime procedure returns false if
>>> the target is without any core runtime library for D.  This additional
>>> procedure is for targets where the core runtime library exists, but is
>>> without the higher level standard D library.
>>>
>>> OK for master?
>>
>> OK.  FAOD though, D-related effective-target keywords are covered by the
>> D frontend maintainership.
> 
> indeed.  However, they still need documenting in sourcebuild.texi.  Iain,
> please do so before committing.
> 

Thanks, committed with added documentation, attached the updated patch.

Iain.

---
gcc/ChangeLog:

	* doc/sourcebuild.texi (Effective-Target Keywords, Environment
	attributes): Document d_runtime_has_std_library.

gcc/testsuite/ChangeLog:

	* gdc.dg/link.d: Use d_runtime_has_std_library effective target.
	* gdc.dg/runnable.d: Move phobos tests to...
	* gdc.dg/runnable2.d: ...here.  New test.
	* lib/target-supports.exp
	(check_effective_target_d_runtime_has_std_library): New.

libphobos/ChangeLog:

	* testsuite/libphobos.phobos/phobos.exp: Skip if effective target is
	not d_runtime_has_std_library.
	* testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise.
---
 gcc/doc/sourcebuild.texi                      |   3 +
 gcc/testsuite/gdc.dg/link.d                   |   2 +-
 gcc/testsuite/gdc.dg/runnable.d               | 229 ----------------
 gcc/testsuite/gdc.dg/runnable2.d              | 244 ++++++++++++++++++
 gcc/testsuite/lib/target-supports.exp         |  15 ++
 .../testsuite/libphobos.phobos/phobos.exp     |   5 +
 .../libphobos.phobos_shared/phobos_shared.exp |   5 +
 7 files changed, 273 insertions(+), 230 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/runnable2.d

diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index de28227236a..c1642bad398 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2207,6 +2207,9 @@ overloads for @code{strchr} etc. functions.
 @item d_runtime
 Target provides the D runtime.
 
+@item d_runtime_has_std_library
+Target provides the D standard library (Phobos).
+
 @item dummy_wcsftime
 Target uses a dummy @code{wcsftime} function that always returns zero.
 
diff --git a/gcc/testsuite/gdc.dg/link.d b/gcc/testsuite/gdc.dg/link.d
index a8ca4ed5cb6..5efd0ad347f 100644
--- a/gcc/testsuite/gdc.dg/link.d
+++ b/gcc/testsuite/gdc.dg/link.d
@@ -1,4 +1,4 @@
-// { dg-do link { target d_runtime } }
+// { dg-do link { target d_runtime_has_std_library } }
 
 /******************************************/
 
diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d
index 484a9709bf3..7307e09a645 100644
--- a/gcc/testsuite/gdc.dg/runnable.d
+++ b/gcc/testsuite/gdc.dg/runnable.d
@@ -9,20 +9,6 @@ import core.stdc.stdio;
 import gcc.attribute;
 
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=2
-
-struct S
-{
-    string toString() { return "foo"; }
-}
-
-void test2()
-{
-    import std.string : format;
-    assert(format("%s", S()) == "foo");
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=4
 
@@ -33,35 +19,6 @@ void test4()
     static assert(!__traits(compiles, str.sort));
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=15
-
-class B
-{
-    class A { }
-    A a;
-}
-
-class C
-{
-    void visit(B b)
-    {
-        import std.algorithm : map;
-        auto as = [b.a];
-        as.map!(d => d);
-    }
-}
-
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=16
-
-void test16()
-{
-    import std.parallelism : taskPool;
-
-    taskPool.reduce!"a+b"([0, 1, 2, 3]);
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=17
 
@@ -99,59 +56,6 @@ void test17()
   (new ModuleWriter()).save ("test.0.mci");
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=18
-
-class C18
-{
-    struct Link
-    {
-        int x;
-        int y;
-    }
-
-    void sort_links()
-    {
-        import std.algorithm : sort;
-        import std.array : empty;
-        import std.exception : enforce;
-
-        enforce(!_link.empty);
-
-        bool lt(Link a, Link b)
-        {
-            if(a.x > b.x)
-                return false;
-            if(a.x < b.x)
-                return true;
-            if(a.y >= b.y)
-                return false;
-            else
-                return true;
-        }
-        sort!(lt)(_link);
-    }
-
-    this()
-    {
-        _link ~= Link(8, 3);
-        _link ~= Link(4, 7);
-        _link ~= Link(4, 6);
-        _link ~= Link(3, 7);
-        _link ~= Link(2, 7);
-        _link ~= Link(2, 2);
-        _link ~= Link(4, 1);
-    }
-
-    Link[] _link;
-}
-
-void test18()
-{
-    C18 foo = new C18;
-    foo.sort_links();
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=19
 
@@ -177,22 +81,6 @@ void test24()
         return;
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=29
-
-void test29()
-{
-    import std.string : format;
-    import std.conv : text;
-
-    string s;
-    for (auto i = 0; i < 100000; i++)
-    {
-        s = format("%d", i);
-        s = text(i);
-    }
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=31
 
@@ -499,54 +387,6 @@ void test51()
     assert (s.x == 0);
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=52
-
-class C52
-{
-    C52 a;
-
-    this()
-    {
-        printf("Construct: this=%p\n", cast(void*)this);
-        a = this;
-    }
-
-    bool check()
-    {
-        printf("Check: this=%p a=%p\n", cast(void*)this, cast(void*)a);
-        return this is a;
-    }
-}
-
-auto test52a()
-{
-    import std.conv, std.traits;
-
-    struct Scoped
-    {
-        void[__traits (classInstanceSize, C52) ] Scoped_store = void;
-
-        inout(C52) Scoped_payload() inout
-        {
-            void* alignedStore = cast(void*) Scoped_store.ptr;
-            return cast(inout (C52)) alignedStore;
-        }
-        alias Scoped_payload this;
-    }
-
-    Scoped result;
-    emplace!(Unqual!C52)(result.Scoped_store);
-    assert(result.Scoped_payload().check);
-    return result;
-}
-
-void test52()
-{
-    auto a1 = test52a();
-    assert(a1.Scoped_payload().check);
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=57
 
@@ -588,54 +428,6 @@ void test66()
 __vector(float[4]) d[2];  // ICE
 
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=71
-
-struct Leaf
-{
-    ubyte symbol;
-    ubyte codeLen;
-}
-
-struct CanonicalHuffman
-{
-    Leaf[] table;
-
-    void print()
-    {
-        import std.algorithm;
-        import std.range;
-
-        auto list = zip(iota(table.length), table.dup).array
-            .sort!((a, b) => a[1].symbol < b[1].symbol)
-            .uniq!((a, b) => (a[0] & (1 << a[1].codeLen) - 1) == (b[0] & (1 << b[1].codeLen) - 1));
-    }
-}
-
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=77
-
-void fun(ubyte[3] buf)
-{
-    import std.bitmanip : bigEndianToNative;
-    bigEndianToNative!ushort(buf[0..2]);
-}
-
-void test77()
-{
-    fun([1,2,3]);
-}
-
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=108
-
-@attribute("forceinline")
-void test108()
-{
-    import std.stdio : writeln;
-    writeln("Here");
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=115
 
@@ -657,21 +449,6 @@ void test115()
 
 immutable char C121 = void; // ICE
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=122
-
-void test122()
-{
-    import std.algorithm : map;
-    import std.parallelism : taskPool;
-    import std.range : iota;
-
-    immutable n = 10000;
-    enum delta = 1.0 / n;       // XBUG: was 'immutable delta' https://issues.dlang.org/show_bug.cgi?id=17092
-    immutable pi = 4.0 * delta * taskPool.reduce!"a + b"(
-        map!((int i) { immutable x = (i - 0.5) * delta; return 1.0 / (1.0 + x * x); })(iota(n)));
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=127
 
@@ -1584,20 +1361,14 @@ void test309()
 
 void main()
 {
-    test2();
     test4();
-    test16();
     test17();
-    test18();
     test35();
     test36();
     test43();
     test51();
-    test52();
     test57();
     test66();
-    test77();
-    test108();
     test115();
     test131();
     test133();
diff --git a/gcc/testsuite/gdc.dg/runnable2.d b/gcc/testsuite/gdc.dg/runnable2.d
new file mode 100644
index 00000000000..d9463e337c1
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/runnable2.d
@@ -0,0 +1,244 @@
+// { dg-do run { target { hw && d_runtime_has_std_library } } }
+
+module runnable;
+
+import core.stdc.stdio;
+import gcc.attribute;
+
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=2
+
+struct S
+{
+    string toString() { return "foo"; }
+}
+
+void test2()
+{
+    import std.string : format;
+    assert(format("%s", S()) == "foo");
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=15
+
+class B
+{
+    class A { }
+    A a;
+}
+
+class C
+{
+    void visit(B b)
+    {
+        import std.algorithm : map;
+        auto as = [b.a];
+        as.map!(d => d);
+    }
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=16
+
+void test16()
+{
+    import std.parallelism : taskPool;
+
+    taskPool.reduce!"a+b"([0, 1, 2, 3]);
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=18
+
+class C18
+{
+    struct Link
+    {
+        int x;
+        int y;
+    }
+
+    void sort_links()
+    {
+        import std.algorithm : sort;
+        import std.array : empty;
+        import std.exception : enforce;
+
+        enforce(!_link.empty);
+
+        bool lt(Link a, Link b)
+        {
+            if(a.x > b.x)
+                return false;
+            if(a.x < b.x)
+                return true;
+            if(a.y >= b.y)
+                return false;
+            else
+                return true;
+        }
+        sort!(lt)(_link);
+    }
+
+    this()
+    {
+        _link ~= Link(8, 3);
+        _link ~= Link(4, 7);
+        _link ~= Link(4, 6);
+        _link ~= Link(3, 7);
+        _link ~= Link(2, 7);
+        _link ~= Link(2, 2);
+        _link ~= Link(4, 1);
+    }
+
+    Link[] _link;
+}
+
+void test18()
+{
+    C18 foo = new C18;
+    foo.sort_links();
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=29
+
+void test29()
+{
+    import std.string : format;
+    import std.conv : text;
+
+    string s;
+    for (auto i = 0; i < 100000; i++)
+    {
+        s = format("%d", i);
+        s = text(i);
+    }
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=52
+
+class C52
+{
+    C52 a;
+
+    this()
+    {
+        printf("Construct: this=%p\n", cast(void*)this);
+        a = this;
+    }
+
+    bool check()
+    {
+        printf("Check: this=%p a=%p\n", cast(void*)this, cast(void*)a);
+        return this is a;
+    }
+}
+
+auto test52a()
+{
+    import std.conv, std.traits;
+
+    struct Scoped
+    {
+        void[__traits (classInstanceSize, C52) ] Scoped_store = void;
+
+        inout(C52) Scoped_payload() inout
+        {
+            void* alignedStore = cast(void*) Scoped_store.ptr;
+            return cast(inout (C52)) alignedStore;
+        }
+        alias Scoped_payload this;
+    }
+
+    Scoped result;
+    emplace!(Unqual!C52)(result.Scoped_store);
+    assert(result.Scoped_payload().check);
+    return result;
+}
+
+void test52()
+{
+    auto a1 = test52a();
+    assert(a1.Scoped_payload().check);
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=71
+
+struct Leaf
+{
+    ubyte symbol;
+    ubyte codeLen;
+}
+
+struct CanonicalHuffman
+{
+    Leaf[] table;
+
+    void print()
+    {
+        import std.algorithm;
+        import std.range;
+
+        auto list = zip(iota(table.length), table.dup).array
+            .sort!((a, b) => a[1].symbol < b[1].symbol)
+            .uniq!((a, b) => (a[0] & (1 << a[1].codeLen) - 1) == (b[0] & (1 << b[1].codeLen) - 1));
+    }
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=77
+
+void fun(ubyte[3] buf)
+{
+    import std.bitmanip : bigEndianToNative;
+    bigEndianToNative!ushort(buf[0..2]);
+}
+
+void test77()
+{
+    fun([1,2,3]);
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=108
+
+@attribute("forceinline")
+void test108()
+{
+    import std.stdio : writeln;
+    writeln("Here");
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=122
+
+void test122()
+{
+    import std.algorithm : map;
+    import std.parallelism : taskPool;
+    import std.range : iota;
+
+    immutable n = 10000;
+    enum delta = 1.0 / n;       // XBUG: was 'immutable delta' https://issues.dlang.org/show_bug.cgi?id=17092
+    immutable pi = 4.0 * delta * taskPool.reduce!"a + b"(
+        map!((int i) { immutable x = (i - 0.5) * delta; return 1.0 / (1.0 + x * x); })(iota(n)));
+}
+
+/******************************************/
+
+void main()
+{
+    test2();
+    test16();
+    test18();
+    test52();
+    test77();
+    test108();
+
+    printf("Success!\n");
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 3758bb3a91d..5704a2fc583 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -8069,6 +8069,21 @@ proc check_effective_target_d_runtime { } {
     }]
 }
 
+# Return 1 if the target provides the D standard library.
+
+proc check_effective_target_d_runtime_has_std_library { } {
+    return [check_no_compiler_messages d_runtime_has_std_library executable {
+	// D
+	module mod;
+
+	extern(C) int main() {
+	    import std.math;
+	    real function(real) pcos = &cos;
+	    return 0;
+	}
+    }]
+}
+
 # Return 1 if  target wchar_t is at least 4 bytes.
 
 proc check_effective_target_4byte_wchar_t { } {
diff --git a/libphobos/testsuite/libphobos.phobos/phobos.exp b/libphobos/testsuite/libphobos.phobos/phobos.exp
index 3d876acf27b..aad877c24c2 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -19,6 +19,11 @@ if { ![isnative] || ![is-effective-target static] } {
     return
 }
 
+# Skip running test if phobos was not built on the target.
+if { ![is-effective-target d_runtime_has_std_library] } {
+    return
+}
+
 # Gather a list of all tests.
 set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]
 
diff --git a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
index 43b9772d6f2..a00ecf11ac9 100644
--- a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
+++ b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
@@ -19,6 +19,11 @@ if { ![isnative] || ![is-effective-target shared] } {
     return
 }
 
+# Skip running test if phobos was not built on the target.
+if { ![is-effective-target d_runtime_has_std_library] } {
+    return
+}
+
 # Gather a list of all tests.
 set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]
diff mbox series

Patch

diff --git a/gcc/testsuite/gdc.dg/link.d b/gcc/testsuite/gdc.dg/link.d
index a8ca4ed5cb6..5efd0ad347f 100644
--- a/gcc/testsuite/gdc.dg/link.d
+++ b/gcc/testsuite/gdc.dg/link.d
@@ -1,4 +1,4 @@ 
-// { dg-do link { target d_runtime } }
+// { dg-do link { target d_runtime_has_std_library } }
 
 /******************************************/
 
diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d
index 484a9709bf3..7307e09a645 100644
--- a/gcc/testsuite/gdc.dg/runnable.d
+++ b/gcc/testsuite/gdc.dg/runnable.d
@@ -9,20 +9,6 @@  import core.stdc.stdio;
 import gcc.attribute;
 
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=2
-
-struct S
-{
-    string toString() { return "foo"; }
-}
-
-void test2()
-{
-    import std.string : format;
-    assert(format("%s", S()) == "foo");
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=4
 
@@ -33,35 +19,6 @@  void test4()
     static assert(!__traits(compiles, str.sort));
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=15
-
-class B
-{
-    class A { }
-    A a;
-}
-
-class C
-{
-    void visit(B b)
-    {
-        import std.algorithm : map;
-        auto as = [b.a];
-        as.map!(d => d);
-    }
-}
-
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=16
-
-void test16()
-{
-    import std.parallelism : taskPool;
-
-    taskPool.reduce!"a+b"([0, 1, 2, 3]);
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=17
 
@@ -99,59 +56,6 @@  void test17()
   (new ModuleWriter()).save ("test.0.mci");
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=18
-
-class C18
-{
-    struct Link
-    {
-        int x;
-        int y;
-    }
-
-    void sort_links()
-    {
-        import std.algorithm : sort;
-        import std.array : empty;
-        import std.exception : enforce;
-
-        enforce(!_link.empty);
-
-        bool lt(Link a, Link b)
-        {
-            if(a.x > b.x)
-                return false;
-            if(a.x < b.x)
-                return true;
-            if(a.y >= b.y)
-                return false;
-            else
-                return true;
-        }
-        sort!(lt)(_link);
-    }
-
-    this()
-    {
-        _link ~= Link(8, 3);
-        _link ~= Link(4, 7);
-        _link ~= Link(4, 6);
-        _link ~= Link(3, 7);
-        _link ~= Link(2, 7);
-        _link ~= Link(2, 2);
-        _link ~= Link(4, 1);
-    }
-
-    Link[] _link;
-}
-
-void test18()
-{
-    C18 foo = new C18;
-    foo.sort_links();
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=19
 
@@ -177,22 +81,6 @@  void test24()
         return;
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=29
-
-void test29()
-{
-    import std.string : format;
-    import std.conv : text;
-
-    string s;
-    for (auto i = 0; i < 100000; i++)
-    {
-        s = format("%d", i);
-        s = text(i);
-    }
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=31
 
@@ -499,54 +387,6 @@  void test51()
     assert (s.x == 0);
 }
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=52
-
-class C52
-{
-    C52 a;
-
-    this()
-    {
-        printf("Construct: this=%p\n", cast(void*)this);
-        a = this;
-    }
-
-    bool check()
-    {
-        printf("Check: this=%p a=%p\n", cast(void*)this, cast(void*)a);
-        return this is a;
-    }
-}
-
-auto test52a()
-{
-    import std.conv, std.traits;
-
-    struct Scoped
-    {
-        void[__traits (classInstanceSize, C52) ] Scoped_store = void;
-
-        inout(C52) Scoped_payload() inout
-        {
-            void* alignedStore = cast(void*) Scoped_store.ptr;
-            return cast(inout (C52)) alignedStore;
-        }
-        alias Scoped_payload this;
-    }
-
-    Scoped result;
-    emplace!(Unqual!C52)(result.Scoped_store);
-    assert(result.Scoped_payload().check);
-    return result;
-}
-
-void test52()
-{
-    auto a1 = test52a();
-    assert(a1.Scoped_payload().check);
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=57
 
@@ -588,54 +428,6 @@  void test66()
 __vector(float[4]) d[2];  // ICE
 
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=71
-
-struct Leaf
-{
-    ubyte symbol;
-    ubyte codeLen;
-}
-
-struct CanonicalHuffman
-{
-    Leaf[] table;
-
-    void print()
-    {
-        import std.algorithm;
-        import std.range;
-
-        auto list = zip(iota(table.length), table.dup).array
-            .sort!((a, b) => a[1].symbol < b[1].symbol)
-            .uniq!((a, b) => (a[0] & (1 << a[1].codeLen) - 1) == (b[0] & (1 << b[1].codeLen) - 1));
-    }
-}
-
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=77
-
-void fun(ubyte[3] buf)
-{
-    import std.bitmanip : bigEndianToNative;
-    bigEndianToNative!ushort(buf[0..2]);
-}
-
-void test77()
-{
-    fun([1,2,3]);
-}
-
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=108
-
-@attribute("forceinline")
-void test108()
-{
-    import std.stdio : writeln;
-    writeln("Here");
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=115
 
@@ -657,21 +449,6 @@  void test115()
 
 immutable char C121 = void; // ICE
 
-/******************************************/
-// https://bugzilla.gdcproject.org/show_bug.cgi?id=122
-
-void test122()
-{
-    import std.algorithm : map;
-    import std.parallelism : taskPool;
-    import std.range : iota;
-
-    immutable n = 10000;
-    enum delta = 1.0 / n;       // XBUG: was 'immutable delta' https://issues.dlang.org/show_bug.cgi?id=17092
-    immutable pi = 4.0 * delta * taskPool.reduce!"a + b"(
-        map!((int i) { immutable x = (i - 0.5) * delta; return 1.0 / (1.0 + x * x); })(iota(n)));
-}
-
 /******************************************/
 // https://bugzilla.gdcproject.org/show_bug.cgi?id=127
 
@@ -1584,20 +1361,14 @@  void test309()
 
 void main()
 {
-    test2();
     test4();
-    test16();
     test17();
-    test18();
     test35();
     test36();
     test43();
     test51();
-    test52();
     test57();
     test66();
-    test77();
-    test108();
     test115();
     test131();
     test133();
diff --git a/gcc/testsuite/gdc.dg/runnable2.d b/gcc/testsuite/gdc.dg/runnable2.d
new file mode 100644
index 00000000000..d9463e337c1
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/runnable2.d
@@ -0,0 +1,244 @@ 
+// { dg-do run { target { hw && d_runtime_has_std_library } } }
+
+module runnable;
+
+import core.stdc.stdio;
+import gcc.attribute;
+
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=2
+
+struct S
+{
+    string toString() { return "foo"; }
+}
+
+void test2()
+{
+    import std.string : format;
+    assert(format("%s", S()) == "foo");
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=15
+
+class B
+{
+    class A { }
+    A a;
+}
+
+class C
+{
+    void visit(B b)
+    {
+        import std.algorithm : map;
+        auto as = [b.a];
+        as.map!(d => d);
+    }
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=16
+
+void test16()
+{
+    import std.parallelism : taskPool;
+
+    taskPool.reduce!"a+b"([0, 1, 2, 3]);
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=18
+
+class C18
+{
+    struct Link
+    {
+        int x;
+        int y;
+    }
+
+    void sort_links()
+    {
+        import std.algorithm : sort;
+        import std.array : empty;
+        import std.exception : enforce;
+
+        enforce(!_link.empty);
+
+        bool lt(Link a, Link b)
+        {
+            if(a.x > b.x)
+                return false;
+            if(a.x < b.x)
+                return true;
+            if(a.y >= b.y)
+                return false;
+            else
+                return true;
+        }
+        sort!(lt)(_link);
+    }
+
+    this()
+    {
+        _link ~= Link(8, 3);
+        _link ~= Link(4, 7);
+        _link ~= Link(4, 6);
+        _link ~= Link(3, 7);
+        _link ~= Link(2, 7);
+        _link ~= Link(2, 2);
+        _link ~= Link(4, 1);
+    }
+
+    Link[] _link;
+}
+
+void test18()
+{
+    C18 foo = new C18;
+    foo.sort_links();
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=29
+
+void test29()
+{
+    import std.string : format;
+    import std.conv : text;
+
+    string s;
+    for (auto i = 0; i < 100000; i++)
+    {
+        s = format("%d", i);
+        s = text(i);
+    }
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=52
+
+class C52
+{
+    C52 a;
+
+    this()
+    {
+        printf("Construct: this=%p\n", cast(void*)this);
+        a = this;
+    }
+
+    bool check()
+    {
+        printf("Check: this=%p a=%p\n", cast(void*)this, cast(void*)a);
+        return this is a;
+    }
+}
+
+auto test52a()
+{
+    import std.conv, std.traits;
+
+    struct Scoped
+    {
+        void[__traits (classInstanceSize, C52) ] Scoped_store = void;
+
+        inout(C52) Scoped_payload() inout
+        {
+            void* alignedStore = cast(void*) Scoped_store.ptr;
+            return cast(inout (C52)) alignedStore;
+        }
+        alias Scoped_payload this;
+    }
+
+    Scoped result;
+    emplace!(Unqual!C52)(result.Scoped_store);
+    assert(result.Scoped_payload().check);
+    return result;
+}
+
+void test52()
+{
+    auto a1 = test52a();
+    assert(a1.Scoped_payload().check);
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=71
+
+struct Leaf
+{
+    ubyte symbol;
+    ubyte codeLen;
+}
+
+struct CanonicalHuffman
+{
+    Leaf[] table;
+
+    void print()
+    {
+        import std.algorithm;
+        import std.range;
+
+        auto list = zip(iota(table.length), table.dup).array
+            .sort!((a, b) => a[1].symbol < b[1].symbol)
+            .uniq!((a, b) => (a[0] & (1 << a[1].codeLen) - 1) == (b[0] & (1 << b[1].codeLen) - 1));
+    }
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=77
+
+void fun(ubyte[3] buf)
+{
+    import std.bitmanip : bigEndianToNative;
+    bigEndianToNative!ushort(buf[0..2]);
+}
+
+void test77()
+{
+    fun([1,2,3]);
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=108
+
+@attribute("forceinline")
+void test108()
+{
+    import std.stdio : writeln;
+    writeln("Here");
+}
+
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=122
+
+void test122()
+{
+    import std.algorithm : map;
+    import std.parallelism : taskPool;
+    import std.range : iota;
+
+    immutable n = 10000;
+    enum delta = 1.0 / n;       // XBUG: was 'immutable delta' https://issues.dlang.org/show_bug.cgi?id=17092
+    immutable pi = 4.0 * delta * taskPool.reduce!"a + b"(
+        map!((int i) { immutable x = (i - 0.5) * delta; return 1.0 / (1.0 + x * x); })(iota(n)));
+}
+
+/******************************************/
+
+void main()
+{
+    test2();
+    test16();
+    test18();
+    test52();
+    test77();
+    test108();
+
+    printf("Success!\n");
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 3758bb3a91d..5704a2fc583 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -8069,6 +8069,21 @@  proc check_effective_target_d_runtime { } {
     }]
 }
 
+# Return 1 if the target provides the D standard library.
+
+proc check_effective_target_d_runtime_has_std_library { } {
+    return [check_no_compiler_messages d_runtime_has_std_library executable {
+	// D
+	module mod;
+
+	extern(C) int main() {
+	    import std.math;
+	    real function(real) pcos = &cos;
+	    return 0;
+	}
+    }]
+}
+
 # Return 1 if  target wchar_t is at least 4 bytes.
 
 proc check_effective_target_4byte_wchar_t { } {
diff --git a/libphobos/testsuite/libphobos.phobos/phobos.exp b/libphobos/testsuite/libphobos.phobos/phobos.exp
index 3d876acf27b..aad877c24c2 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -19,6 +19,11 @@  if { ![isnative] || ![is-effective-target static] } {
     return
 }
 
+# Skip running test if phobos was not built on the target.
+if { ![is-effective-target d_runtime_has_std_library] } {
+    return
+}
+
 # Gather a list of all tests.
 set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]
 
diff --git a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
index 43b9772d6f2..a00ecf11ac9 100644
--- a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
+++ b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
@@ -19,6 +19,11 @@  if { ![isnative] || ![is-effective-target shared] } {
     return
 }
 
+# Skip running test if phobos was not built on the target.
+if { ![is-effective-target d_runtime_has_std_library] } {
+    return
+}
+
 # Gather a list of all tests.
 set tests [lsort [filter_libphobos_unittests [find $srcdir/../src "*.d"]]]