1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 01:15:29 +02:00

Exponential complexity resolving overloaded function calls, bug 283324.

This commit is contained in:
Markus Schorn 2009-07-22 16:04:46 +00:00
parent 448fec099f
commit 7768ee8e9e
5 changed files with 42 additions and 14 deletions

View file

@ -7267,4 +7267,23 @@ public class AST2CPPTests extends AST2BaseTest {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// class C {
// C& operator()() {return *this;}
// };
// void test() {
// C c;
// c()()()()()()()()()()()()()();
// }
public void testNestedOverloadedFunctionCalls_Bug283324() throws Exception {
final String code = getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.CPP);
IASTFunctionDefinition test= getDeclaration(tu, 1);
IASTExpressionStatement stmt= getStatement(test, 1);
long now= System.currentTimeMillis();
IType t= stmt.getExpression().getExpressionType();
assertInstance(t, ICPPReferenceType.class);
final long time = System.currentTimeMillis() - now;
assertTrue("Lasted " + time + "ms", time < 5000);
}
}

View file

@ -19,9 +19,11 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.parser.scanner.ILexerLog;
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer;
@ -32,7 +34,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
* Base class for all non-preprocessor nodes in the AST.
*/
public abstract class ASTNode implements IASTNode {
protected static final ICPPFunction UNINITIALIZED_FUNCTION = new CPPFunction(null);
private static final IASTNodeLocation[] EMPTY_LOCATION_ARRAY = new IASTNodeLocation[0];
private IASTNode parent;

View file

@ -33,12 +33,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent {
private static final ICPPFunction UNINITIALIZED = new CPPFunction(null);
private int op;
private IASTExpression operand1;
private IASTExpression operand2;
private IType type;
private ICPPFunction overload= UNINITIALIZED;
private ICPPFunction overload= UNINITIALIZED_FUNCTION;
private IASTImplicitName[] implicitNames = null;
@ -166,7 +165,7 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
}
public ICPPFunction getOverload() {
if (overload != UNINITIALIZED)
if (overload != UNINITIALIZED_FUNCTION)
return overload;
return overload = CPPSemantics.findOverloadedOperator(this);

View file

@ -44,6 +44,8 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
private IASTExpression parameter;
private IASTImplicitName[] implicitNames = null;
private IType type; // cached type of expression
private ICPPFunction overload= UNINITIALIZED_FUNCTION;
public CPPASTFunctionCallExpression() {
@ -182,16 +184,23 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
}
public ICPPFunction getOperator() {
ICPPFunction[] overload = new ICPPFunction[] {null};
getExpressionType(overload);
return overload[0];
if (overload == UNINITIALIZED_FUNCTION) {
overload= null;
// as a side effect this computes the overload
getExpressionType();
}
return overload;
}
public IType getExpressionType() {
return getExpressionType(null);
if (type == null) {
type= computeExpressionType();
}
return type;
}
private IType getExpressionType(ICPPFunction[] overload) {
private IType computeExpressionType() {
overload= null;
try {
IType t= null;
if (functionName instanceof IASTIdExpression) {
@ -224,8 +233,8 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
if (op != null) {
// overload can be a surrogate function call, which consists of a conversion and a call to
// a dynamically computed function pointer.
if(overload != null && !(op instanceof CPPImplicitFunction))
overload[0] = op;
if(!(op instanceof CPPImplicitFunction))
overload = op;
return op.getType().getReturnType();
}
} else if (t instanceof IPointerType) {

View file

@ -47,11 +47,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
* Unary expression in c++
*/
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
private static final ICPPFunction UNINITIALIZED = new CPPFunction(null);
private int op;
private IASTExpression operand;
private ICPPFunction overload = UNINITIALIZED;
private ICPPFunction overload = UNINITIALIZED_FUNCTION;
private IASTImplicitName[] implicitNames = null;
public CPPASTUnaryExpression() {
@ -158,7 +157,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
public ICPPFunction getOverload() {
if (overload != UNINITIALIZED)
if (overload != UNINITIALIZED_FUNCTION)
return overload;
overload = CPPSemantics.findOverloadedOperator(this);