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

fix Issue 22102 - importC: Error: function is used as a type #12834

Merged
merged 1 commit into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/dmd/cparse.d
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,18 @@ final class CParser(AST) : Parser!AST
case TOK.rightShiftAssign:
goto Lexp;

case TOK.leftParenthesis:
{
/* If tokens look like a function call, assume it is one,
* As any type-name won't be resolved until semantic, this
* could be rewritten later.
*/
auto tk = &token;
if (isFunctionCall(tk))
goto Lexp;
goto default;
}

default:
{
/* If tokens look like a declaration, assume it is one
Expand Down Expand Up @@ -3208,6 +3220,46 @@ final class CParser(AST) : Parser!AST
return true;
}

/********************************
* See if match for:
* postfix-expression ( argument-expression-list(opt) )
* Params:
* pt = starting token, updated to one past end of initializer if true
* Returns:
* true if function call
*/
private bool isFunctionCall(ref Token* pt)
{
//printf("isFunctionCall()\n");
auto t = pt;

if (!isPrimaryExpression(t))
return false;
if (t.value != TOK.leftParenthesis)
return false;
t = peek(t);
while (1)
{
if (!isAssignmentExpression(t))
return false;
if (t.value == TOK.comma)
{
t = peek(t);
continue;
}
if (t.value == TOK.rightParenthesis)
{
t = peek(t);
break;
}
return false;
}
if (t.value != TOK.semicolon)
return false;
pt = t;
return true;
}

/********************************
* See if match for assignment-expression.
* Params:
Expand Down
34 changes: 34 additions & 0 deletions src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -4463,6 +4463,40 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// Rewrite (*fp)(arguments) to fp(arguments)
exp.e1 = (cast(PtrExp)exp.e1).e1;
}
else if (exp.e1.op == TOK.type && (sc && sc.flags & SCOPE.Cfile))
{
/* Ambiguous cases arise from CParser where there is not enough
* information to determine if we have a function call or declaration.
* type-name ( identifier ) ;
* identifier ( identifier ) ;
* If exp.e1 is a type-name, then this is a declaration. C11 does not
* have type construction syntax, so don't convert this to a cast().
*/
if (exp.arguments && exp.arguments.dim == 1)
{
Expression arg = (*exp.arguments)[0];
if (auto ie = (*exp.arguments)[0].isIdentifierExp())
{
TypeExp te = cast(TypeExp)exp.e1;
auto initializer = new VoidInitializer(ie.loc);
Dsymbol s = new VarDeclaration(ie.loc, te.type, ie.ident, initializer);
auto decls = new Dsymbols(1);
(*decls)[0] = s;
s = new LinkDeclaration(s.loc, LINK.c, decls);
result = new DeclarationExp(exp.loc, s);
result = result.expressionSemantic(sc);
}
else
{
arg.error("identifier or `(` expected");
result = ErrorExp.get();
}
return;
}
exp.error("identifier or `(` expected before `)`");
result = ErrorExp.get();
return;
}
}

Type t1 = exp.e1.type ? exp.e1.type.toBasetype() : null;
Expand Down
16 changes: 14 additions & 2 deletions test/compilable/testcstuff2.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ void test22063()

void test22066()
{
int var = 0;
(var)++;
int var = 0;
(var)++;
}

/***************************************************/
Expand Down Expand Up @@ -320,6 +320,18 @@ void test22088()
c = ld;
}

/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=22102

void fun22102(int var);
typedef int int22102;

void test22102()
{
int22102(var);
fun22102(var);
}

/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=22103

Expand Down
16 changes: 16 additions & 0 deletions test/fail_compilation/failcstuff1.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ fail_compilation/failcstuff1.c(460): Error: variable length arrays are not suppo
fail_compilation/failcstuff1.c(460): Error: variable length array used outside of function prototype
fail_compilation/failcstuff1.c(461): Error: array type has incomplete element type `int[]`
fail_compilation/failcstuff1.c(462): Error: `=`, `;` or `,` expected
fail_compilation/failcstuff1.c(502): Error: identifier or `(` expected
fail_compilation/failcstuff1.c(502): Error: found `;` when expecting `)`
fail_compilation/failcstuff1.c(503): Error: `=`, `;` or `,` expected
fail_compilation/failcstuff1.c(504): Error: identifier or `(` expected
fail_compilation/failcstuff1.c(504): Error: found `;` when expecting `)`
fail_compilation/failcstuff1.c(505): Error: `=`, `;` or `,` expected
---
*/

Expand Down Expand Up @@ -132,3 +138,13 @@ void test22103e()
int array4[][];
int array4[4] const;
}

// https://issues.dlang.org/show_bug.cgi?id=22102
#line 500
void test22102()
{
int(0);
int var1;
int();
int var2;
}
13 changes: 13 additions & 0 deletions test/fail_compilation/failcstuff2.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ fail_compilation/failcstuff2.c(204): Error: variable `var` is used as a type
fail_compilation/failcstuff2.c(203): variable `var` is declared here
fail_compilation/failcstuff2.c(205): Error: variable `var` is used as a type
fail_compilation/failcstuff2.c(203): variable `var` is declared here
fail_compilation/failcstuff2.c(254): Error: identifier or `(` expected before `)`
fail_compilation/failcstuff2.c(255): Error: identifier or `(` expected
---
*/

Expand Down Expand Up @@ -97,3 +99,14 @@ void test21992(int var)
var = (var) ~ 1234;
var = (var) ! 1234;
}

/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=22102
#line 250
typedef int int22102;

void test22102()
{
int22102();
int22102(0);
}