mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-09 01:05:38 +02:00
Exponential complexity resolving overloaded function calls, bug 283324.
This commit is contained in:
parent
448fec099f
commit
7768ee8e9e
5 changed files with 42 additions and 14 deletions
|
@ -7267,4 +7267,23 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
final String code = getAboveComment();
|
final String code = getAboveComment();
|
||||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
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.IToken;
|
||||||
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
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.ILexerLog;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
|
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer;
|
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.
|
* Base class for all non-preprocessor nodes in the AST.
|
||||||
*/
|
*/
|
||||||
public abstract class ASTNode implements IASTNode {
|
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 static final IASTNodeLocation[] EMPTY_LOCATION_ARRAY = new IASTNodeLocation[0];
|
||||||
|
|
||||||
private IASTNode parent;
|
private IASTNode parent;
|
||||||
|
|
|
@ -33,12 +33,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
|
|
||||||
public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent {
|
public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent {
|
||||||
private static final ICPPFunction UNINITIALIZED = new CPPFunction(null);
|
|
||||||
private int op;
|
private int op;
|
||||||
private IASTExpression operand1;
|
private IASTExpression operand1;
|
||||||
private IASTExpression operand2;
|
private IASTExpression operand2;
|
||||||
private IType type;
|
private IType type;
|
||||||
private ICPPFunction overload= UNINITIALIZED;
|
private ICPPFunction overload= UNINITIALIZED_FUNCTION;
|
||||||
private IASTImplicitName[] implicitNames = null;
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,7 +165,7 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICPPFunction getOverload() {
|
public ICPPFunction getOverload() {
|
||||||
if (overload != UNINITIALIZED)
|
if (overload != UNINITIALIZED_FUNCTION)
|
||||||
return overload;
|
return overload;
|
||||||
|
|
||||||
return overload = CPPSemantics.findOverloadedOperator(this);
|
return overload = CPPSemantics.findOverloadedOperator(this);
|
||||||
|
|
|
@ -44,6 +44,8 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
private IASTExpression parameter;
|
private IASTExpression parameter;
|
||||||
|
|
||||||
private IASTImplicitName[] implicitNames = null;
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
private IType type; // cached type of expression
|
||||||
|
private ICPPFunction overload= UNINITIALIZED_FUNCTION;
|
||||||
|
|
||||||
|
|
||||||
public CPPASTFunctionCallExpression() {
|
public CPPASTFunctionCallExpression() {
|
||||||
|
@ -182,16 +184,23 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICPPFunction getOperator() {
|
public ICPPFunction getOperator() {
|
||||||
ICPPFunction[] overload = new ICPPFunction[] {null};
|
if (overload == UNINITIALIZED_FUNCTION) {
|
||||||
getExpressionType(overload);
|
overload= null;
|
||||||
return overload[0];
|
// as a side effect this computes the overload
|
||||||
|
getExpressionType();
|
||||||
|
}
|
||||||
|
return overload;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IType getExpressionType() {
|
public IType getExpressionType() {
|
||||||
return getExpressionType(null);
|
if (type == null) {
|
||||||
|
type= computeExpressionType();
|
||||||
|
}
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IType getExpressionType(ICPPFunction[] overload) {
|
private IType computeExpressionType() {
|
||||||
|
overload= null;
|
||||||
try {
|
try {
|
||||||
IType t= null;
|
IType t= null;
|
||||||
if (functionName instanceof IASTIdExpression) {
|
if (functionName instanceof IASTIdExpression) {
|
||||||
|
@ -224,8 +233,8 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
if (op != null) {
|
if (op != null) {
|
||||||
// overload can be a surrogate function call, which consists of a conversion and a call to
|
// overload can be a surrogate function call, which consists of a conversion and a call to
|
||||||
// a dynamically computed function pointer.
|
// a dynamically computed function pointer.
|
||||||
if(overload != null && !(op instanceof CPPImplicitFunction))
|
if(!(op instanceof CPPImplicitFunction))
|
||||||
overload[0] = op;
|
overload = op;
|
||||||
return op.getType().getReturnType();
|
return op.getType().getReturnType();
|
||||||
}
|
}
|
||||||
} else if (t instanceof IPointerType) {
|
} else if (t instanceof IPointerType) {
|
||||||
|
|
|
@ -47,11 +47,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
* Unary expression in c++
|
* Unary expression in c++
|
||||||
*/
|
*/
|
||||||
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
|
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
|
||||||
private static final ICPPFunction UNINITIALIZED = new CPPFunction(null);
|
|
||||||
private int op;
|
private int op;
|
||||||
private IASTExpression operand;
|
private IASTExpression operand;
|
||||||
|
|
||||||
private ICPPFunction overload = UNINITIALIZED;
|
private ICPPFunction overload = UNINITIALIZED_FUNCTION;
|
||||||
private IASTImplicitName[] implicitNames = null;
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
public CPPASTUnaryExpression() {
|
public CPPASTUnaryExpression() {
|
||||||
|
@ -158,7 +157,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
|
|
||||||
|
|
||||||
public ICPPFunction getOverload() {
|
public ICPPFunction getOverload() {
|
||||||
if (overload != UNINITIALIZED)
|
if (overload != UNINITIALIZED_FUNCTION)
|
||||||
return overload;
|
return overload;
|
||||||
|
|
||||||
overload = CPPSemantics.findOverloadedOperator(this);
|
overload = CPPSemantics.findOverloadedOperator(this);
|
||||||
|
|
Loading…
Add table
Reference in a new issue