fix Issue 23509 - ImportC: need statement expressions extension for GLibC's assert() (#15093)

This commit is contained in:
Walter Bright 2023-04-10 10:35:55 -07:00 committed by GitHub
parent 77cacd2f76
commit b571a1a118
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 4 deletions

View file

@ -799,7 +799,10 @@ final class CParser(AST) : Parser!AST
case TOK.leftParenthesis:
nextToken();
e = cparseExpression();
if (token.value == TOK.leftCurly)
e = cparseStatementExpression(); // gcc extension
else
e = cparseExpression();
check(TOK.rightParenthesis);
break;
@ -1622,6 +1625,41 @@ final class CParser(AST) : Parser!AST
return e;
}
/*****************************
* gcc extension: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
* Represent as a function literal, then call the function literal.
* Parser is on opening curly brace.
*/
private AST.Expression cparseStatementExpression()
{
AST.ParameterList parameterList;
StorageClass stc = 0;
const loc = token.loc;
typedefTab.push(null);
auto fbody = cparseStatement(ParseStatementFlags.scope_);
typedefTab.pop(); // end of function scope
// Rewrite last ExpStatement (if there is one) as a ReturnStatement
auto ss = fbody.isScopeStatement();
auto cs = ss.statement.isCompoundStatement();
assert(cs);
if (const len = (*cs.statements).length)
{
auto s = (*cs.statements)[len - 1];
if (auto es = s.isExpStatement())
(*cs.statements)[len - 1] = new AST.ReturnStatement(es.loc, es.exp);
}
auto tf = new AST.TypeFunction(parameterList, null, LINK.d, stc);
auto fd = new AST.FuncLiteralDeclaration(loc, token.loc, tf, TOK.delegate_, null, null, 0);
fd.fbody = fbody;
auto fe = new AST.FuncExp(loc, fd);
auto args = new AST.Expressions();
auto e = new AST.CallExp(loc, fe, args); // call the function literal
return e;
}
//}
/********************************************************************************/
/********************************* Declaration Parser ***************************/

View file

@ -196,10 +196,9 @@ private void statementToBuffer(Statement s, OutBuffer* buf, HdrGenState* hgs)
foreach (sx; *s.statements)
{
auto ds = sx ? sx.isExpStatement() : null;
if (ds && ds.exp.op == EXP.declaration)
if (ds && ds.exp.isDeclarationExp())
{
auto d = (cast(DeclarationExp)ds.exp).declaration;
assert(d.isDeclaration());
auto d = ds.exp.isDeclarationExp().declaration;
if (auto v = d.isVarDeclaration())
{
scope ppv = new DsymbolPrettyPrintVisitor(buf, hgs);

View file

@ -0,0 +1,8 @@
// https://issues.dlang.org/show_bug.cgi?id=23509
int max(int a, int b)
{
return ({int _a = (a), _b = (b); _a > _b ? _a : _b; });
}
_Static_assert(max(3,4) == 4, "1");