aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gdc.test
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2020-03-13 21:03:02 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2020-03-13 21:03:02 +0100
commit5b74dd0a2278365eb562d9d1999c3c11cddb733c (patch)
treed50cf33dd430febb733c654fc1ea60dc7a34609f /gcc/testsuite/gdc.test
parentdb3fa3476e9e922ca3e283df03ebd14be7220b6e (diff)
downloadgcc-5b74dd0a2278365eb562d9d1999c3c11cddb733c.zip
gcc-5b74dd0a2278365eb562d9d1999c3c11cddb733c.tar.gz
gcc-5b74dd0a2278365eb562d9d1999c3c11cddb733c.tar.bz2
d/dmd: Merge upstream dmd e9420cfbf
1. Implement DIP 1010 - (Static foreach) Support for 'static foreach' has been added. 'static foreach' is a conditional compilation construct that is to 'foreach' what 'static if' is to 'if'. It is a convenient way to generate declarations and statements by iteration. import std.conv: to; static foreach(i; 0 .. 10) { // a 'static foreach' body does not introduce a nested scope // (similar to 'static if'). // The following mixin declaration is at module scope: // declares 10 variables x0, x1, ..., x9 mixin('enum x' ~ to!string(i) ~ ' = i;'); } import std.range: iota; // all aggregate types that can be iterated with a standard 'foreach' // loop are also supported by static foreach: static foreach(i; iota(10)) { // we access the declarations generated in the first 'static foreach' pragma(msg, "x", i, ": ", mixin(`x` ~ to!string(i))); static assert(mixin(`x` ~ to!string(i)) == i); } void main() { import std.conv: text; import std.typecons: tuple; import std.algorithm: map; import std.stdio: writeln; // 'static foreach' has both declaration and statement forms // (similar to 'static if'). static foreach(x; iota(3).map!(i => tuple(text("x", i), i))) { // generates three local variables x0, x1 and x2. mixin(text(`int `,x[0],` = x[1];`)); scope(exit) // this is within the scope of 'main' { writeln(mixin(x[0])); } } writeln(x0," ",x1," ",x2); // first runtime output } 2. Aliases can be created directly from a '__trait'. Aliases can be created directly from the traits that return symbol(s) or tuples. This includes 'getMember', 'allMembers', 'derivedMembers', 'parent', 'getOverloads', 'getVirtualFunctions', 'getVirtualMethods', 'getUnitTests', 'getAttributes' and finally 'getAliasThis'. Previously an 'AliasSeq' was necessary in order to alias their return. Now the grammar allows to write shorter declarations: struct Foo { static int a; } alias oldWay = AliasSeq!(__traits(getMember, Foo, "a"))[0]; alias newWay = __traits(getMember, Foo, "a"); To permit this it was more interesting to include '__trait' in the basic types rather than just changing the alias syntax. So additionally, wherever a type appears a '__trait' can be used, for example in a variable declaration: struct Foo { static struct Bar {} } const(__traits(getMember, Foo, "Bar")) fooBar; static assert(is(typeof(fooBar) == const(Foo.Bar))); 3. fix Issue 10100 - Identifiers with double underscores and allMembers The identifer whitelist has been converted into a blacklist of all possible internal D language declarations. Reviewed-on: https://github.com/dlang/dmd/pull/10791
Diffstat (limited to 'gcc/testsuite/gdc.test')
-rw-r--r--gcc/testsuite/gdc.test/compilable/b12001.d9
-rw-r--r--gcc/testsuite/gdc.test/compilable/json.d21
-rw-r--r--gcc/testsuite/gdc.test/compilable/staticforeach.d842
-rw-r--r--gcc/testsuite/gdc.test/compilable/test11169.d15
-rw-r--r--gcc/testsuite/gdc.test/compilable/test17819.d17
-rw-r--r--gcc/testsuite/gdc.test/compilable/test18871.d15
-rw-r--r--gcc/testsuite/gdc.test/compilable/test7815.d (renamed from gcc/testsuite/gdc.test/fail_compilation/fail7815.d)6
-rw-r--r--gcc/testsuite/gdc.test/compilable/test7886.d5
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/e7804_1.d11
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/e7804_2.d19
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail11169.d28
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail19182.d18
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail19336.d17
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail19520.d21
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail2195.d18
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7886.d5
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/staticforeach1.d13
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/staticforeach2.d13
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/staticforeach3.d7
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test17307.d12
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/traits_alone.d10
-rw-r--r--gcc/testsuite/gdc.test/runnable/arrayop.d3
-rw-r--r--gcc/testsuite/gdc.test/runnable/constfold.d18
-rw-r--r--gcc/testsuite/gdc.test/runnable/e7804.d179
-rw-r--r--gcc/testsuite/gdc.test/runnable/imports/template13478a.d5
-rw-r--r--gcc/testsuite/gdc.test/runnable/staticforeach.d45
-rw-r--r--gcc/testsuite/gdc.test/runnable/test42.d60
-rw-r--r--gcc/testsuite/gdc.test/runnable/traits.d38
28 files changed, 1365 insertions, 105 deletions
diff --git a/gcc/testsuite/gdc.test/compilable/b12001.d b/gcc/testsuite/gdc.test/compilable/b12001.d
new file mode 100644
index 0000000..f67c895
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/b12001.d
@@ -0,0 +1,9 @@
+void main()
+{
+ static assert(__traits(isSame, int, int));
+ static assert(__traits(isSame, int[][], int[][]));
+ static assert(__traits(isSame, bool*, bool*));
+
+ static assert(!__traits(isSame, bool*, bool[]));
+ static assert(!__traits(isSame, float, double));
+}
diff --git a/gcc/testsuite/gdc.test/compilable/json.d b/gcc/testsuite/gdc.test/compilable/json.d
index b5a560d..e2b0860 100644
--- a/gcc/testsuite/gdc.test/compilable/json.d
+++ b/gcc/testsuite/gdc.test/compilable/json.d
@@ -111,3 +111,24 @@ enum Numbers
}
template IncludeConstraint(T) if (T == string) {}
+
+static foreach(enum i; 0..3)
+{
+ mixin("int a" ~ i.stringof ~ " = 1;");
+}
+
+alias Seq(T...) = T;
+
+static foreach(int i, alias a; Seq!(a0, a1, a2))
+{
+ mixin("alias b" ~ i.stringof ~ " = a;");
+}
+
+mixin template test18211(int n)
+{
+ static foreach (i; 0 .. n>10 ? 10 : n)
+ {
+ mixin("enum x" ~ cast(char)('0' + i));
+ }
+ static if (true) {}
+}
diff --git a/gcc/testsuite/gdc.test/compilable/staticforeach.d b/gcc/testsuite/gdc.test/compilable/staticforeach.d
new file mode 100644
index 0000000..48d06b4
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/staticforeach.d
@@ -0,0 +1,842 @@
+// REQUIRED_ARGS: -o-
+// PERMUTE_ARGS:
+// EXTRA_FILES: imports/imp12242a1.d imports/imp12242a2.d
+/*
+TEST_OUTPUT:
+---
+9
+8
+7
+6
+5
+4
+3
+2
+1
+0
+S(1, 2, 3, [0, 1, 2])
+x0: 1
+x1: 2
+x2: 3
+a: [0, 1, 2]
+(int[], char[], bool[], Object[])
+[0, 0]
+x0: int
+x1: double
+x2: char
+test(0)→ 0
+test(1)→ 1
+test(2)→ 2
+test(3)→ 3
+test(4)→ 4
+test(5)→ 5
+test(6)→ 6
+test(7)→ 7
+test(8)→ 8
+test(9)→ 9
+test(10)→ -1
+test(11)→ -1
+test(12)→ -1
+test(13)→ -1
+test(14)→ -1
+1
+[1, 2, 3]
+2
+[1, 2, 3]
+3
+[1, 2, 3]
+0 1
+1 2
+2 3
+1
+3
+4
+object
+Tuple
+tuple
+main
+front
+popFront
+empty
+back
+popBack
+Iota
+iota
+map
+to
+text
+all
+any
+join
+S
+s
+Seq
+Overloads
+Parameters
+forward
+foo
+A
+B
+C
+D
+E
+Types
+Visitor
+testVisitor
+staticMap
+arrayOf
+StaticForeachLoopVariable
+StaticForeachScopeExit
+StaticForeachReverseHiding
+UnrolledForeachReverse
+StaticForeachReverse
+StaticForeachByAliasDefault
+NestedStaticForeach
+TestAliasOutsideFunctionScope
+OpApplyMultipleStaticForeach
+OpApplyMultipleStaticForeachLowered
+RangeStaticForeach
+OpApplySingleStaticForeach
+TypeStaticForeach
+AliasForeach
+EnumForeach
+TestUninterpretable
+SeqForeachConstant
+SeqForeachBreakContinue
+TestStaticForeach
+testtest
+fun
+testEmpty
+bug17660
+breakContinueBan
+MixinTemplate
+testToStatement
+bug17688
+T
+foo2
+T2
+1 2 '3'
+2 3 '4'
+0 1
+1 2
+2 3
+---
+*/
+
+module staticforeach;
+
+struct Tuple(T...){
+ T expand;
+ alias expand this;
+}
+auto tuple(T...)(T t){ return Tuple!T(t); }
+
+/+struct TupleStaticForeach{ // should work, but is not the fault of the static foreach implementation.
+ //pragma(msg, [tuple(1,"2",'3'),tuple(2,"3",'4')].map!((x)=>x));
+ static foreach(a,b,c;[tuple(1,"2",'3'),tuple(2,"3",'4')].map!((x)=>x)){
+ pragma(msg,a," ",b," ",c);
+ }
+}+/
+
+void main(){
+ static foreach(a,b,c;[tuple(1,"2",'3'),tuple(2,"3",'4')].map!((x)=>x)){
+ pragma(msg, a," ",b," ",c);
+ }
+ static struct S{
+ // (aggregate scope, forward referencing possible)
+ static assert(stripA("123")==1);
+ static assert(stripA([1],2)==2);
+ static foreach(i;0..2){
+ mixin(`import imports.imp12242a`~text(i+1)~`;`);
+ static assert(stripA("123")==1);
+ static assert(stripA([1],2)==2);
+ }
+ static assert(stripA("123")==1);
+ static assert(stripA([1],2)==2);
+ }
+ static foreach(i;0..2){
+ // (function scope, no forward referencing)
+ mixin(`import imports.imp12242a`~text(i+1)~`;`);
+ static assert(stripA("123")==1);
+ static if(i) static assert(stripA([1],2)==2);
+ }
+ static assert(stripA("123")==1);
+ static assert(stripA([1],2)==2);
+}
+
+auto front(T)(T[] a){ return a[0]; }
+auto popFront(T)(ref T[] a){ a=a[1..$]; }
+auto empty(T)(T[] a){ return !a.length; }
+auto back(T)(T[] a){ return a[$-1]; }
+auto popBack(T)(ref T[] a){ a=a[0..$-1]; }
+
+struct Iota(T){
+ T s,e;
+ @property bool empty(){ return s>=e; }
+ @property T front(){ return s; }
+ @property T back(){ return cast(T)(e-1); }
+ void popFront(){ s++; }
+ void popBack(){ e--; }
+}
+auto iota(T)(T s, T e){ return Iota!T(s,e); }
+
+template map(alias a){
+ struct Map(R){
+ R r;
+ @property front(){ return a(r.front); }
+ @property back(){ return a(r.back); }
+ @property bool empty(){ return r.empty; }
+ void popFront(){ r.popFront(); }
+ void popBack(){ r.popBack(); }
+ }
+ auto map(R)(R r){ return Map!R(r); }
+}
+
+template to(T:string){
+ string to(S)(S x)if(is(S:int)||is(S:size_t)||is(S:char)){
+ static if(is(S==char)) return cast(string)[x];
+ if(x<0) return "-"~to(-1 * x);
+ if(x==0) return "0";
+ return (x>=10?to(x/10):"")~cast(char)(x%10+'0');
+ }
+}
+auto text(T)(T arg){ return to!string(arg); };
+
+template all(alias a){
+ bool all(R)(R r){
+ foreach(x;r) if(!a(x)) return false;
+ return true;
+ }
+}
+template any(alias a){
+ bool any(R)(R r){
+ foreach(x;r) if(a(x)) return true;
+ return false;
+ }
+}
+auto join(R)(R r,string sep=""){
+ string a;
+ int first=0;
+ foreach(x;r){
+ if(first++) a~=sep;
+ a~=x;
+ }
+ return a;
+}
+
+static foreach_reverse(x;iota(0,10).map!(to!string)){
+ pragma(msg, x);
+}
+
+// create struct members iteratively
+struct S{
+ static foreach(i;a){
+ mixin("int x"~to!string(i)~";");
+ }
+ immutable int[] a = [0,1,2];
+}
+enum s=S(1,2,3);
+pragma(msg, s);
+
+// loop over struct members
+static foreach(member;__traits(allMembers,S)){
+ pragma(msg, member,": ",mixin("s."~member));
+}
+
+// print prime numbers using overload sets as state variables.
+/+
+static assert(is(typeof(bad57)));
+static assert(!is(typeof(bad53)));
+
+static foreach(x;iota(2,100)){
+ static foreach(y;iota(2,x)){
+ static if(!(x%y)){
+ mixin("void bad"~to!string(x)~"();");
+ }
+ }
+ static if(!is(typeof(mixin("bad"~to!string(x))))){
+ static assert(iota(2,x).all!(y=>!!(x%y)));
+ pragma(msg, x);
+ }else{
+ static assert(iota(2,x).any!(y=>!(x%y)));
+ }
+}
++/
+
+
+alias Seq(T...)=T;
+
+alias Overloads(alias a) = Seq!(__traits(getOverloads, __traits(parent, a), __traits(identifier, a)));
+
+template Parameters(alias f){
+ static if(is(typeof(f) P == function)) alias Parameters=P;
+}
+
+template forward(alias a){
+ enum x=2;
+ static foreach(f;Overloads!a){
+ auto ref forward(Parameters!f args){
+ return f(args);
+ }
+ }
+ enum y=3;
+}
+
+int foo(int x){ return x; }
+string foo(string x){ return x; }
+
+static assert(forward!foo(2)==2 && forward!foo("hi") == "hi");
+
+
+// simple boilerplate-free visitor pattern
+static foreach(char T;'A'..'F'){
+ mixin("class "~T~q{{
+ void accept(Visitor v){
+ return v.visit(this);
+ }
+ }});
+}
+alias Types = Seq!(mixin("Seq!("~iota('A','F').map!(to!string).join(", ")~")"));
+abstract class Visitor{
+ static foreach(T;Types){
+ abstract void visit(T);
+ }
+}
+
+string testVisitor(){
+ string r;
+ void writeln(T...)(T args){
+ static foreach(x;args) r~=x;
+ r~='\n';
+ }
+ class Visitor: .Visitor{
+ static foreach(T;Types){
+ override void visit(T){
+ writeln("visited: ",T.stringof);
+ }
+ }
+ }
+ void main(){
+ auto v=new Visitor;
+ static foreach(T;Types){
+ v.visit(new T);
+ }
+ }
+ main();
+ return r;
+}
+static assert(testVisitor()=="visited: A
+visited: B
+visited: C
+visited: D
+visited: E
+");
+
+// iterative computation over AliasSeq:
+template staticMap(alias F,T...){
+ alias state0=Seq!();
+ static foreach(i,A;T){
+ mixin("alias state"~to!string(i+1)~" = Seq!(state"~to!string(i)~",F!A);");
+ }
+ alias staticMap = Seq!(mixin("state"~to!string(T.length)));
+}
+
+alias arrayOf(T)=T[];
+static assert(is(staticMap!(arrayOf,int,char,bool,Object)==Seq!(int[], char[], bool[], Object[])));
+pragma(msg, staticMap!(arrayOf,int,char,bool,Object));
+
+
+struct StaticForeachLoopVariable{
+ int x;
+ static foreach(i;0..1){
+ mixin("enum x"~text(i)~" = i;");
+ }
+ int y;
+ static assert(__traits(allMembers, StaticForeachLoopVariable).length==3);
+ static assert(!is(typeof(StaticForeachLoopVariable.i)));
+ static assert(!is(typeof(__traits(getMember, StaticForeachLoopVariable, "i"))));
+}
+
+struct StaticForeachScopeExit{
+static:
+ int[] test(){
+ int[] r;
+ scope(exit) r ~= 1234;
+ {
+ static foreach(i;0..5){
+ scope(exit) r ~= i;
+ }
+ r ~= 5;
+ }
+ return r;
+ }
+ static assert(test()==[5,4,3,2,1,0]);
+}
+
+struct StaticForeachReverseHiding{
+ static foreach(i;[0]){
+ enum i = 1; // TODO: disallow?
+ static assert(i==0);
+ }
+}
+
+struct UnrolledForeachReverse{
+static:
+ alias Seq(T...)=T;
+ int[] test(){
+ int[] r;
+ foreach_reverse(i;Seq!(0,1,2,3)){
+ r~=i;
+ }
+ return r;
+ }
+ static assert(test()==[3,2,1,0]);
+}
+
+struct StaticForeachReverse{
+static:
+ alias Seq(T...)=T;
+ int[] test(){
+ int[] r;
+ static foreach_reverse(i;0..4){
+ r~=i;
+ }
+ return r;
+ }
+ static assert(test()==[3,2,1,0]);
+
+ int[] test2(){
+ int[] r;
+ static foreach_reverse(i;[0,1,2,3]){
+ r~=i;
+ }
+ return r;
+ }
+ static assert(test2()==[3,2,1,0]);
+
+ int[] test3(){
+ static struct S{
+ int opApplyReverse(scope int delegate(int) dg){
+ foreach_reverse(i;0..4) if(auto r=dg(i)) return r;
+ return 0;
+ }
+ }
+ int[] r;
+ static foreach_reverse(i;S()){
+ r~=i;
+ }
+ return r;
+ }
+ static assert(test3()==[3,2,1,0]);
+
+ int[] test4(){
+ int[] r;
+ static foreach_reverse(i;Seq!(0,1,2,3)){
+ r~=i;
+ }
+ return r;
+ }
+ static assert(test()==[3,2,1,0]);
+}
+
+struct StaticForeachByAliasDefault{
+static:
+ alias Seq(T...)=T;
+
+ int[] test(){
+ int a,b,c;
+ static foreach(i,x;Seq!(a,b,c)) x=i;
+ return [a,b,c];
+ }
+ static assert(test()==[0,1,2]);
+
+ int[] test2(){
+ int x=0;
+ int foo(){ return ++x; }
+ static foreach(y;Seq!foo)
+ return [y,y,y];
+ }
+ static assert(test2()==[1,2,3]);
+
+ void test3(){
+ int x=0;
+ int foo(){ return ++x; }
+ static assert(!is(typeof({
+ static foreach(enum y;Seq!foo)
+ return [y,y,y];
+ })));
+ }
+}
+
+struct NestedStaticForeach{
+ static:
+ static foreach(i,name;["a"]){
+ static foreach(j,name2;["d"]){
+ mixin("enum int[] "~name~name2~"=[i, j];");
+ }
+ }
+ pragma(msg, ad);
+}
+
+struct TestAliasOutsideFunctionScope{
+static:
+ alias Seq(T...)=T;
+ int a;
+ static foreach(alias x;Seq!(a)){
+ }
+}
+
+struct OpApplyMultipleStaticForeach{
+static:
+ struct OpApply{
+ int opApply(scope int delegate(int,int) dg){
+ foreach(i;0..10) if(auto r=dg(i,i*i)) return r;
+ return 0;
+ }
+ }
+ static foreach(a,b;OpApply()){
+ mixin(`enum x`~cast(char)('0'+a)~"=b;");
+ }
+ static foreach(i;0..10){
+ static assert(mixin(`x`~cast(char)('0'+i))==i*i);
+ }
+}
+
+
+struct OpApplyMultipleStaticForeachLowered{
+static:
+ struct OpApply{
+ int opApply(scope int delegate(int,int) dg){
+ foreach(i;0..10) if(auto r=dg(i,i*i)) return r;
+ return 0;
+ }
+ }
+ static foreach(x;{
+ static struct S(T...){ this(T k){ this.x=k; } T x; }
+ static s(T...)(T a){ return S!T(a); }
+ typeof({ foreach(a,b;OpApply()){ return s(a,b); } assert(0);}())[] r;
+ foreach(a,b;OpApply()) r~=s(a,b);
+ return r;
+ }()){
+ mixin(`enum x`~cast(char)('0'+x.x[0])~"=x.x[1];");
+ }
+ static foreach(i;0..10){
+ static assert(mixin(`x`~cast(char)('0'+i))==i*i);
+ }
+}
+
+struct RangeStaticForeach{
+ static:
+ struct Range{
+ int x=0;
+ this(int x){ this.x=x; }
+ @property int front(){ return x; }
+ void popFront(){ x += 2; }
+ @property bool empty(){ return x>=10; }
+ }
+ static foreach(i;Range()){
+ mixin(`enum x`~cast(char)('0'+i)~"=i;");
+ }
+ static foreach(i;0..5){
+ static assert(mixin(`x`~cast(char)('0'+2*i))==2*i);
+ }
+ static assert(!is(typeof({
+ struct S{
+ static foreach(i,k;Range()){}
+ }
+ })));
+ static foreach(k;Range()){} // ok
+}
+
+struct OpApplySingleStaticForeach{
+ static:
+ struct OpApply{
+ int opApply(scope int delegate(int) dg){
+ foreach(i;0..10) if(auto r=dg(i)) return r;
+ return 0;
+ }
+ }
+ static foreach(b;OpApply()){
+ mixin(`enum x`~cast(char)('0'+b)~"=b;");
+ }
+ static foreach(i;0..10){
+ static assert(mixin(`x`~cast(char)('0'+i))==i);
+ }
+}
+
+struct TypeStaticForeach{
+static:
+ alias Seq(T...)=T;
+ static foreach(i,alias T;Seq!(int,double,char)){
+ mixin(`T x`~cast(char)('0'+i)~";");
+ }
+ pragma(msg, "x0: ",typeof(x0));
+ pragma(msg, "x1: ",typeof(x1));
+ pragma(msg, "x2: ",typeof(x2));
+ static assert(is(typeof(x0)==int));
+ static assert(is(typeof(x1)==double));
+ static assert(is(typeof(x2)==char));
+}
+
+struct AliasForeach{
+static:
+ alias Seq(T...)=T;
+ int[] test(){
+ int a,b,c;
+ static foreach(x;Seq!(a,b,c,2)){
+ static if(is(typeof({x=2;}))) x=2;
+ }
+ int x,y,z;
+ static foreach(alias k;Seq!(x,y,z,2)){
+ static if(is(typeof({k=2;}))) k=2;
+ }
+ int j,k,l;
+ static assert(!is(typeof({
+ static foreach(ref x;Seq!(j,k,l,2)){
+ static if(is(typeof({x=2;}))) x=2;
+ }
+ })));
+ return [x,y,z];
+ }
+ static assert(test()==[2,2,2]);
+}
+
+struct EnumForeach{
+static:
+ alias Seq(T...)=T;
+ int a=1;
+ int fun(){ return 1; }
+ int gun(){ return 2; }
+ int hun(){ return 3;}
+ auto test(){
+ static foreach(i,enum x;Seq!(fun,gun,hun)){
+ static assert(i+1==x);
+ }
+ foreach(i,enum x;Seq!(fun,gun,hun)){
+ static assert(i+1==x);
+ }
+ }
+}
+
+struct TestUninterpretable{
+static:
+ alias Seq(T...)=T;
+ auto test(){
+ int k;
+ static assert(!is(typeof({
+ static foreach(x;[k]){}
+ })));
+ static assert(!is(typeof({
+ foreach(enum x;[1,2,3]){}
+ })));
+ static assert(!is(typeof({
+ foreach(alias x;[1,2,3]){}
+ })));
+ foreach(enum x;Seq!(1,2,3)){} // ok
+ foreach(alias x;Seq!(1,2,3)){} // ok
+ static foreach(enum x;[1,2,3]){} // ok
+ static foreach(alias x;[1,2,3]){} // ok
+ static assert(!is(typeof({
+ static foreach(enum alias x;[1,2,3]){}
+ })));
+ int x;
+ static foreach(i;Seq!x){ } // ok
+ static foreach(i,j;Seq!(1,2,x)){ } // ok
+ static assert(!is(typeof({
+ static foreach(ref x;[1,2,3]){}
+ })));
+ }
+}
+
+struct SeqForeachConstant{
+static:
+ alias Seq(T...)=T;
+ static assert(!is(typeof({
+ foreach(x;Seq!1) x=2;
+ })));
+ int test2(){
+ int r=0;
+ foreach(x;Seq!(1,2,3)){
+ enum k=x;
+ r+=k;
+ }
+ return r;
+ }
+ static assert(test2()==6);
+}
+
+struct SeqForeachBreakContinue{
+static:
+ alias Seq(T...)=T;
+ int[] test(){
+ int[] r;
+ foreach(i;Seq!(0,1,2,3,4,5)){
+ if(i==2) continue;
+ if(i==4) break;
+ r~=i;
+ }
+ return r;
+ }
+ static assert(test()==[0,1,3]);
+}
+
+struct TestStaticForeach{
+static:
+ int test(int x){
+ int r=0;
+ label: switch(x){
+ static foreach(i;0..10){
+ case i: r=i; break label; // TODO: remove label when restriction is lifted
+ }
+ default: r=-1; break label;
+ }
+ return r;
+ }
+ static foreach(i;0..15){
+ pragma(msg, "test(",i,")→ ",test(i));
+ static assert(test(i)==(i<10?i:-1));
+ }
+
+ enum x=[1,2,3];
+
+ static foreach(i;x){
+ mixin("enum x"~cast(char)('0'+i)~"="~cast(char)('0'+i)~";");
+ }
+
+ static foreach(i;x){
+ pragma(msg, mixin("x"~cast(char)('0'+i)));
+ pragma(msg,x);
+ }
+
+ int[] noBreakNoContinue(){
+ int[] r;
+ static foreach(i;0..1){
+ // if(i==3) continue; // TODO: error?
+ // if(i==7) break; // TODO: error?
+ r~=i;
+ }
+ return r;
+ }
+
+ mixin("enum k=3;");
+}
+
+static foreach(i,j;[1,2,3]){
+ pragma(msg, int(i)," ",j);
+}
+
+void testtest(){
+ static foreach(i,v;[1,2,3]){
+ pragma(msg, int(i)," ",v);
+ static assert(i+1 == v);
+ }
+}
+
+
+static foreach(i;Seq!(1,2,3,4,int)){
+ static if(!is(i) && i!=2){
+ pragma(msg, i);
+ }
+}
+
+int fun(int x){
+ int r=0;
+ label: switch(x){
+ static foreach(i;Seq!(0,1,2,3,4,5,6)){
+ static if (i < 5)
+ case i: r=i; break label; // TODO: remove label when restriction is lifted
+ }
+ default: r=-1; break label;
+ }
+ return r;
+}
+
+static foreach(i;0..10) static assert(fun(i)==(i<5?i:-1));
+
+static foreach(i;0..0) { }
+void testEmpty(){
+ static foreach(i;0..0) { }
+}
+
+auto bug17660(){
+ int x;
+ static foreach (i; 0 .. 1) { return 3; }
+ return x;
+}
+static assert(bug17660()==3);
+
+int breakContinueBan(){
+ static assert(!is(typeof({
+ for(;;){
+ static foreach(i;0..1){
+ break;
+ }
+ }
+ })));
+ static assert(!is(typeof({
+ for(;;){
+ static foreach(i;0..1){
+ continue;
+ }
+ }
+ })));
+ Louter1: for(;;){
+ static foreach(i;0..1){
+ break Louter1;
+ }
+ }
+ Louter2: foreach(i;0..10){
+ static foreach(j;0..1){
+ continue Louter2;
+ }
+ return 0;
+ }
+ static foreach(i;0..1){
+ for(;;){ break; } // ok
+ }
+ return 1;
+}
+static assert(breakContinueBan()==1);
+
+mixin template MixinTemplate(){
+ static foreach(i;0..2){
+ mixin(`enum x`~cast(char)('0'+i)~"=i;");
+ }
+ static foreach(i;[0,1]){
+ mixin(`enum y`~cast(char)('0'+i)~"=i;");
+ }
+}
+void testToStatement(){
+ mixin MixinTemplate;
+ static assert(x0==0 && x1==1);
+ static assert(y0==0 && y1==1);
+}
+
+void bug17688(){
+ final switch(1) static foreach(x;0..1){ int y=3; case 1: return; }
+ static assert(!is(typeof(y)));
+}
+
+struct T{ enum n = 1; }
+T foo(T v)@nogc{
+ static foreach(x;0..v.n){ }
+ return T.init;
+}
+T foo2(T v)@nogc{
+ static foreach(_;0..typeof(return).n){ }
+ return T.init;
+}
+
+//https://issues.dlang.org/show_bug.cgi?id=18698
+
+static foreach(m; __traits(allMembers, staticforeach))
+{
+ pragma(msg, m);
+}
+
+//https://issues.dlang.org/show_bug.cgi?id=20072
+struct T2{
+ static foreach(i;0..1)
+ struct S{}
+}
+static assert(is(__traits(parent,T2.S)==T2));
diff --git a/gcc/testsuite/gdc.test/compilable/test11169.d b/gcc/testsuite/gdc.test/compilable/test11169.d
index 10a3df2..79863e1 100644
--- a/gcc/testsuite/gdc.test/compilable/test11169.d
+++ b/gcc/testsuite/gdc.test/compilable/test11169.d
@@ -43,3 +43,18 @@ void main()
static assert(!__traits(compiles, { auto b = new B2(); }));
static assert(!__traits(compiles, { auto b = new B3(); }));
}
+
+class B : A
+{
+ // __traits(isAbstractClass) is not usable in static if condition.
+ static assert (!__traits(isAbstractClass, typeof(this)));
+
+ override void foo()
+ {
+ }
+}
+
+void main2()
+{
+ B b = new B();
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test17819.d b/gcc/testsuite/gdc.test/compilable/test17819.d
new file mode 100644
index 0000000..f1266a0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test17819.d
@@ -0,0 +1,17 @@
+static if (__traits(allMembers, __traits(parent,{}))[0]=="object") {
+ enum test = 0;
+}
+
+static foreach (m; __traits(allMembers, __traits(parent,{}))) {
+ mixin("enum new"~m~"=`"~m~"`;");
+}
+
+static assert([__traits(allMembers, __traits(parent,{}))] == ["object", "test", "newobject", "newWorld", "newBuildStuff", "World", "BuildStuff"]);
+
+struct World {
+ mixin BuildStuff;
+}
+
+template BuildStuff() {
+ static foreach(elem; __traits(allMembers, typeof(this))) {}
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test18871.d b/gcc/testsuite/gdc.test/compilable/test18871.d
new file mode 100644
index 0000000..44486f2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test18871.d
@@ -0,0 +1,15 @@
+// https://issues.dlang.org/show_bug.cgi?id=18871
+// and https://issues.dlang.org/show_bug.cgi?id=18819
+
+struct Problem
+{
+ ~this() {}
+}
+struct S
+{
+ Problem[1] payload;
+}
+enum theTemplateB = {
+ static foreach (e; S.init.tupleof) {}
+ return true;
+}();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7815.d b/gcc/testsuite/gdc.test/compilable/test7815.d
index ceb5923..405d9fc 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7815.d
+++ b/gcc/testsuite/gdc.test/compilable/test7815.d
@@ -2,8 +2,6 @@
/*
TEST_OUTPUT:
---
-X: tuple("x")
-fail_compilation/fail7815.d(47): Error: no property 'flags' for type 'Move'
---
*/
@@ -47,7 +45,7 @@ struct Move
enum a7815 = Move.init.flags;
/+
-This is an invalid case.
+This originally was an invalid case:
When the Move struct member is analyzed:
1. mixin Helpers!() is instantiated.
2. In Helpers!(), static if and its condition is(Flags!Move)) evaluated.
@@ -62,4 +60,6 @@ When the Move struct member is analyzed:
Flags!Move is instantiated to a new struct Flags.
7. Finally Move struct does not have flags member, then the `enum a7815`
definition will fail in its initializer.
+
+Now, static if will behave like a string mixin: it is invisible during its own expansion.
+/
diff --git a/gcc/testsuite/gdc.test/compilable/test7886.d b/gcc/testsuite/gdc.test/compilable/test7886.d
new file mode 100644
index 0000000..fd3ade4
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test7886.d
@@ -0,0 +1,5 @@
+// https://issues.dlang.org/show_bug.cgi?id=7886
+
+struct A {
+ static assert (__traits(derivedMembers, A).length == 0);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/e7804_1.d b/gcc/testsuite/gdc.test/fail_compilation/e7804_1.d
new file mode 100644
index 0000000..38c25fb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/e7804_1.d
@@ -0,0 +1,11 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/e7804_1.d(10): Error: trait `farfelu` is either invalid or not supported as type
+fail_compilation/e7804_1.d(11): Error: trait `farfelu` is either invalid or not supported in alias
+---
+*/
+module e7804_1;
+
+__traits(farfelu, Aggr, "member") a;
+alias foo = __traits(farfelu, Aggr, "member");
diff --git a/gcc/testsuite/gdc.test/fail_compilation/e7804_2.d b/gcc/testsuite/gdc.test/fail_compilation/e7804_2.d
new file mode 100644
index 0000000..ef9b784
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/e7804_2.d
@@ -0,0 +1,19 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/e7804_2.d(17): Error: `__traits(getMember, Foo, "func")` does not give a valid type
+---
+*/
+
+module e7804_2;
+
+class Foo
+{
+ void func(){}
+}
+
+void test()
+{
+ __traits(getMember, Foo, "func") var;
+ auto a = cast(__traits(getMember, Foo, "func")) 0;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail11169.d b/gcc/testsuite/gdc.test/fail_compilation/fail11169.d
deleted file mode 100644
index e6ab4a6..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail11169.d
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail11169.d(16): Error: error evaluating static if expression
----
-*/
-
-class A
-{
- abstract void foo();
-}
-
-class B : A
-{
- // __traits(isAbstractClass) is not usable in static if condition.
- static if (__traits(isAbstractClass, typeof(this)))
- {
- }
-
- override void foo()
- {
- }
-}
-
-void main()
-{
- B b = new B();
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19182.d b/gcc/testsuite/gdc.test/fail_compilation/fail19182.d
new file mode 100644
index 0000000..388c460
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19182.d
@@ -0,0 +1,18 @@
+// REQUIRED_ARGS: -c
+/*
+TEST_OUTPUT:
+---
+gigi
+fail_compilation/fail19182.d(12): Error: `pragma(msg)` is missing a terminating `;`
+---
+*/
+
+void foo()
+{
+ pragma(msg, "gigi") // Here
+ static foreach (e; [])
+ {
+ pragma(msg, "lili");
+ }
+
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19336.d b/gcc/testsuite/gdc.test/fail_compilation/fail19336.d
new file mode 100644
index 0000000..fc15be5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19336.d
@@ -0,0 +1,17 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19336.d(14): Error: template instance `Template!()` template `Template` is not defined
+fail_compilation/fail19336.d(14): Error: circular reference to `fail19336.Foo.a`
+fail_compilation/fail19336.d(17): Error: circular reference to `fail19336.b`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=19336
+
+struct Foo
+{
+ Template!() a(a.x);
+}
+
+int b(b.x);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19520.d b/gcc/testsuite/gdc.test/fail_compilation/fail19520.d
new file mode 100644
index 0000000..305e055
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19520.d
@@ -0,0 +1,21 @@
+/* https://issues.dlang.org/show_bug.cgi?id=19520
+TEST_OUTPUT:
+---
+fail_compilation/fail19520.d(17): Error: incompatible types for `(Empty) is (Empty)`: cannot use `is` with types
+fail_compilation/fail19520.d(17): while evaluating: `static assert((Empty) is (Empty))`
+fail_compilation/fail19520.d(18): Error: incompatible types for `(WithSym) is (WithSym)`: cannot use `is` with types
+fail_compilation/fail19520.d(18): while evaluating: `static assert((WithSym) is (WithSym))`
+fail_compilation/fail19520.d(19): Error: incompatible types for `(Empty) is (Empty)`: cannot use `is` with types
+fail_compilation/fail19520.d(20): Error: incompatible types for `(WithSym) is (WithSym)`: cannot use `is` with types
+---
+*/
+struct Empty { }
+struct WithSym { int i; }
+
+void test()
+{
+ static assert(Empty is Empty);
+ static assert(WithSym is WithSym);
+ assert(Empty is Empty);
+ assert(WithSym is WithSym);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail2195.d b/gcc/testsuite/gdc.test/fail_compilation/fail2195.d
new file mode 100644
index 0000000..b6d5304
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail2195.d
@@ -0,0 +1,18 @@
+// https://issues.dlang.org/show_bug.cgi?id=2195
+// REQUIRED_ARGS: -de
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail2195.d(16): Deprecation: variable `variable` is shadowing variable `fail2195.main.variable`. Rename the `foreach` variable.
+---
+*/
+
+void main()
+{
+ int[int] arr;
+ int variable;
+ foreach (i, j; arr)
+ {
+ int variable; // shadowing is disallowed but not detected
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7886.d b/gcc/testsuite/gdc.test/fail_compilation/fail7886.d
deleted file mode 100644
index b939aad..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7886.d
+++ /dev/null
@@ -1,5 +0,0 @@
-// 7886
-
-struct A {
- static if (__traits(derivedMembers, A).length) {}
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/staticforeach1.d b/gcc/testsuite/gdc.test/fail_compilation/staticforeach1.d
new file mode 100644
index 0000000..b58f520
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/staticforeach1.d
@@ -0,0 +1,13 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/staticforeach1.d(10): Error: must use labeled `break` within `static foreach`
+---
+*/
+void main(){
+ for(;;){
+ static foreach(i;0..1){
+ break;
+ }
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/staticforeach2.d b/gcc/testsuite/gdc.test/fail_compilation/staticforeach2.d
new file mode 100644
index 0000000..25e283e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/staticforeach2.d
@@ -0,0 +1,13 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/staticforeach2.d(10): Error: must use labeled `continue` within `static foreach`
+---
+*/
+void main(){
+ for(;;){
+ static foreach(i;0..1){
+ continue;
+ }
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/staticforeach3.d b/gcc/testsuite/gdc.test/fail_compilation/staticforeach3.d
new file mode 100644
index 0000000..a93d20b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/staticforeach3.d
@@ -0,0 +1,7 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/staticforeach3.d(7): Error: variable `staticforeach3.__anonymous.i` conflicts with variable `staticforeach3.__anonymous.i` at fail_compilation/staticforeach3.d(7)
+---
+*/
+static foreach(i,i;[0]){}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17307.d b/gcc/testsuite/gdc.test/fail_compilation/test17307.d
new file mode 100644
index 0000000..470cfed
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17307.d
@@ -0,0 +1,12 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test17307.d(9): Error: anonymous struct can only be a part of an aggregate, not module `test17307`
+---
+ * https://issues.dlang.org/show_bug.cgi?id=17307
+ */
+
+struct { enum bitsPerWord = size_t; }
+
+void main()
+{ }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/traits_alone.d b/gcc/testsuite/gdc.test/fail_compilation/traits_alone.d
new file mode 100644
index 0000000..8f6f145
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/traits_alone.d
@@ -0,0 +1,10 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/traits_alone.d(11): Error: found `End of File` when expecting `(`
+fail_compilation/traits_alone.d(11): Error: `__traits(identifier, args...)` expected
+fail_compilation/traits_alone.d(11): Error: no identifier for declarator `_error_`
+---
+*/
+//used to segfault
+__traits
diff --git a/gcc/testsuite/gdc.test/runnable/arrayop.d b/gcc/testsuite/gdc.test/runnable/arrayop.d
index 99bf800..e3749be 100644
--- a/gcc/testsuite/gdc.test/runnable/arrayop.d
+++ b/gcc/testsuite/gdc.test/runnable/arrayop.d
@@ -919,8 +919,7 @@ int main()
}
else
{
- pragma(msg, "arrayop.d:test1 Test skipped because arrayop evaluation"
- " order is ill-defined. See GDC issue #8");
+ //pragma(msg, "Test skipped because arrayop evaluation order is ill-defined.");
}
test3();
test4();
diff --git a/gcc/testsuite/gdc.test/runnable/constfold.d b/gcc/testsuite/gdc.test/runnable/constfold.d
index 57da8b7..0708056 100644
--- a/gcc/testsuite/gdc.test/runnable/constfold.d
+++ b/gcc/testsuite/gdc.test/runnable/constfold.d
@@ -252,15 +252,15 @@ void test2()
// This test only tests undefined, architecture-dependant behavior.
// E.g. the result of converting a float whose value doesn't fit into the integer
// leads to an undefined result.
- version(GNU)
- return;
-
- float f = float.infinity;
- int i = cast(int) f;
- writeln(i);
- writeln(cast(int)float.max);
- assert(i == cast(int)float.max);
- assert(i == 0x80000000);
+ version (DigitalMars)
+ {
+ float f = float.infinity;
+ int i = cast(int) f;
+ writeln(i);
+ writeln(cast(int)float.max);
+ assert(i == cast(int)float.max);
+ assert(i == 0x80000000);
+ }
}
/************************************/
diff --git a/gcc/testsuite/gdc.test/runnable/e7804.d b/gcc/testsuite/gdc.test/runnable/e7804.d
new file mode 100644
index 0000000..d325310
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/e7804.d
@@ -0,0 +1,179 @@
+/* REQUIRED_ARGS: -unittest
+*/
+module e7804;
+
+struct Bar {static struct B{}}
+alias BarB = __traits(getMember, Bar, "B");
+static assert(is(BarB == Bar.B));
+static assert(is(const(__traits(getMember, Bar, "B")) == const(Bar.B)));
+
+alias BarBParent = __traits(parent, BarB);
+static assert(is(BarBParent == Bar));
+
+struct Foo {alias MyInt = int;}
+alias FooInt = __traits(getMember, Foo, "MyInt");
+static immutable FooInt fi = 42;
+static assert(fi == 42);
+void declVsStatementSupport()
+{
+ __traits(getMember, Foo, "MyInt") i1 = 1;
+ const(__traits(getMember, Foo, "MyInt")) i2 = 1;
+ assert(i1 == i2);
+ __traits(getMember, Foo, "MyInt") i3 = __traits(getMember, Foo, "MyInt").max;
+ assert(i3 == int.max);
+}
+
+
+enum __traits(getMember, Foo, "MyInt") a0 = 12;
+static assert(is(typeof(a0) == int));
+static assert(a0 == 12);
+
+
+const __traits(getMember, Foo, "MyInt") a1 = 46;
+
+
+__traits(getMember, Foo, "MyInt") a2 = 78;
+
+
+const(__traits(getMember, Foo, "MyInt")) a3 = 63;
+
+
+struct WithSym {static int foo; static int bar(){return 42;}}
+alias m1 = __traits(getMember, WithSym, "foo");
+alias m2 = WithSym.foo;
+static assert(__traits(isSame, m1, m2));
+alias f1 = __traits(getMember, WithSym, "bar");
+alias f2 = WithSym.bar;
+static assert(__traits(isSame, f1, f2));
+
+
+auto ovld(const(char)[] s){return s;}
+auto ovld(int i){return i;}
+alias ovlds = __traits(getOverloads, e7804, "ovld");
+
+
+struct TmpPrm(T)
+if (is(T == int)){T t;}
+TmpPrm!(__traits(getMember, Foo, "MyInt")) tpt = TmpPrm!(__traits(getMember, Foo, "MyInt"))(42);
+
+
+@Foo @(1) class Class
+{
+ final void virtual(){}
+ int virtual(int p){return p;}
+ void test(this T)()
+ {
+ alias vf = __traits(getVirtualFunctions, Class, "virtual");
+ assert(vf.length == 2);
+ alias vm = __traits(getVirtualMethods, Class, "virtual");
+ assert(vm.length == 1);
+ assert(vm[0](42) == 42);
+ alias attribs = __traits(getAttributes, Class);
+ assert(attribs.length == 2);
+ assert(is(typeof(attribs[0]()) == Foo));
+ assert(attribs[1] == 1);
+
+ alias objectAll = __traits(allMembers, Object);
+ alias classDerived = __traits(derivedMembers, Class);
+ alias classAll = __traits(allMembers, Class);
+ enum Seq(T...) = T;
+ static assert (classAll == Seq!(classDerived, objectAll));
+ }
+}
+
+
+struct UnitTests
+{
+ static int count;
+ unittest { count++; }
+ unittest {++++count;}
+ static void test()
+ {
+ alias tests = __traits(getUnitTests, UnitTests);
+ static assert(tests.length == 2);
+ foreach(t; tests) t();
+ assert(count == 6); // not 3 because executed automatically (DRT) then manually
+ }
+}
+
+
+class One
+{
+ void foo(){}
+ void foo(int){}
+}
+
+class Two : One
+{
+ void test()
+ {
+ alias Seq(T...) = T;
+ alias p1 = Seq!(__traits(getMember, super, "foo"))[0];
+ alias p2 = __traits(getMember, super, "foo");
+ static assert(__traits(isSame, p1, p2));
+ }
+}
+
+
+class SingleSymTuple
+{
+ int foo(){return 42;}
+ void test()
+ {
+ alias f = __traits(getMember, this, "foo");
+ assert(f() == 42);
+ }
+}
+
+
+struct WithAliasThis
+{
+ auto getter(){return 42;}
+ alias getter this;
+ void test()
+ {
+ alias getterCall = __traits(getAliasThis, typeof(this));
+ assert(mixin(getterCall[0]) == 42);
+ }
+}
+
+void main()
+{
+ declVsStatementSupport();
+ assert(a1 == 46);
+ assert(a2 == 78);
+ assert(a3 == 63);
+ assert(f1() == f2());
+ Foo.MyInt fmi = cast(__traits(getMember, Foo, "MyInt")) 0;
+ auto c = __traits(getMember, Foo, "MyInt").max;
+ assert(c == int.max);
+ assert(ovlds[0]("farfelu") == "farfelu");
+ assert(ovlds[1](42) == 42);
+ (new Class).test();
+ UnitTests.test();
+ (new WithAliasThis).test();
+ (new Two).test();
+ (new SingleSymTuple).test();
+}
+
+/* https://issues.dlang.org/show_bug.cgi?id=19708 */
+struct Foo19708 {}
+struct Bar19708 {}
+template Baz19708(T) { struct Baz19708{T t;} }
+int symbol19708;
+
+@Foo19708 @Bar19708 @Baz19708 @symbol19708 int bar19708;
+
+alias TR19708 = __traits(getAttributes, bar19708);
+alias TRT = __traits(getAttributes, bar19708)[2];
+
+TR19708[0] a119708;
+TR19708[1] a219708;
+alias A3 = TRT!int;
+
+alias C19708 = TR19708[0];
+alias D19708 = TR19708[1];
+C19708 c1;
+D19708 d1;
+
+static assert(__traits(isSame, TR19708[3], symbol19708));
diff --git a/gcc/testsuite/gdc.test/runnable/imports/template13478a.d b/gcc/testsuite/gdc.test/runnable/imports/template13478a.d
index 9fcecf3..0c390bc 100644
--- a/gcc/testsuite/gdc.test/runnable/imports/template13478a.d
+++ b/gcc/testsuite/gdc.test/runnable/imports/template13478a.d
@@ -1,9 +1,8 @@
module imports.template13478a;
-import gcc.attribute;
-
-@attribute("noinline") bool foo(T)() {
+bool foo(T)() {
// Make sure this is not inlined so template13478.o actually
// needs to reference it.
+ pragma(inline, false);
return false;
}
diff --git a/gcc/testsuite/gdc.test/runnable/staticforeach.d b/gcc/testsuite/gdc.test/runnable/staticforeach.d
new file mode 100644
index 0000000..bf6dc98
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/staticforeach.d
@@ -0,0 +1,45 @@
+// REQUIRED_ARGS:
+
+/**********************************/
+// https://issues.dlang.org/show_bug.cgi?id=19479
+
+mixin template genInts19479a()
+{
+ static foreach (t; 0..1)
+ int i = 5;
+}
+
+mixin template genInts19479b()
+{
+ static foreach (t; 0..2)
+ mixin("int i" ~ cast(char)('0' + t) ~ " = 5;");
+}
+
+void test19479()
+{
+ {
+ static foreach (t; 0..1)
+ int i = 5;
+ assert(i == 5);
+ }
+ {
+ mixin genInts19479a!();
+ assert(i == 5);
+ }
+ {
+ static foreach (t; 0..2)
+ mixin("int i" ~ cast(char)('0' + t) ~ " = 5;");
+ assert(i0 == 5);
+ assert(i1 == 5);
+ }
+ {
+ mixin genInts19479b!();
+ assert(i0 == 5);
+ assert(i1 == 5);
+ }
+}
+
+void main()
+{
+ test19479();
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test42.d b/gcc/testsuite/gdc.test/runnable/test42.d
index 76f8e21..6e0c42b 100644
--- a/gcc/testsuite/gdc.test/runnable/test42.d
+++ b/gcc/testsuite/gdc.test/runnable/test42.d
@@ -1682,54 +1682,13 @@ void test101()
/***************************************************/
-version(GNU)
-{
-int x103;
-
-void external(int a, ...)
-{
- va_list ap;
- va_start(ap, a);
- auto ext = va_arg!int(ap);
- printf("external: %d\n", ext);
- x103 = ext;
- va_end(ap);
-}
-
-class C103
-{
- void method ()
- {
- void internal (int a, ...)
- {
- va_list ap;
- va_start(ap, a);
- auto internal = va_arg!int(ap);
- printf("internal: %d\n", internal);
- x103 = internal;
- va_end(ap);
- }
-
- internal (0, 43);
- assert(x103 == 43);
- }
-}
-
-void test103()
-{
- external(0, 42);
- assert(x103 == 42);
- (new C103).method ();
-}
-}
-else version(X86)
-{
int x103;
void external(...)
{
- printf("external: %d\n", *cast (int *) _argptr);
- x103 = *cast (int *) _argptr;
+ int arg = va_arg!int(_argptr);
+ printf("external: %d\n", arg);
+ x103 = arg;
}
class C103
@@ -1738,8 +1697,9 @@ class C103
{
void internal (...)
{
- printf("internal: %d\n", *cast (int *)_argptr);
- x103 = *cast (int *) _argptr;
+ int arg = va_arg!int(_argptr);
+ printf("internal: %d\n", arg);
+ x103 = arg;
}
internal (43);
@@ -1753,14 +1713,6 @@ void test103()
assert(x103 == 42);
(new C103).method ();
}
-}
-else version(X86_64)
-{
- pragma(msg, "Not ported to x86-64 compatible varargs, yet.");
- void test103() {}
-}
-else
- static assert(false, "Unknown platform");
/***************************************************/
diff --git a/gcc/testsuite/gdc.test/runnable/traits.d b/gcc/testsuite/gdc.test/runnable/traits.d
index ef23e9f..6c3bf78 100644
--- a/gcc/testsuite/gdc.test/runnable/traits.d
+++ b/gcc/testsuite/gdc.test/runnable/traits.d
@@ -1247,14 +1247,35 @@ struct S10096X
invariant() {}
invariant() {}
unittest {}
+ unittest {}
this(int) {}
this(this) {}
~this() {}
+
+ string getStr() in(str) out(r; r == str) { return str; }
}
static assert(
[__traits(allMembers, S10096X)] ==
- ["str", "__ctor", "__postblit", "__dtor", "__xdtor", "__xpostblit", "opAssign"]);
+ ["str", "__ctor", "__postblit", "__dtor", "getStr", "__xdtor", "__xpostblit", "opAssign"]);
+
+class C10096X
+{
+ string str;
+
+ invariant() {}
+ invariant() {}
+ unittest {}
+ unittest {}
+
+ this(int) {}
+ ~this() {}
+
+ string getStr() in(str) out(r; r == str) { return str;
+}
+static assert(
+ [__traits(allMembers, C10096X)] ==
+ ["str", "__ctor", "__dtor", "getStr", "__xdtor", "toString", "toHash", "opCmp", "opEquals", "Monitor", "factory"]);
// --------
@@ -1526,6 +1547,21 @@ void async(ARGS...)(ARGS)
alias test17495 = async!(int, int);
/********************************************************/
+// https://issues.dlang.org/show_bug.cgi?id=10100
+
+enum E10100
+{
+ value,
+ _value,
+ __value,
+ ___value,
+ ____value,
+}
+static assert(
+ [__traits(allMembers, E10100)] ==
+ ["value", "_value", "__value", "___value", "____value"]);
+
+/********************************************************/
int main()
{