From b21382f93c961be3396ee691333b77bb33303e5f Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 28 Nov 2011 13:41:59 +0100 Subject: [PATCH] Bug 364108: Exponential complexity parsing code with missing closing braces. --- .../parser/tests/ast2/AST2CPPSpecTest.java | 55 ++++++++++--------- .../tests/ast2/FaultToleranceTests.java | 37 +++++++++++++ .../ast2/GCCCompleteParseExtensionsTest.java | 2 +- .../parser/AbstractGNUSourceCodeParser.java | 8 ++- .../core/dom/parser/DeclarationOptions.java | 11 ++-- .../dom/parser/cpp/GNUCPPSourceParser.java | 2 +- 6 files changed, 79 insertions(+), 36 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index fae5b672666..156d1e97c51 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -1941,33 +1941,34 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(getAboveComment(), ParserLanguage.CPP, true, 0); } - // void f(double& a) { a += 3.14; } - // // ... - // int foo() { - // double d = 0; - // f(d); - // int v[20]; - // // ... - // int& g(int i) { return v[i]; } - // // ... - // g(3) = 7; - // } - // struct link { - // link* next; - // }; - // link* first; - // void h(link*& p) // p is a reference to pointer - // { - // p->next = first; - // first = p; - // p = 0; - // } - // void k() - // { - // link* q = new link; - // h(q); - // } - public void test8_3_2s2() throws Exception { + // void f(double& a) { a += 3.14; } + // void foo1() { + // double d = 0; + // f(d); + // } + // + // int v[20]; + // int& g(int i) { return v[i]; } + // void foo2() { + // g(3) = 7; + // } + // + // struct link { + // link* next; + // }; + // link* first; + // void h(link*& p) // p is a reference to pointer + // { + // p->next = first; + // first = p; + // p = 0; + // } + // void k() + // { + // link* q = new link; + // h(q); + // } + public void test8_3_2s3() throws Exception { parse(getAboveComment(), ParserLanguage.CPP, true, 0); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/FaultToleranceTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/FaultToleranceTests.java index bd7993150fe..46beb30698f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/FaultToleranceTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/FaultToleranceTests.java @@ -278,4 +278,41 @@ public class FaultToleranceTests extends AST2BaseTest { p= getDeclaration(tu, 1); s= getDeclaration(tu, 2); } + + // TINT* f(TINT* p) { + // TINT* f1(TINT* p) { + // TINT* f2(TINT* p) { + // TINT* f3(TINT* p) { + // TINT* f4(TINT* p) { + // TINT* f5(TINT* p) { + // TINT* f6(TINT* p) { + // TINT* f7(TINT* p) { + // TINT* f8(TINT* p) { + // TINT* f9(TINT* p) { + // TINT* f10(TINT* p) { + // TINT* f11(TINT* p) { + // TINT* f12(TINT* p) { + // TINT* f13(TINT* p) { + // TINT* f14(TINT* p) { + // TINT* f15(TINT* p) { + // TINT* f16(TINT* p) { + // TINT* f17(TINT* p) { + // TINT* f18(TINT* p) { + // TINT* f19(TINT* p) { + // TINT* f20(TINT* p) { + // TINT* f21(TINT* p) { + // TINT* f22(TINT* p) { + // TINT* f23(TINT* p) { + // TINT* f24(TINT* p) { + // TINT* f25(TINT* p) { + // TINT* f26(TINT* p) { + // TINT* f27(TINT* p) { + // TINT* f28(TINT* p) { + // TINT* f29(TINT* p) { + // } + public void testPerformanceIssue_364108() throws Exception { + final String comment= getAboveComment(); + parse(comment, ParserLanguage.CPP, false, false); + parse(comment, ParserLanguage.C, false, false); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java index 446116a1b8a..be16c393abe 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java @@ -216,7 +216,7 @@ public class GCCCompleteParseExtensionsTest extends AST2BaseTest { parseGPP( writer.toString() ); writer = new StringWriter(); - writer.write( "int x = ({ int foo() { return 1; } int y = foo (); int z;\n" ); //$NON-NLS-1$ + writer.write( "int x = ({ int foo(); 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$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index 946044da4b2..17e44a1607f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -1874,9 +1874,11 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { ds = nodeFactory.newDeclarationStatement(d); setRange(ds, d); } catch (BacktrackException b) { - if (expressionStatement == null) { - IASTNode node = b.getNodeBeforeProblem(); - if (node instanceof IASTDeclaration) { + IASTNode node = b.getNodeBeforeProblem(); + final boolean isProblemDecl = node instanceof IASTDeclaration; + if (expressionStatement == null + || (!foundSemicolon && isProblemDecl && node.contains(expressionStatement))) { + if (isProblemDecl) { ds= nodeFactory.newDeclarationStatement((IASTDeclaration) node); b.initialize(b.getProblem(), setRange(ds, node)); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java index 93a7c5213db..b48d03820b7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java @@ -29,16 +29,17 @@ public class DeclarationOptions { final public static int ALLOW_FOLLOWED_BY_BRACE= 0x1000; final public static int ALLOW_OPAQUE_ENUM= 0x2000; final public static int SINGLE_DTOR= 0x4000; + final public static int ALLOW_FUNCTION_DEFINITION= 0x8000; public static final DeclarationOptions - GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_OPAQUE_ENUM), - FUNCTION_STYLE_ASM= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | NO_INITIALIZER | ALLOW_ABSTRACT), + GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_OPAQUE_ENUM | ALLOW_FUNCTION_DEFINITION), + FUNCTION_STYLE_ASM= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | NO_INITIALIZER | ALLOW_ABSTRACT | ALLOW_FUNCTION_DEFINITION), C_MEMBER= new DeclarationOptions(ALLOW_BITFIELD | ALLOW_ABSTRACT), - CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD | NO_CTOR_STYLE_INITIALIZER), + CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD | NO_CTOR_STYLE_INITIALIZER | ALLOW_FUNCTION_DEFINITION), LOCAL= new DeclarationOptions(ALLOW_OPAQUE_ENUM), PARAMETER= new DeclarationOptions(ALLOW_ABSTRACT | ALLOW_PARAMETER_PACKS | REQUIRE_SIMPLE_NAME | NO_BRACED_INITIALIZER | NO_CTOR_STYLE_INITIALIZER), TYPEID= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER), - TYPEID_TRAILING_RETURN_TYPE= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | ALLOW_FOLLOWED_BY_BRACE), + TYPEID_TRAILING_RETURN_TYPE= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | ALLOW_FOLLOWED_BY_BRACE | ALLOW_FUNCTION_DEFINITION), TYPEID_NEW= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | NO_FUNCTIONS | NO_NESTED | ALLOW_FOLLOWED_BY_BRACE), TYPEID_CONVERSION= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | NO_FUNCTIONS | NO_NESTED), EXCEPTION= new DeclarationOptions(ALLOW_ABSTRACT | NO_INITIALIZER), @@ -60,6 +61,7 @@ public class DeclarationOptions { final public boolean fRequireSimpleName; final public boolean fAllowOpaqueEnum; final public boolean fSingleDtor; + final public boolean fAllowFunctionDefinition; public DeclarationOptions(int options) { fAllowEmptySpecifier= (options & ALLOW_EMPTY_SPECIFIER) != 0; @@ -76,5 +78,6 @@ public class DeclarationOptions { fCanBeFollowedByBrace= fAllowBracedInitializer || (options & ALLOW_FOLLOWED_BY_BRACE) != 0; fAllowOpaqueEnum= (options & ALLOW_OPAQUE_ENUM) != 0; fSingleDtor= (options & SINGLE_DTOR) != 0; + fAllowFunctionDefinition= (options & ALLOW_FUNCTION_DEFINITION) != 0; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 0631dec1572..f5ecef7ddd4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -2390,7 +2390,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IToken.t_try: case IToken.tLBRACE: case IToken.tASSIGN: // defaulted or deleted function definition - if (declarators.length != 1) + if (declarators.length != 1 || !declOption.fAllowFunctionDefinition) throwBacktrack(LA(1)); dtor= declarators[0];