Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow qualified types in base class list #16882

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 41 additions & 25 deletions compiler/src/dmd/parse.d
Original file line number Diff line number Diff line change
Expand Up @@ -2859,7 +2859,7 @@
{
case TOK.rightParenthesis:
if (storageClass != 0 || udas !is null)
error("basic type expected, not `)`");
error("primary type expected, not `)`");

Check warning on line 2862 in compiler/src/dmd/parse.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/parse.d#L2862

Added line #L2862 was not covered by tests
break;

case TOK.dotDotDot:
Expand Down Expand Up @@ -3074,7 +3074,7 @@
nextToken();
int alt = 0;
const typeLoc = token.loc;
memtype = parseBasicType();
memtype = parsePrimaryType();
memtype = parseDeclarator(memtype, alt, null);
checkCstyleTypeSyntax(typeLoc, memtype, alt, null);
}
Expand Down Expand Up @@ -3186,7 +3186,7 @@
else
{
Token* t = &token;
if (isBasicType(&t))
if (isPrimaryType(&t))

Check warning on line 3189 in compiler/src/dmd/parse.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/parse.d#L3189

Added line #L3189 was not covered by tests
{
error("named enum cannot declare member with type", (*t).toChars());
nextToken();
Expand Down Expand Up @@ -3582,7 +3582,7 @@
const typeLoc = token.loc;

AST.Type t;
t = parseBasicType();
t = parsePrimaryType();

if (pdeclLoc)
*pdeclLoc = token.loc;
Expand All @@ -3594,7 +3594,7 @@
return t;
}

private AST.Type parseBasicType(bool dontLookDotIdents = false)
private AST.Type parseBasicType(bool dontLookDotIdents = false, bool parsingPrimaryType = false)
{
AST.Type t;
Loc loc;
Expand Down Expand Up @@ -3723,11 +3723,11 @@
{
// ident!(template_arguments)
auto tempinst = new AST.TemplateInstance(loc, id, parseTemplateArguments());
t = parseBasicTypeStartingAt(new AST.TypeInstance(loc, tempinst), dontLookDotIdents);
t = parsePrimaryTypeStartingAt(new AST.TypeInstance(loc, tempinst), dontLookDotIdents);
}
else
{
t = parseBasicTypeStartingAt(new AST.TypeIdentifier(loc, id), dontLookDotIdents);
t = parsePrimaryTypeStartingAt(new AST.TypeIdentifier(loc, id), dontLookDotIdents);
}
break;

Expand All @@ -3743,14 +3743,33 @@

case TOK.dot:
// Leading . as in .foo
t = parseBasicTypeStartingAt(new AST.TypeIdentifier(token.loc, Id.empty), dontLookDotIdents);
t = parsePrimaryTypeStartingAt(new AST.TypeIdentifier(token.loc, Id.empty), dontLookDotIdents);
break;

case TOK.typeof_:
// typeof(expression)
t = parseBasicTypeStartingAt(parseTypeof(), dontLookDotIdents);
t = parsePrimaryTypeStartingAt(parseTypeof(), dontLookDotIdents);
break;

default:
immutable char* kind = parsingPrimaryType ? "primary" : "basic";
error("%s type expected, not `%s`", kind, token.toChars());
if (token.value == TOK.else_)
eSink.errorSupplemental(token.loc, "There's no `static else`, use `else` instead.");
t = AST.Type.terror;
break;
}
return t;
}

private AST.Type parsePrimaryType(bool dontLookDotIdents = false)
{
AST.Type t;
Loc loc;
Identifier id;
//printf("parsePrimaryType()\n");
switch (token.value)
{
case TOK.vector:
t = parseVector();
break;
Expand Down Expand Up @@ -3798,20 +3817,17 @@
break;

default:
error("basic type expected, not `%s`", token.toChars());
if (token.value == TOK.else_)
eSink.errorSupplemental(token.loc, "There's no `static else`, use `else` instead.");
t = AST.Type.terror;
t = parseBasicType(dontLookDotIdents, /+parsingPrimaryType:+/true);
break;
}
return t;
}

