From eca6fa41ec1b37da850a30de16086f3f8b4b4e70 Mon Sep 17 00:00:00 2001 From: k-hara Date: Mon, 26 May 2014 11:33:56 +0900 Subject: [PATCH] fix Issue 12436 - Opaque struct parameter type should not be allowed --- src/mtype.c | 26 ++++++++++--- test/compilable/cppmangle.d | 2 +- test/fail_compilation/diag9247.d | 4 +- test/fail_compilation/fail112.d | 13 ------- test/fail_compilation/fail12436.d | 64 +++++++++++++++++++++++++++++++ test/fail_compilation/fail130.d | 15 -------- 6 files changed, 88 insertions(+), 36 deletions(-) delete mode 100644 test/fail_compilation/fail112.d create mode 100644 test/fail_compilation/fail12436.d delete mode 100644 test/fail_compilation/fail130.d diff --git a/src/mtype.c b/src/mtype.c index 1cba0e696eba..09b52f62b6a1 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -5466,12 +5466,12 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) error(loc, "functions cannot return a tuple"); errors = true; } - else if (tb->ty == Tstruct) + else if (!tf->isref && (tb->ty == Tstruct || tb->ty == Tsarray)) { - StructDeclaration *sd = ((TypeStruct *)tb)->sym; - if (sd->isforwardRef()) + Type *tb2 = tb->baseElemOf(); + if (tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members) { - error(loc, "cannot return opaque struct %s by value", tb->toChars()); + error(loc, "functions cannot return opaque type %s by value", tb->toChars()); errors = true; } } @@ -5523,11 +5523,27 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) Type *t = fparam->type->toBasetype(); - if (!(fparam->storageClass & STClazy) && t->ty == Tvoid) + if (t->ty == Tfunction) + { + error(loc, "cannot have parameter of function type %s", fparam->type->toChars()); + errors = true; + } + else if (!(fparam->storageClass & (STCref | STCout)) && + (t->ty == Tstruct || t->ty == Tsarray)) + { + Type *tb2 = t->baseElemOf(); + if (tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members) + { + error(loc, "cannot have parameter of opaque type %s by value", fparam->type->toChars()); + errors = true; + } + } + else if (!(fparam->storageClass & STClazy) && t->ty == Tvoid) { error(loc, "cannot have parameter of type %s", fparam->type->toChars()); errors = true; } + if (fparam->storageClass & (STCref | STClazy)) { } diff --git a/test/compilable/cppmangle.d b/test/compilable/cppmangle.d index cfb0fafd4afb..663758904df6 100644 --- a/test/compilable/cppmangle.d +++ b/test/compilable/cppmangle.d @@ -271,7 +271,7 @@ static assert(test10058l.mangleof == "_Z10test10058lPFPvS_EPFS_PKvEPFS3_S_E"); // 11696 class Expression; -struct Loc; +struct Loc {} extern(C++) class CallExp diff --git a/test/fail_compilation/diag9247.d b/test/fail_compilation/diag9247.d index 65373d696a01..e22634559cb2 100644 --- a/test/fail_compilation/diag9247.d +++ b/test/fail_compilation/diag9247.d @@ -1,8 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/diag9247.d(11): Error: cannot return opaque struct S by value -fail_compilation/diag9247.d(12): Error: cannot return opaque struct S by value +fail_compilation/diag9247.d(11): Error: functions cannot return opaque type S by value +fail_compilation/diag9247.d(12): Error: functions cannot return opaque type S by value --- */ diff --git a/test/fail_compilation/fail112.d b/test/fail_compilation/fail112.d deleted file mode 100644 index 455250c7303c..000000000000 --- a/test/fail_compilation/fail112.d +++ /dev/null @@ -1,13 +0,0 @@ -/* -TEST_OUTPUT: ---- -fail_compilation/fail112.d(11): Error: functions cannot return a function ---- -*/ - -void func(int a) { } -//typedef int ft(int); - -typeof(func) test() -{ -} diff --git a/test/fail_compilation/fail12436.d b/test/fail_compilation/fail12436.d new file mode 100644 index 000000000000..53e55d0c50ee --- /dev/null +++ b/test/fail_compilation/fail12436.d @@ -0,0 +1,64 @@ +alias void FuncType(); + +struct Opaque; + +template Tuple(T...) { alias T Tuple; } +alias Tuple!(int, int) TupleType; + +/******************************************/ +// return type + +/* +TEST_OUTPUT: +--- +fail_compilation/fail12436.d(18): Error: functions cannot return a function +fail_compilation/fail12436.d(19): Error: functions cannot return a tuple +--- +*/ +FuncType test1(); +TupleType test2(); + +/* +TEST_OUTPUT: +--- +fail_compilation/fail12436.d(28): Error: functions cannot return opaque type Opaque by value +fail_compilation/fail12436.d(29): Error: functions cannot return opaque type Opaque[1] by value +--- +*/ +Opaque ret12436a(); // error +Opaque[1] ret12436b(); // error +Opaque* ret12436c(); // no error +Opaque[] ret12436d(); // no error +Opaque[]* ret12436e(); // no error + +ref Opaque ret12436f(); // no error +ref Opaque[1] ret12436g(); // no error + +/******************************************/ +// parameter type + +/* +TEST_OUTPUT: +--- +fail_compilation/fail12436.d(46): Error: cannot have parameter of function type void() +--- +*/ +void test3(FuncType) {} + +/* +TEST_OUTPUT: +--- +fail_compilation/fail12436.d(55): Error: cannot have parameter of opaque type Opaque by value +fail_compilation/fail12436.d(56): Error: cannot have parameter of opaque type Opaque[1] by value +--- +*/ +void param12436a(Opaque); // error +void param12436b(Opaque[1]); // error +void param12436c(Opaque*); // no error +void param12436d(Opaque[]); // no error +void param12436e(Opaque[]*); // no error + +void param12436f(ref Opaque); // no error +void param12436g(ref Opaque[1]); // no error +void param12436h(out Opaque); // no error +void param12436i(out Opaque[1]); // no error diff --git a/test/fail_compilation/fail130.d b/test/fail_compilation/fail130.d deleted file mode 100644 index 844c1838d03e..000000000000 --- a/test/fail_compilation/fail130.d +++ /dev/null @@ -1,15 +0,0 @@ -/* -TEST_OUTPUT: ---- -fail_compilation/fail130.d(12): Error: functions cannot return a tuple ---- -*/ - -template Tuple(T...) { alias T Tuple; } - -alias Tuple!(int,int) TType; - -TType foo() -{ - return TType; -}