Skip to content

Commit

Permalink
Fixes bug 435: Constructors should be templatized
Browse files Browse the repository at this point in the history
Basically just applying Shin Fujishiro's patch, with some test cases.
  • Loading branch information
kennytm committed Feb 13, 2012
1 parent f330b95 commit 59c5fe5
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 5 deletions.
7 changes: 6 additions & 1 deletion src/class.c
Expand Up @@ -687,9 +687,14 @@ void ClassDeclaration::semantic(Scope *sc)
/* Look for special member functions.
* They must be in this class, not in a base class.
*/
ctor = (CtorDeclaration *)search(0, Id::ctor, 0);
ctor = search(0, Id::ctor, 0);
#if DMDV1
if (ctor && (ctor->toParent() != this || !ctor->isCtorDeclaration()))
ctor = NULL;
#else
if (ctor && (ctor->toParent() != this || !(ctor->isCtorDeclaration() || ctor->isTemplateDeclaration())))
ctor = NULL; // search() looks through ancestor classes
#endif

// dtor = (DtorDeclaration *)search(Id::dtor, 0);
// if (dtor && dtor->toParent() != this)
Expand Down
8 changes: 4 additions & 4 deletions src/expression.c
Expand Up @@ -7649,8 +7649,8 @@ Expression *CallExp::semantic(Scope *sc)
// Base class constructor call
ClassDeclaration *cd = NULL;

if (sc->func)
cd = sc->func->toParent()->isClassDeclaration();
if (sc->func && sc->func->isThis())
cd = sc->func->isThis()->isClassDeclaration();
if (!cd || !cd->baseClass || !sc->func->isCtorDeclaration())
{
error("super class constructor call must be in a constructor");
Expand Down Expand Up @@ -7695,8 +7695,8 @@ Expression *CallExp::semantic(Scope *sc)
// same class constructor call
AggregateDeclaration *cd = NULL;

if (sc->func)
cd = sc->func->toParent()->isAggregateDeclaration();
if (sc->func && sc->func->isThis())
cd = sc->func->isThis()->isAggregateDeclaration();
if (!cd || !sc->func->isCtorDeclaration())
{
error("constructor call must be in a constructor");
Expand Down
143 changes: 143 additions & 0 deletions test/runnable/test435.d
@@ -0,0 +1,143 @@
import core.stdc.stdio;

class A
{
immutable size_t f;

this(T)(T z)
{
f = z.sizeof;
}
}

struct AS
{
immutable size_t f;

this(T)(T z)
{
f = z.sizeof;
}
}

void test0()
{
assert((new A(2.2)).f == double.sizeof);
assert((new A('g')).f == char.sizeof);
assert((AS(17)).f == int.sizeof);
assert((AS(null)).f == typeof(null).sizeof);
}

//------------------------------------------------------------------------------

class C
{
const int x;
const int y;

this(T...)(T z)
{
this.tupleof = z;
}
}

struct CS
{
const int x;
const int y;

this(T...)(T z)
{
this.tupleof = z;
}
}

void test1()
{
auto c = new C(4, 6);
assert(c.x == 4);
assert(c.y == 6);

auto cs = CS(7, 8);
assert(cs.x == 7);
assert(cs.y == 8);
}

//------------------------------------------------------------------------------

// bug 435.
class B
{
int i;
this(int k)
{
i = k;
}
}
class D : B
{
this(A...)(A args)
{
super(args);
}
}

void test2()
{
auto a = new D(4);
assert(a.i == 4);
}

//------------------------------------------------------------------------------

// bug 4905
class C2
{
string x;

this(T...)(in string msg, T args)
{
x = msg;
foreach (a; args)
x ~= a;
}
}

void test3()
{
auto c2 = new C2("test");
assert(c2.x == "test");

auto c3 = new C2("test", " variadic", " constructor");
assert(c3.x == "test variadic constructor");
}

//------------------------------------------------------------------------------

// bug 4531 test case 2
class MyError : Exception
{
this(T...)(T msg)
{
assert(msg[0] == "Hello, " && msg[1] == 42);
super("Hello, 42");
}
}

void test4()
{
auto err = new MyError("Hello, ", 42);
assert(err.msg == "Hello, 42");
}

void main()
{
test0();
test1();
test2();
test3();
test4();
printf("Success\n");
}


0 comments on commit 59c5fe5

Please sign in to comment.