private AST.Type parseBasicTypeStartingAt(AST.TypeQualified tid, bool dontLookDotIdents)
private AST.Type parsePrimaryTypeStartingAt(AST.TypeQualified tid, bool dontLookDotIdents)
{
AST.Type maybeArray = null;
// See https://issues.dlang.org/show_bug.cgi?id=1215
// A basic type can look like MyType (typical case), but also:
// A primary type can look like MyType (typical case), but also:
// MyType.T -> A type
// MyType[expr] -> Either a static array of MyType or a type (iif MyType is a Ttuple)
// MyType[expr].T -> A type.
Expand Down Expand Up @@ -4517,7 +4533,7 @@
}
else
{
ts = parseBasicType();
ts = parsePrimaryType();
ts = parseTypeSuffixes(ts);
}
}
Expand Down Expand Up @@ -4971,7 +4987,7 @@
if (udas)
error("user-defined attributes not allowed for `alias` declarations");

auto t = parseBasicType();
auto t = parsePrimaryType();
t = parseTypeSuffixes(t);
if (token.value == TOK.identifier)
{
Expand Down Expand Up @@ -5115,7 +5131,7 @@
{
// function type (parameters) { statements... }
// delegate type (parameters) { statements... }
tret = parseBasicType();
tret = parsePrimaryType();
tret = parseTypeSuffixes(tret); // function return type
}

Expand Down Expand Up @@ -7211,7 +7227,7 @@
break;
}

if (!isBasicType(&t))
if (!isPrimaryType(&t))
{
goto Lisnot;
}
Expand Down Expand Up @@ -7240,10 +7256,10 @@
return false;
}

// pt = test token. If found, pt is set to the token after BasicType
private bool isBasicType(Token** pt)
// pt = test token. If found, pt is set to the token after PrimaryType
private bool isPrimaryType(Token** pt)
{
// This code parallels parseBasicType()
// This code parallels parsePrimaryType()
Token* t = *pt;
switch (t.value)
{
Expand Down Expand Up @@ -7746,7 +7762,7 @@

default:
{
if (!isBasicType(&t))
if (!isPrimaryType(&t))
return false;
L2:
int tmp = false;
Expand Down Expand Up @@ -8785,7 +8801,7 @@
{
StorageClass stc = parseTypeCtor();

AST.Type t = parseBasicType();
AST.Type t = parsePrimaryType();
t = t.addSTC(stc);

if (stc == 0 && token.value == TOK.dot)
Expand Down Expand Up @@ -9545,7 +9561,7 @@
}

const stc = parseTypeCtor();
auto t = parseBasicType(true);
auto t = parsePrimaryType(true);
t = parseTypeSuffixes(t);
t = t.addSTC(stc);
if (t.ty == Taarray)
Expand Down
12 changes: 12 additions & 0 deletions compiler/test/fail_compilation/qualbaseclass1.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* TEST_OUTPUT:
---
fail_compilation\qualbaseclass1.d(101): Error: basic type expected, not `const`
fail_compilation\qualbaseclass1.d(101): Error: { } expected following `class` declaration
fail_compilation\qualbaseclass1.d(101): Error: no identifier for declarator `const(Object)`
fail_compilation\qualbaseclass1.d(101): Error: declaration expected, not `{`
---
*/

#line 100

class C : const(Object) { }
15 changes: 15 additions & 0 deletions compiler/test/fail_compilation/qualbaseclass2.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* TEST_OUTPUT:
---
fail_compilation\qualbaseclass2.d(103): Error: basic type expected, not `const`
fail_compilation\qualbaseclass2.d(103): Error: `{ members }` expected for anonymous class
fail_compilation\qualbaseclass2.d(103): Error: semicolon expected following auto declaration, not `const`
fail_compilation\qualbaseclass2.d(103): Error: no identifier for declarator `const(Object)`
---
*/

#line 100

void test()
{
auto obj = new class () const(Object) { };
}
Loading