Skip to content

Commit

Permalink
Merge pull request #3584 from 9rnsr/fix12436
Browse files Browse the repository at this point in the history
Issue 12436 - Opaque struct parameter type should not be allowed
  • Loading branch information
WalterBright committed May 28, 2014
2 parents dd4a482 + eca6fa4 commit f15bd87
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 36 deletions.
26 changes: 21 additions & 5 deletions src/mtype.c
Expand Up @@ -5478,12 +5478,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;
}
}
Expand Down Expand Up @@ -5535,11 +5535,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))
{
}
Expand Down
2 changes: 1 addition & 1 deletion test/compilable/cppmangle.d
Expand Up @@ -271,7 +271,7 @@ static assert(test10058l.mangleof == "_Z10test10058lPFPvS_EPFS_PKvEPFS3_S_E");
// 11696

class Expression;
struct Loc;
struct Loc {}

extern(C++)
class CallExp
Expand Down
4 changes: 2 additions & 2 deletions 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
---
*/

Expand Down
13 changes: 0 additions & 13 deletions test/fail_compilation/fail112.d

This file was deleted.

64 changes: 64 additions & 0 deletions 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
15 changes: 0 additions & 15 deletions test/fail_compilation/fail130.d

This file was deleted.

0 comments on commit f15bd87

Please sign in to comment.