diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-10-23 09:41:11 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-10-27 11:50:35 +0100 |
commit | e419ede8915eeb879de3d9c026cd4213aaceb86a (patch) | |
tree | 03b7bf22cb46b94e4ad563d88dfbb0e73aaac92e /gcc/testsuite/gdc.test | |
parent | 14e19b82c1e67ead60c3095ac23347317298904b (diff) | |
download | gcc-e419ede8915eeb879de3d9c026cd4213aaceb86a.zip gcc-e419ede8915eeb879de3d9c026cd4213aaceb86a.tar.gz gcc-e419ede8915eeb879de3d9c026cd4213aaceb86a.tar.bz2 |
d: Merge upstream dmd 0fcdaab32
Fixes a bug where there was undefined template references when compiling
upstream dmd mainline.
In `TemplateInstance::semantic`, there exists special handling of
matching template instances for the same template declaration to ensure
that only at most one instance gets codegen'd.
If the primary instance `inst` originated from a non-root module, the
`minst` field will be updated so it is now coming from a root module,
however all Dsymbol `inst->members` of the instance still have their
`_scope->minst` pointing at the original non-root module. We must now
propagate `minst` to all members so that forward referenced dependencies
that get instantiated will also be appended to the root module,
otherwise there will be undefined references at link-time.
This doesn't affect compilations where all modules are compiled
together, as every module is a root module in that situation. What this
primarily affects are cases where there is a mix of root and non-root
modules, and a template was first instantiated in a non-root context,
then later instantiated again in a root context.
Reviewed-on: https://github.com/dlang/dmd/pull/11867
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 0fcdaab32
Diffstat (limited to 'gcc/testsuite/gdc.test')
7 files changed, 152 insertions, 0 deletions
diff --git a/gcc/testsuite/gdc.test/compilable/imports/test21299/func.d b/gcc/testsuite/gdc.test/compilable/imports/test21299/func.d new file mode 100644 index 0000000..fe3321f --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test21299/func.d @@ -0,0 +1,8 @@ +module imports.test21299.func; +import imports.test21299.mtype; +import imports.test21299.rootstringtable; +class FuncDeclaration { + StringTable!Type stringtable; + StringTable2!Type stringtable2; + StringTable3!Type stringtable3; +} diff --git a/gcc/testsuite/gdc.test/compilable/imports/test21299/mtype.d b/gcc/testsuite/gdc.test/compilable/imports/test21299/mtype.d new file mode 100644 index 0000000..01bac82 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test21299/mtype.d @@ -0,0 +1,8 @@ +module imports.test21299.mtype; +import imports.test21299.func; +import imports.test21299.rootstringtable; +class Type { + StringTable!Type stringtable; + StringTable2!Type stringtable2; + StringTable3!Type stringtable3; +} diff --git a/gcc/testsuite/gdc.test/compilable/imports/test21299/rootstringtable.d b/gcc/testsuite/gdc.test/compilable/imports/test21299/rootstringtable.d new file mode 100644 index 0000000..12a2d92 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test21299/rootstringtable.d @@ -0,0 +1,96 @@ +module imports.test21299.rootstringtable; +struct StringValue(T) +{ + char* lstring() + { + return cast(char*)&this; + } +} + +struct StringTable(T) +{ + StringValue!T* insert() + { + allocValue; + return getValue; + } + + uint allocValue() + { + StringValue!(T) sv; + sv.lstring[0] = 0; + return 0; + } + + StringValue!T* getValue() + { + return cast(StringValue!T*)&this; + } +} + +// Other tests are the same as the original issue, but use other kinds of +// nesting Dsymbols that need to be handled by templateInstanceSemantic(). +struct StringValue2(T) +{ + char* lstring() + { + return cast(char*)&this; + } +} + +struct StringTable2(T) +{ + @nogc // AttribDeclaration (also covers pragma, extern(), static foreach, ...) + { + StringValue2!T* insert() + { + allocValue; + return getValue; + } + + uint allocValue() + { + StringValue2!(T) sv; + sv.lstring[0] = 0; + return 0; + } + + StringValue2!T* getValue() + { + return cast(StringValue2!T*)&this; + } + } +} + +// +struct StringValue3(T) +{ + char* lstring() + { + return cast(char*)&this; + } +} + +struct StringTable3(T) +{ + static if (true) // ConditionalDeclaration (static if) + { + StringValue3!T* insert() + { + allocValue; + return getValue; + } + + uint allocValue() + { + StringValue3!(T) sv; + sv.lstring[0] = 0; + return 0; + } + + StringValue3!T* getValue() + { + return cast(StringValue3!T*)&this; + } + } +} diff --git a/gcc/testsuite/gdc.test/compilable/test21299a.d b/gcc/testsuite/gdc.test/compilable/test21299a.d new file mode 100644 index 0000000..049ee6a --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test21299a.d @@ -0,0 +1,4 @@ +// EXTRA_SOURCES: imports/test21299/mtype.d imports/test21299/rootstringtable.d +// REQUIRED_ARGS: -main +// LINK +module test21299a; diff --git a/gcc/testsuite/gdc.test/compilable/test21299b.d b/gcc/testsuite/gdc.test/compilable/test21299b.d new file mode 100644 index 0000000..b9d992a --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test21299b.d @@ -0,0 +1,4 @@ +// EXTRA_SOURCES: imports/test21299/func.d imports/test21299/rootstringtable.d +// REQUIRED_ARGS: -main +// LINK: +module test21299b; diff --git a/gcc/testsuite/gdc.test/compilable/test21299c.d b/gcc/testsuite/gdc.test/compilable/test21299c.d new file mode 100644 index 0000000..88ed21f --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test21299c.d @@ -0,0 +1,5 @@ +// EXTRA_SOURCES: imports/test21299/mtype.d imports/test21299/func.d imports/test21299/rootstringtable.d +// COMPILE_SEPARATELY: +// LINK: +module test21299c; +void main() {} diff --git a/gcc/testsuite/gdc.test/compilable/test21299d.d b/gcc/testsuite/gdc.test/compilable/test21299d.d new file mode 100644 index 0000000..67ec60a --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test21299d.d @@ -0,0 +1,27 @@ +// REQUIRED_ARGS: -main +// LINK: +module test21299d; + +struct DefaultPredicates +{ + struct IsEqual(T) + { + static opCall(in T, in T) + { + return 0; + } + } +} + +void moveToEnd(T, Pred = DefaultPredicates.IsEqual!T)(T[] array, T element, Pred pred = Pred.init) +{ + pred(array[0], element); +} + +class Task +{ + void removeTerminationHook(void delegate() hook) + { + moveToEnd([], hook); + } +} |