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:
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();
|
||||
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.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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue