aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/d/decl.cc14
-rw-r--r--gcc/testsuite/gdc.dg/torture/imports/pr108055conv.d26
-rw-r--r--gcc/testsuite/gdc.dg/torture/imports/pr108055spec.d18
-rw-r--r--gcc/testsuite/gdc.dg/torture/imports/pr108055write.d19
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr108055.d12
5 files changed, 84 insertions, 5 deletions
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index bed1632..3508108 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -1028,7 +1028,8 @@ build_decl_tree (Dsymbol *d)
input_location = saved_location;
}
-/* Returns true if function FD is defined or instantiated in a root module. */
+/* Returns true if function FD, or any lexically enclosing scope function of FD
+ is defined or instantiated in a root module. */
static bool
function_defined_in_root_p (FuncDeclaration *fd)
@@ -1037,9 +1038,11 @@ function_defined_in_root_p (FuncDeclaration *fd)
if (md && md->isRoot ())
return true;
- TemplateInstance *ti = fd->isInstantiated ();
- if (ti && ti->minst && ti->minst->isRoot ())
- return true;
+ for (TemplateInstance *ti = fd->isInstantiated (); ti != NULL; ti = ti->tinst)
+ {
+ if (ti->minst && ti->minst->isRoot ())
+ return true;
+ }
return false;
}
@@ -1067,7 +1070,8 @@ function_needs_inline_definition_p (FuncDeclaration *fd)
/* Check whether function will be regularly defined later in the current
translation unit. */
- if (function_defined_in_root_p (fd))
+ Module *md = fd->getModule ();
+ if (md && md->isRoot ())
return false;
/* Non-inlineable functions are always external. */
diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr108055conv.d b/gcc/testsuite/gdc.dg/torture/imports/pr108055conv.d
new file mode 100644
index 0000000..93ebba7
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/imports/pr108055conv.d
@@ -0,0 +1,26 @@
+module imports.pr108055conv;
+
+T toStr(T, S)(S src)
+{
+ static if (is(typeof(T.init[0]) E))
+ {
+ struct Appender
+ {
+ inout(E)[] data;
+ }
+
+ import imports.pr108055spec;
+ import imports.pr108055write;
+
+ auto w = Appender();
+ FormatSpec!E f;
+ formatValue(w, src, f);
+ return w.data;
+ }
+}
+
+T to(T, A)(A args)
+{
+ return toStr!T(args);
+}
+
diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr108055spec.d b/gcc/testsuite/gdc.dg/torture/imports/pr108055spec.d
new file mode 100644
index 0000000..801c581
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/imports/pr108055spec.d
@@ -0,0 +1,18 @@
+module imports.pr108055spec;
+
+template Unqual(T : const U, U)
+{
+ alias Unqual = U;
+}
+
+template FormatSpec(Char)
+if (!is(Unqual!Char == Char))
+{
+ alias FormatSpec = FormatSpec!(Unqual!Char);
+}
+
+struct FormatSpec(Char)
+if (is(Unqual!Char == Char))
+{
+ const(Char)[] nested;
+}
diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr108055write.d b/gcc/testsuite/gdc.dg/torture/imports/pr108055write.d
new file mode 100644
index 0000000..fe41d7b
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/imports/pr108055write.d
@@ -0,0 +1,19 @@
+module imports.pr108055write;
+import imports.pr108055spec;
+
+void formatValueImpl(Writer, T, Char)(ref Writer , const(T) ,
+ scope const ref FormatSpec!Char )
+{
+ T val;
+ char spec;
+
+ (ref val) @trusted {
+ return (cast(const char*) &val)[0 .. val.sizeof];
+ }(val);
+
+}
+
+void formatValue(Writer, T, Char)(Writer w, T val, Char f)
+{
+ formatValueImpl(w, val, f);
+}
diff --git a/gcc/testsuite/gdc.dg/torture/pr108055.d b/gcc/testsuite/gdc.dg/torture/pr108055.d
new file mode 100644
index 0000000..c4ffad2
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr108055.d
@@ -0,0 +1,12 @@
+// { dg-do link }
+// { dg-additional-files "imports/pr108055conv.d imports/pr108055spec.d imports/pr108055write.d" }
+// { dg-additional-options "-I[srcdir] -fno-druntime" }
+import imports.pr108055conv;
+
+extern(C) int main()
+{
+ float zis;
+ static if (is(typeof(to!string(&zis))))
+ to!string(&zis);
+ return 0;
+}