1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-10 12:03:16 +02:00

Bug 298455: Stack overflow with deeply nested else if statements.

This commit is contained in:
Markus Schorn 2010-01-04 16:31:32 +00:00
parent 30bddf9ac0
commit a867009329
3 changed files with 119 additions and 39 deletions

View file

@ -7221,4 +7221,18 @@ public class AST2Tests extends AST2BaseTest {
IASTTranslationUnit tu = parseAndCheckBindings(code, lang);
}
}
public void testDeepElseif_298455() throws Exception {
sValidateCopy= false;
StringBuilder buf= new StringBuilder("void f() {if (0) {}");
for (int i = 0; i < 75000; i++) {
buf.append("else if (0) {}");
}
buf.append("}");
String code= buf.toString();
for(ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu = parseAndCheckBindings(code, lang);
}
}
}

View file

@ -92,26 +92,58 @@ public class CASTIfStatement extends ASTNode implements IASTIfStatement, IASTAmb
}
}
@Override
public boolean accept( ASTVisitor action ){
if( action.shouldVisitStatements ){
switch( action.visit( this ) ){
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
}
if( condition != null ) if( !condition.accept( action ) ) return false;
if( thenClause != null ) if( !thenClause.accept( action ) ) return false;
if( elseClause != null ) if( !elseClause.accept( action ) ) return false;
private static class N {
final IASTIfStatement fIfStatement;
N fNext;
if( action.shouldVisitStatements ){
switch( action.leave( this ) ){
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
N(IASTIfStatement stmt) {
fIfStatement = stmt;
}
}
@Override
public boolean accept(ASTVisitor action) {
N stack= null;
IASTIfStatement stmt= this;
loop: for(;;) {
if (action.shouldVisitStatements) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP:
stmt= null;
break loop;
default: break;
}
}
IASTNode child = stmt.getConditionExpression();
if (child != null && !child.accept(action))
return false;
child= stmt.getThenClause();
if (child != null && !child.accept(action))
return false;
child= stmt.getElseClause();
if (child instanceof IASTIfStatement) {
if (action.shouldVisitStatements) {
N n= new N(stmt);
n.fNext= stack;
stack= n;
}
stmt= (IASTIfStatement) child;
} else {
if (child != null && !child.accept(action))
return false;
break loop;
}
}
if (action.shouldVisitStatements) {
if (stmt != null && action.leave(stmt) == ASTVisitor.PROCESS_ABORT)
return false;
while (stack != null) {
if (action.leave(stack.fIfStatement) == ASTVisitor.PROCESS_ABORT)
return false;
stack= stack.fNext;
}
}
return true;
}

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -98,28 +99,61 @@ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IA
}
}
private static class N {
final IASTIfStatement fIfStatement;
N fNext;
N(IASTIfStatement stmt) {
fIfStatement = stmt;
}
}
@Override
public boolean accept( ASTVisitor action ){
if( action.shouldVisitStatements ){
switch( action.visit( this ) ){
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
}
if( condition != null ) if( !condition.accept( action ) ) return false;
if( condDecl != null ) if( !condDecl.accept( action )) return false;
if( thenClause != null ) if( !thenClause.accept( action ) ) return false;
if( elseClause != null ) if( !elseClause.accept( action ) ) return false;
if( action.shouldVisitStatements ){
switch( action.leave( this ) ){
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
}
public boolean accept(ASTVisitor action) {
N stack= null;
ICPPASTIfStatement stmt= this;
loop: for(;;) {
if (action.shouldVisitStatements) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP:
stmt= null;
break loop;
default: break;
}
}
IASTNode child = stmt.getConditionExpression();
if (child != null && !child.accept(action))
return false;
child= stmt.getConditionDeclaration();
if (child != null && !child.accept(action))
return false;
child= stmt.getThenClause();
if (child != null && !child.accept(action))
return false;
child= stmt.getElseClause();
if (child instanceof ICPPASTIfStatement) {
if (action.shouldVisitStatements) {
N n= new N(stmt);
n.fNext= stack;
stack= n;
}
stmt= (ICPPASTIfStatement) child;
} else {
if (child != null && !child.accept(action))
return false;
break loop;
}
}
if (action.shouldVisitStatements) {
if (stmt != null && action.leave(stmt) == ASTVisitor.PROCESS_ABORT)
return false;
while (stack != null) {
if (action.leave(stack.fIfStatement) == ASTVisitor.PROCESS_ABORT)
return false;
stack= stack.fNext;
}
}
return true;
}