summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gdc.test/compilable
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-01-04 19:05:38 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2021-01-05 22:09:10 +0100
commitc5e94699efa816444c0ae49ad55d0e01a48203df (patch)
treef527fd1748c2f034d74ca1b268d4f56fc36cf050 /gcc/testsuite/gdc.test/compilable
parentae1ada95fee1ee4fac0dec0486076d9787988a03 (diff)
d: Merge upstream dmd a5c86f5b9
Adds the following new `__traits' to the D language. - isDeprecated: used to detect if a function is deprecated. - isDisabled: used to detect if a function is marked with @disable. - isFuture: used to detect if a function is marked with @__future. - isModule: used to detect if a given symbol represents a module, this enhancement also adds support using `is(sym == module)'. - isPackage: used to detect if a given symbol represents a package, this enhancement also adds support using `is(sym == package)'. - child: takes two arguments. The first must be a symbol or expression and the second must be a symbol, such as an alias to a member of the first 'parent' argument. The result is the second 'member' argument interpreted with its 'this' context set to 'parent'. This is the inverse of `__traits(parent, member)'. - isReturnOnStack: determines if a function's return value is placed on the stack, or is returned via registers. - isZeroInit: used to detect if a type's default initializer has no non-zero bits. - getTargetInfo: used to query features of the target being compiled for, the back-end can expand this to register any key to handle the given argument, however a reliable subset exists which includes "cppRuntimeLibrary", "cppStd", "floatAbi", and "objectFormat". - getLocation: returns a tuple whose entries correspond to the filename, line number, and column number of where the argument was declared. - hasPostblit: used to detect if a type is a struct with a postblit. - isCopyable: used to detect if a type allows copying its value. - getVisibility: an alias for the getProtection trait. Reviewed-on: https://github.com/dlang/dmd/pull/12093 gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd a5c86f5b9. * d-builtins.cc (d_eval_constant_expression): Handle ADDR_EXPR trees created by build_string_literal. * d-frontend.cc (retStyle): Remove function. * d-target.cc (d_language_target_info): New variable. (d_target_info_table): Likewise. (Target::_init): Initialize d_target_info_table. (Target::isReturnOnStack): New function. (d_add_target_info_handlers): Likewise. (d_handle_target_cpp_std): Likewise. (d_handle_target_cpp_runtime_library): Likewise. (Target::getTargetInfo): Likewise. * d-target.h (struct d_target_info_spec): New type. (d_add_target_info_handlers): Declare.
Diffstat (limited to 'gcc/testsuite/gdc.test/compilable')
-rw-r--r--gcc/testsuite/gdc.test/compilable/Test16206.d28
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/pkgmodule/package.d3
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/pkgmodule/plainmodule.d2
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/plainpackage/plainmodule.d4
-rw-r--r--gcc/testsuite/gdc.test/compilable/isZeroInit.d78
-rw-r--r--gcc/testsuite/gdc.test/compilable/isreturnonstack.d7
-rw-r--r--gcc/testsuite/gdc.test/compilable/line.d4
-rw-r--r--gcc/testsuite/gdc.test/compilable/test16002.d24
-rw-r--r--gcc/testsuite/gdc.test/compilable/test17791.d28
-rw-r--r--gcc/testsuite/gdc.test/compilable/traits.d130
10 files changed, 306 insertions, 2 deletions
diff --git a/gcc/testsuite/gdc.test/compilable/Test16206.d b/gcc/testsuite/gdc.test/compilable/Test16206.d
new file mode 100644
index 00000000000..0b9ccf31876
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/Test16206.d
@@ -0,0 +1,28 @@
+struct S {
+ static int foo()() { return 0; }
+ static int foo()(int n) { return 1; }
+ static int foo(string s) { return 2; }
+ enum foo(int[] arr) = arr.length;
+}
+
+alias AliasSeq(T...) = T;
+
+alias allFoos = AliasSeq!(__traits(getOverloads, S, "foo", true));
+
+static assert(allFoos.length == 4);
+
+static assert(allFoos[0]("") == 2);
+static assert(allFoos[1]() == 0);
+static assert(allFoos[2](1) == 1);
+alias foo3 = allFoos[3];
+static assert(foo3!([]) == 0);
+
+static assert(S.foo() == 0);
+static assert(S.foo(1) == 1);
+static assert(S.foo("") == 2);
+static assert(S.foo!([]) == 0);
+
+
+alias fooFuns = AliasSeq!(__traits(getOverloads, S, "foo"));
+static assert(fooFuns.length == 1);
+static assert(fooFuns[0]("") == 2); \ No newline at end of file
diff --git a/gcc/testsuite/gdc.test/compilable/imports/pkgmodule/package.d b/gcc/testsuite/gdc.test/compilable/imports/pkgmodule/package.d
new file mode 100644
index 00000000000..b6e98ff011b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/pkgmodule/package.d
@@ -0,0 +1,3 @@
+/// Used to test is(x == package) and is(x == module)
+
+module imports.pkgmodule;
diff --git a/gcc/testsuite/gdc.test/compilable/imports/pkgmodule/plainmodule.d b/gcc/testsuite/gdc.test/compilable/imports/pkgmodule/plainmodule.d
new file mode 100644
index 00000000000..948a87e5fee
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/pkgmodule/plainmodule.d
@@ -0,0 +1,2 @@
+/// Used to test is(x == module)
+module imports.pkgmodule.plainmodule;
diff --git a/gcc/testsuite/gdc.test/compilable/imports/plainpackage/plainmodule.d b/gcc/testsuite/gdc.test/compilable/imports/plainpackage/plainmodule.d
new file mode 100644
index 00000000000..9e9933b379b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/plainpackage/plainmodule.d
@@ -0,0 +1,4 @@
+/// Used to test is(x == module)
+
+module imports.plainpackage.plainmodule;
+
diff --git a/gcc/testsuite/gdc.test/compilable/isZeroInit.d b/gcc/testsuite/gdc.test/compilable/isZeroInit.d
new file mode 100644
index 00000000000..b5423cfb636
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/isZeroInit.d
@@ -0,0 +1,78 @@
+alias AliasSeq(T...) = T;
+
+struct Holder(T, ubyte val)
+{
+ T x = val;
+}
+
+struct SArrayHolder(T, ubyte val)
+{
+ T[2] x = val;
+}
+
+static foreach (T; AliasSeq!(bool, byte, short, int, long,
+ ubyte, ushort, uint, ulong,
+ char, wchar, dchar,
+ float, double, real))
+{
+ static assert(__traits(isZeroInit, T) == (T.init is T(0)));
+ static assert(__traits(isZeroInit, T[2]) == (T.init is T(0)));
+
+ static assert(!__traits(isZeroInit, Holder!(T, 1)));
+ static assert(__traits(isZeroInit, Holder!(T, 0)));
+
+ static assert(__traits(isZeroInit, SArrayHolder!(T, 0)));
+ static assert(!__traits(isZeroInit, SArrayHolder!(T, 1)));
+
+}
+
+static assert(__traits(isZeroInit, void)); // For initializing arrays of element type `void`.
+static assert(__traits(isZeroInit, void*));
+static assert(__traits(isZeroInit, void[]));
+static assert(__traits(isZeroInit, float[]));
+static assert(__traits(isZeroInit, Object));
+class C1 : Object
+{
+ int x = 1;
+}
+static assert(__traits(isZeroInit, C1)); // An Object's fields are irrelevant.
+
+struct S1
+{
+ int[] a;
+ int b;
+}
+static assert(__traits(isZeroInit, S1));
+
+struct S2
+{
+ alias H = Holder!(int, 1);
+ H h;
+ int a;
+}
+static assert(!__traits(isZeroInit, S2));
+
+struct S3
+{
+ S1 h;
+ float f = 0;
+}
+static assert(__traits(isZeroInit, S3));
+
+struct S4
+{
+ S2 h = S2(S2.H(0), 0);
+ int a;
+}
+static assert(__traits(isZeroInit, S4));
+
+struct S5
+{
+ Object o = null;
+}
+static assert(__traits(isZeroInit, S5));
+
+version(D_SIMD):
+import core.simd : int4;
+static assert(__traits(isZeroInit, Holder!(int4, 0)));
+static assert(!__traits(isZeroInit, Holder!(int4, 1)));
diff --git a/gcc/testsuite/gdc.test/compilable/isreturnonstack.d b/gcc/testsuite/gdc.test/compilable/isreturnonstack.d
new file mode 100644
index 00000000000..8bdb97de13f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/isreturnonstack.d
@@ -0,0 +1,7 @@
+struct S { int[10] a; }
+int test1();
+S test2();
+
+static assert(__traits(isReturnOnStack, test1) == false);
+static assert(__traits(isReturnOnStack, test2) == true);
+
diff --git a/gcc/testsuite/gdc.test/compilable/line.d b/gcc/testsuite/gdc.test/compilable/line.d
index 5122ed3cbf8..14e178988c8 100644
--- a/gcc/testsuite/gdc.test/compilable/line.d
+++ b/gcc/testsuite/gdc.test/compilable/line.d
@@ -19,12 +19,12 @@ static assert(__FILE_FULL_PATH__[$-__FILE__.length..$] == __FILE__);
static assert(__LINE__ == 101);
static assert(__FILE__ == "newfile.d");
-static assert(__FILE_FULL_PATH__ == "newfile.d");
+static assert(__FILE_FULL_PATH__[$ - 9 .. $] == "newfile.d");
# line 200
static assert(__LINE__ == 201);
static assert(__FILE__ == "newfile.d");
-static assert(__FILE_FULL_PATH__ == "newfile.d");
+static assert(__FILE_FULL_PATH__[$ - 9 .. $] == "newfile.d");
diff --git a/gcc/testsuite/gdc.test/compilable/test16002.d b/gcc/testsuite/gdc.test/compilable/test16002.d
new file mode 100644
index 00000000000..f3303c0e310
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test16002.d
@@ -0,0 +1,24 @@
+module test.compilable.test16002;
+
+import imports.plainpackage.plainmodule;
+import imports.pkgmodule.plainmodule;
+
+struct MyStruct;
+
+alias a = imports.plainpackage;
+alias b = imports.pkgmodule.plainmodule;
+
+static assert(is(imports.plainpackage == package));
+static assert(is(a == package));
+static assert(!is(imports.plainpackage.plainmodule == package));
+static assert(!is(b == package));
+static assert(is(imports.pkgmodule == package));
+static assert(!is(MyStruct == package));
+
+static assert(!is(imports.plainpackage == module));
+static assert(!is(a == module));
+static assert(is(imports.plainpackage.plainmodule == module));
+static assert(is(b == module));
+// This is supposed to work even though we haven't directly imported imports.pkgmodule.
+static assert(is(imports.pkgmodule == module));
+static assert(!is(MyStruct == module));
diff --git a/gcc/testsuite/gdc.test/compilable/test17791.d b/gcc/testsuite/gdc.test/compilable/test17791.d
new file mode 100644
index 00000000000..3244c129aa9
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test17791.d
@@ -0,0 +1,28 @@
+/*
+REQUIRED_ARGS: -de
+TEST_OUTPUT:
+---
+---
+*/
+deprecated("A deprecated class") {
+class DepClass
+{
+}
+}
+
+class NewClass
+{
+}
+
+void main()
+{
+ // test that a symbol (which is not likely to be deprecated)
+ // is not depercated
+ static assert(!__traits(isDeprecated, int));
+ // check that a class marked deprecated "isDeprecated"
+ static assert(__traits(isDeprecated, DepClass));
+ // check that a class not marked deprecated is not deprecated
+ static assert(!__traits(isDeprecated, NewClass));
+ // Check for expressions (18617)
+ static assert(__traits(isDeprecated, { scope foo = new DepClass; }));
+}
diff --git a/gcc/testsuite/gdc.test/compilable/traits.d b/gcc/testsuite/gdc.test/compilable/traits.d
index 736eae4a89d..4d8a5e140c4 100644
--- a/gcc/testsuite/gdc.test/compilable/traits.d
+++ b/gcc/testsuite/gdc.test/compilable/traits.d
@@ -1,10 +1,140 @@
// REQUIRED_ARGS:
+// EXTRA_FILES: imports/plainpackage/plainmodule.d imports/pkgmodule/package.d imports/pkgmodule/plainmodule.d
// This file is intended to contain all compilable traits-related tests in an
// effort to keep the number of files in the `compilable` folder to a minimum.
+// https://issues.dlang.org/show_bug.cgi?id=19152
+module traits;
+
+class C19152
+{
+ int OnExecute()
+ {
+ auto name = __traits(getOverloads, this, "OnExecute").stringof;
+ return 0;
+ }
+}
+
+static assert(is(typeof(__traits(getTargetInfo, "cppRuntimeLibrary")) == string));
+version (CppRuntime_Microsoft)
+{
+ static assert(__traits(getTargetInfo, "cppRuntimeLibrary") == "libcmt");
+}
+
+import imports.plainpackage.plainmodule;
+import imports.pkgmodule.plainmodule;
+
+#line 40
+struct MyStruct;
+
+alias a = imports.plainpackage;
+alias b = imports.pkgmodule.plainmodule;
+
+static assert(__traits(isPackage, imports.plainpackage));
+static assert(__traits(isPackage, a));
+static assert(!__traits(isPackage, imports.plainpackage.plainmodule));
+static assert(!__traits(isPackage, b));
+static assert(__traits(isPackage, imports.pkgmodule));
+static assert(!__traits(isPackage, MyStruct));
+
+static assert(!__traits(isModule, imports.plainpackage));
+static assert(!__traits(isModule, a));
+static assert(__traits(isModule, imports.plainpackage.plainmodule));
+static assert(__traits(isModule, b));
+// This is supposed to work even though we haven't directly imported imports.pkgmodule.
+static assert(__traits(isModule, imports.pkgmodule));
+static assert(!__traits(isModule, MyStruct));
+
/******************************************/
// https://issues.dlang.org/show_bug.cgi?id=19942
static assert(!__traits(compiles, { a.init; }));
static assert(!__traits(compiles, { import m : a; a.init; }));
+
+version(Windows)
+ static assert(__traits(getLocation, MyStruct)[0] == `compilable\traits.d`);
+else
+ static assert(__traits(getLocation, MyStruct)[0] == "compilable/traits.d");
+static assert(__traits(getLocation, MyStruct)[1] == 40);
+static assert(__traits(getLocation, MyStruct)[2] == 1);
+
+int foo();
+int foo(int);
+
+static assert(__traits(getLocation, __traits(getOverloads, traits, "foo")[1])[1] == 74);
+
+mixin("int bar;");
+static assert(__traits(getLocation, bar)[1] == 78);
+
+struct Outer
+{
+ struct Nested{}
+
+ void method() {}
+}
+static assert(__traits(getLocation, Outer.Nested)[1] == 83);
+static assert(__traits(getLocation, Outer.method)[1] == 85);
+
+/******************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19902
+// Define hasElaborateCopyConstructor trait
+// but done as two independent traits per conversation
+// in https://github.com/dlang/dmd/pull/10265
+
+struct S
+{
+ this (ref S rhs) {}
+}
+
+struct OuterS
+{
+ struct S
+ {
+ this (ref S rhs) {}
+ }
+
+ S s;
+}
+
+void foo(T)()
+{
+ struct S(U)
+ {
+ this (ref S rhs) {}
+ }
+}
+
+struct U(T)
+{
+ this (ref U rhs) {}
+}
+
+struct SPostblit
+{
+ this(this) {}
+}
+
+struct DisabledPostblit
+{
+ @disable this(this);
+}
+
+struct NoCpCtor { }
+class C19902 { }
+
+static assert(__traits(compiles, foo!int));
+static assert(__traits(compiles, foo!S));
+static assert(!__traits(hasPostblit, U!S));
+static assert(__traits(hasPostblit, SPostblit));
+
+static assert(!__traits(hasPostblit, NoCpCtor));
+static assert(!__traits(hasPostblit, C19902));
+static assert(!__traits(hasPostblit, int));
+
+// Check that invalid use cases don't compile
+static assert(!__traits(compiles, __traits(hasPostblit)));
+static assert(!__traits(compiles, __traits(hasPostblit, S())));
+
+static assert(__traits(isCopyable, int));
+static assert(!__traits(isCopyable, DisabledPostblit));