diff options
-rw-r--r-- | gcc/d/decl.cc | 14 | ||||
-rw-r--r-- | gcc/testsuite/gdc.dg/torture/imports/pr108055conv.d | 26 | ||||
-rw-r--r-- | gcc/testsuite/gdc.dg/torture/imports/pr108055spec.d | 18 | ||||
-rw-r--r-- | gcc/testsuite/gdc.dg/torture/imports/pr108055write.d | 19 | ||||
-rw-r--r-- | gcc/testsuite/gdc.dg/torture/pr108055.d | 12 |
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; +} |