From 3a5c42c44da72d4a2afbc6029e7b68da87946955 Mon Sep 17 00:00:00 2001 From: k-hara Date: Tue, 20 Jan 2015 11:46:31 +0900 Subject: [PATCH] fix Issue 13860 - template required forward reference for typeof(member) In a struct member function S.foo, 'this' is declared as a ref variable by `declareThis()` in `FuncDeclaration::semantic3()`. But in `VarDeclaration::semantic`, `type->hasPointer()` will needlessly try to resolve struct fwdref. All parameter variables won't be declared with void initializer, so the reordering fixes the issue. --- src/declaration.c | 10 ++++------ test/compilable/fwdref13860.d | 27 +++++++++++++++++++++++++++ test/fail_compilation/ice12350.d | 2 +- test/fail_compilation/ice12362.d | 2 +- test/fail_compilation/ice13225.d | 2 +- 5 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 test/compilable/fwdref13860.d diff --git a/src/declaration.c b/src/declaration.c index 1b39989bf0..bc89435a83 100644 --- a/src/declaration.c +++ b/src/declaration.c @@ -864,13 +864,11 @@ void VarDeclaration::semantic(Scope *sc) if (sc->func->setUnsafe()) error("__gshared not allowed in safe functions; use shared"); } - if (type->hasPointers()) // get type size + if (init && init->isVoidInitializer() && + type->hasPointers()) // get type size { - if (init && init->isVoidInitializer()) - { - if (sc->func->setUnsafe()) - error("void initializers for pointers not allowed in safe functions"); - } + if (sc->func->setUnsafe()) + error("void initializers for pointers not allowed in safe functions"); } } diff --git a/test/compilable/fwdref13860.d b/test/compilable/fwdref13860.d new file mode 100644 index 0000000000..4a3613fa10 --- /dev/null +++ b/test/compilable/fwdref13860.d @@ -0,0 +1,27 @@ +// PERMUTE_ARGS: +/* +TEST_OUTPUT: +--- +pure nothrow @nogc @safe void() +pure nothrow @nogc @safe void() +--- +*/ + +struct Foo(Bar...) +{ + Bar bars; + auto baz(size_t d)() {} + pragma(msg, typeof(baz!0)); +} + +auto bar(S, R)(S s, R r) +{ + pragma(msg, typeof(Foo!().baz!0)); +} + +void main() +{ + int[] x; + int[] y; + x.bar(y); +} diff --git a/test/fail_compilation/ice12350.d b/test/fail_compilation/ice12350.d index e2ca919459..3ac3751d2c 100644 --- a/test/fail_compilation/ice12350.d +++ b/test/fail_compilation/ice12350.d @@ -1,12 +1,12 @@ /* TEST_OUTPUT: --- -fail_compilation/ice12350.d(10): Error: enum ice12350.MyUDC is forward referenced looking for base type fail_compilation/ice12350.d(15): Error: type MyUDC has no value fail_compilation/ice12350.d(30): Error: template instance ice12350.testAttrs!(MyStruct) error instantiating --- */ + enum MyUDC; struct MyStruct diff --git a/test/fail_compilation/ice12362.d b/test/fail_compilation/ice12362.d index 84afa2a714..2c662c050d 100644 --- a/test/fail_compilation/ice12362.d +++ b/test/fail_compilation/ice12362.d @@ -1,12 +1,12 @@ /* TEST_OUTPUT: --- -fail_compilation/ice12362.d(9): Error: enum ice12362.foo is forward referenced looking for base type fail_compilation/ice12362.d(12): Error: cannot interpret foo at compile time --- */ enum foo; + void main() { enum bar = foo; diff --git a/test/fail_compilation/ice13225.d b/test/fail_compilation/ice13225.d index 8582264aca..f29e574b51 100644 --- a/test/fail_compilation/ice13225.d +++ b/test/fail_compilation/ice13225.d @@ -1,10 +1,10 @@ /* TEST_OUTPUT: --- +fail_compilation/ice13225.d(12): Error: mixin ice13225.S.M!(function (S _param_0) => 0) does not match template declaration M(T) fail_compilation/ice13225.d(13): Error: undefined identifier undefined --- */ - mixin template M(T) {} struct S