From ad54f4685351f603f40e5c89fe9a44b27867cfbd Mon Sep 17 00:00:00 2001 From: John Camelon Date: Tue, 28 Sep 2004 15:22:02 +0000 Subject: [PATCH] Fixed Bug 39677 - Statements in expressions are not supported (GCC) --- .../parser/failedTests/ASTFailedTests.java | 5 +- .../tests/GCCCompleteParseExtensionsTest.java | 23 ++++++- .../tests/GCCQuickParseExtensionsTest.java | 21 ++++++ .../parser/ast/gcc/IASTGCCExpression.java | 1 + .../parser/extension/IParserExtension.java | 9 +++ .../core/parser/GCCParserExtension.java | 15 +++++ .../cdt/internal/core/parser/Parser.java | 64 ++++++++++++++++++- .../ast/complete/CompleteParseASTFactory.java | 2 +- .../complete/gcc/GCCASTCompleteExtension.java | 3 + 9 files changed, 133 insertions(+), 10 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/ASTFailedTests.java b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/ASTFailedTests.java index fb4b3b3e286..6cb6980fc1e 100644 --- a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/ASTFailedTests.java +++ b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/ASTFailedTests.java @@ -38,10 +38,7 @@ public class ASTFailedTests extends BaseASTTest { assertCodeFailsParse("struct { int e1, e2; } v = { e2: 0 }"); } - public void testBug39677() throws Exception - { - assertCodeFailsParse("B::B() : a(({ 1; })) {}"); - } + public void testBug39679() throws Exception { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCCompleteParseExtensionsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCCompleteParseExtensionsTest.java index 035ca604a04..59e25beee67 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCCompleteParseExtensionsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCCompleteParseExtensionsTest.java @@ -37,7 +37,6 @@ public class GCCCompleteParseExtensionsTest extends CompleteParseBaseTest { */ public GCCCompleteParseExtensionsTest() { super(); - // TODO Auto-generated constructor stub } /** @@ -45,7 +44,6 @@ public class GCCCompleteParseExtensionsTest extends CompleteParseBaseTest { */ public GCCCompleteParseExtensionsTest(String name) { super(name); - // TODO Auto-generated constructor stub } public void testBug39695() throws Exception @@ -189,4 +187,25 @@ public class GCCCompleteParseExtensionsTest extends CompleteParseBaseTest { code.write("}\n"); //$NON-NLS-1$ parse(code.toString()); } + + public void testBug39677() throws Exception + { + parse("class B { public: B(); int a;}; B::B() : a(({ 1; })) {}"); //$NON-NLS-1$ + Writer writer = new StringWriter(); + writer.write( "B::B() : a(( { int y = foo (); int z;\n" ); //$NON-NLS-1$ + writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ + writer.write( "else z = - y;\n" );//$NON-NLS-1$ + writer.write( "z; }))\n" );//$NON-NLS-1$ + parse( writer.toString() ); + writer = new StringWriter(); + writer.write( "int x = ({ int y = foo (); int z;\n" ); //$NON-NLS-1$ + writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ + writer.write( "else z = - y;\n" );//$NON-NLS-1$ + writer.write( "z; });\n" );//$NON-NLS-1$ + writer = new StringWriter(); + writer.write( "typeof({ int y = foo (); int z;\n" ); //$NON-NLS-1$ + writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ + writer.write( "else z = - y;\n" );//$NON-NLS-1$ + writer.write( "z; }) zoot;\n" );//$NON-NLS-1$ + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCQuickParseExtensionsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCQuickParseExtensionsTest.java index 60768a85fe8..c375d4963d9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCQuickParseExtensionsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCQuickParseExtensionsTest.java @@ -129,4 +129,25 @@ public class GCCQuickParseExtensionsTest extends BaseASTTest { code.write("}\n"); //$NON-NLS-1$ parse(code.toString()); } + + public void testBug39677() throws Exception + { + parse("B::B() : a(({ 1; })) {}"); //$NON-NLS-1$ + Writer writer = new StringWriter(); + writer.write( "B::B() : a(( { int y = foo (); int z;\n" ); //$NON-NLS-1$ + writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ + writer.write( "else z = - y;\n" );//$NON-NLS-1$ + writer.write( "z; }))\n" );//$NON-NLS-1$ + parse( writer.toString() ); + writer = new StringWriter(); + writer.write( "int x = ({ int y = foo (); int z;\n" ); //$NON-NLS-1$ + writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ + writer.write( "else z = - y;\n" );//$NON-NLS-1$ + writer.write( "z; });\n" );//$NON-NLS-1$ + writer = new StringWriter(); + writer.write( "typeof({ int y = foo (); int z;\n" ); //$NON-NLS-1$ + writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ + writer.write( "else z = - y;\n" );//$NON-NLS-1$ + writer.write( "z; }) zoot;\n" );//$NON-NLS-1$ + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/gcc/IASTGCCExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/gcc/IASTGCCExpression.java index 893c25abc81..852f11db751 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/gcc/IASTGCCExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/gcc/IASTGCCExpression.java @@ -26,6 +26,7 @@ public interface IASTGCCExpression extends IASTExpression { public static final Kind UNARY_TYPEOF_TYPEID = new Kind( LAST_KIND + 4 ); public static final Kind RELATIONAL_MAX = new Kind( LAST_KIND + 5 ); public static final Kind RELATIONAL_MIN = new Kind( LAST_KIND + 6 ); + public static final Kind STATEMENT_EXPRESSION = new Kind( LAST_KIND + 7 ); protected Kind( int kind ) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/extension/IParserExtension.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/extension/IParserExtension.java index e93b49deff1..e8d29102fa1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/extension/IParserExtension.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/extension/IParserExtension.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.parser.ast.IASTDesignator; import org.eclipse.cdt.core.parser.ast.IASTExpression; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind; +import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind; import org.eclipse.cdt.internal.core.parser.DeclarationWrapper; import org.eclipse.cdt.internal.core.parser.IParserData; import org.eclipse.cdt.internal.core.parser.Parser; @@ -67,4 +68,12 @@ public interface IParserExtension { * @return */ public IASTDesignator parseDesignator(IParserData parserData, IASTScope scope); + /** + * @return + */ + public boolean supportsStatementsInExpressions(); + /** + * @return + */ + public Kind getExpressionKindForStatement(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/GCCParserExtension.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/GCCParserExtension.java index de8adac444f..5839218aed7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/GCCParserExtension.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/GCCParserExtension.java @@ -28,6 +28,7 @@ import org.eclipse.cdt.core.parser.ast.IASTExpression; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTTypeId; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind; +import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind; import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCDesignator; import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCExpression; import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCSimpleTypeSpecifier; @@ -448,4 +449,18 @@ public class GCCParserExtension implements IParserExtension { } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.extension.IParserExtension#supportsStatementsInExpressions() + */ + public boolean supportsStatementsInExpressions() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.extension.IParserExtension#getExpressionKindForStatement() + */ + public Kind getExpressionKindForStatement() { + return IASTGCCExpression.Kind.STATEMENT_EXPRESSION; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index 9135aa3d501..03cfa4cfac6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -804,6 +804,16 @@ public class Parser implements IParserData, IParser int startingOffset = la.getOffset(); int ln = la.getLineNumber(); char [] fn = la.getFilename(); + + IASTExpression resultExpression = null; + if( la.getType() == IToken.tLPAREN && LT(2) == IToken.tLBRACE && extension.supportsStatementsInExpressions() ) + { + resultExpression = compoundStatementExpression(scope, la, resultExpression); + } + + if( resultExpression != null ) + return resultExpression; + IASTExpression assignmentExpression = assignmentExpression(scope, kind, key); while (LT(1) == IToken.tCOMMA) { @@ -828,6 +838,52 @@ public class Parser implements IParserData, IParser return assignmentExpression; } + /** + * @param scope + * @param la + * @param resultExpression + * @return + * @throws EndOfFileException + * @throws BacktrackException + */ + private IASTExpression compoundStatementExpression(IASTScope scope, IToken la, IASTExpression resultExpression) throws EndOfFileException, BacktrackException { + int startingOffset = la.getOffset(); + int ln = la.getLineNumber(); + char [] fn = la.getFilename(); + consume( IToken.tLPAREN ); + try + { + if( mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE ) + skipOverCompoundStatement(); + else if( mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE ) + { + if( scanner.isOnTopContext() ) + compoundStatement(scope, true); + else + skipOverCompoundStatement(); + } + else if( mode == ParserMode.COMPLETE_PARSE ) + compoundStatement(scope, true); + + consume( IToken.tRPAREN ); + try + { + resultExpression = astFactory.createExpression( scope, extension.getExpressionKindForStatement(), null, null, null, null, null,EMPTY_STRING, null ); + } + catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("expression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset, lastToken != null ? lastToken.getEndOffset() : 0 , ln, fn); + } + } + catch( BacktrackException bte ) + { + backup( la ); + } + return resultExpression; + } + /** * @param expression * @throws BacktrackException @@ -839,6 +895,7 @@ public class Parser implements IParserData, IParser if (LT(1) == IToken.t_throw) { return throwExpression(scope, key); } + IASTExpression conditionalExpression = conditionalExpression(scope, kind, key); // if the condition not taken, try assignment operators @@ -935,8 +992,8 @@ public class Parser implements IParserData, IParser IToken la = LA(1); int startingOffset = la.getOffset(); int ln = la.getLineNumber(); - char [] fn = la.getFilename(); - la = null; + char [] fn = la.getFilename(); + IASTExpression firstExpression = logicalOrExpression(scope, kind, key); if (LT(1) == IToken.tQUESTION) { consume(IToken.tQUESTION); @@ -4159,7 +4216,8 @@ public class Parser implements IParserData, IParser consume(IToken.tLPAREN); IASTExpression expressionList = null; - expressionList = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); + if( LT(1) != IToken.tRPAREN ) + expressionList = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); IToken rparen = consume(IToken.tRPAREN); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index bb527b21c51..2e9847adde8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -1761,7 +1761,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto || (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR) ){ ASTExpression left = (ASTExpression)lhs; - if(left != null){ + if(left != null && left.getResultType() != null ){ info =left.getResultType().getResult(); } else handleProblem( scope, IProblem.SEMANTIC_MALFORMED_EXPRESSION, null ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java index 37ecf25aae3..0eacc8a63f6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java @@ -40,6 +40,7 @@ import org.eclipse.cdt.internal.core.parser.DeclarationWrapper; import org.eclipse.cdt.internal.core.parser.Declarator; import org.eclipse.cdt.internal.core.parser.ast.GCCASTExtension; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTBinaryExpression; +import org.eclipse.cdt.internal.core.parser.ast.complete.ASTEmptyExpression; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTypeIdExpression; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTUnaryExpression; import org.eclipse.cdt.internal.core.parser.ast.complete.ExpressionFactory; @@ -114,6 +115,8 @@ public class GCCASTCompleteExtension extends GCCASTExtension { } }; } + else if( kind == IASTGCCExpression.Kind.STATEMENT_EXPRESSION ) + return new ASTEmptyExpression( kind, references ); else if( lhs != null && (kind == IASTGCCExpression.Kind.UNARY_ALIGNOF_UNARYEXPRESSION || kind == IASTGCCExpression.Kind.UNARY_TYPEOF_UNARYEXPRESSION) )