D_Parser
D_Parser copied to clipboard
Stack overflow in Visual D's D_parser component
There have been a number of reports about stack overflow errors in DParserCOMServer, Visual D's D_Parser process, e.g. https://issues.dlang.org/show_bug.cgi?id=15458
I could reproduce the issue in the bug report (not in the debug version, I guess the analyzer timeout kicks in before the stack overflow occurs), but debugging the release build shows that D_Parser is trying to evaluate the return type of object.opEquals.
Here is a snippet of the current definition:
auto opEquals(Object lhs, Object rhs)
{
// special cases here...
// General case => symmetric calls to method opEquals
return lhs.opEquals(rhs) && rhs.opEquals(lhs);
}
auto opEquals(const Object lhs, const Object rhs)
{
return opEquals(cast()lhs, cast()rhs);
}
I suspect that return opEquals(cast()lhs, cast()rhs);
matches both calls, with the first not considered "better" after casting away const
. So the evaluation recurses endlessly.
[Even if the function matching is fixed, I guess there should be a recursion check somewhere.]
I can reproduce it now with just this code:
void foo()
{
Object o;
o. // invoke completion list after dot => crash
}
So it basically wants to
- resolve opEquals' return type and therefore
- evaluates the
- first resturn statements expression, then
- getting both opEquals-overloads again,
- whereas the first overload actually might be resolved again - applying the same tuple of arguments
Gotta have a look where to build in the SO check.
Yes, sounds about right. It seemed to me it is always just spinning on the second overload. It's evaluating the return statement with the casts.
FWIW here's an ever repeating snapshot of the stack:
D_Parser.dll!D_Parser.Resolver.TypeResolution.TypeDeclarationResolver.GetMethodReturnType(D_Parser.Dom.DMethod method, D_Parser.Resolver.ResolutionContext ctxt) Line 940 C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.HandleDMethodOverload(D_Parser.Resolver.ResolutionContext ctxt, bool eval, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, bool returnBaseTypeOnly, System.Collections.Generic.List<D_Parser.Resolver.AbstractType> argTypeFilteredOverloads, ref bool hasHandledUfcsResultBefore, D_Parser.Resolver.MemberSymbol ms, ref D_Parser.Resolver.AbstractType untemplatedMethod) Line 365 C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.EvalMethodCall(D_Parser.Resolver.AbstractType[] baseExpression, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, D_Parser.Dom.Expressions.TemplateInstanceExpression tix, D_Parser.Resolver.ResolutionContext ctxt, D_Parser.Dom.Expressions.PostfixExpression_MethodCall call, out System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, out D_Parser.Resolver.ExpressionSemantics.ISymbolValue delegateValue, bool returnBaseTypeOnly, D_Parser.Resolver.ExpressionSemantics.AbstractSymbolValueProvider ValueProvider) Line 229 C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.Visit(D_Parser.Dom.Expressions.PostfixExpression_MethodCall call) Line 109 C#
D_Parser.dll!D_Parser.Dom.Expressions.PostfixExpression_MethodCall.Accept<D_Parser.Resolver.AbstractType>(D_Parser.Dom.ExpressionVisitor<D_Parser.Resolver.AbstractType> vis) Line 65 C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.EvaluateType(D_Parser.Dom.Expressions.IExpression x, D_Parser.Resolver.ResolutionContext ctxt, bool tryReturnMethodReturnType) Line 85 C#
D_Parser.dll!D_Parser.Resolver.TypeResolution.TypeDeclarationResolver.GetMethodReturnType(D_Parser.Dom.DMethod method, D_Parser.Resolver.ResolutionContext ctxt) Line 940 C#
Yep, this is the repeating pattern I get in stack overflow crashes:
D_Parser.dll!D_Parser.Dom.Expressions.PostfixExpression_MethodCall.Accept<D_Parser.Resolver.AbstractType>(D_Parser.Dom.ExpressionVisitor<D_Parser.Resolver.AbstractType> vis) Line 65 + 0x1d bytes C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.EvaluateType(D_Parser.Dom.Expressions.IExpression x, D_Parser.Resolver.ResolutionContext ctxt, bool tryReturnMethodReturnType) Line 85 + 0x5b bytes C#
D_Parser.dll!D_Parser.Resolver.TypeResolution.TypeDeclarationResolver.GetMethodReturnType(D_Parser.Dom.DMethod method, D_Parser.Resolver.ResolutionContext ctxt) Line 940 + 0x16 bytes C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.HandleDMethodOverload(D_Parser.Resolver.ResolutionContext ctxt, bool eval, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, bool returnBaseTypeOnly, System.Collections.Generic.List<D_Parser.Resolver.AbstractType> argTypeFilteredOverloads, ref bool hasHandledUfcsResultBefore, D_Parser.Resolver.MemberSymbol ms, ref D_Parser.Resolver.AbstractType untemplatedMethod) Line 365 + 0xa bytes C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.EvalMethodCall(D_Parser.Resolver.AbstractType[] baseExpression, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, D_Parser.Dom.Expressions.TemplateInstanceExpression tix, D_Parser.Resolver.ResolutionContext ctxt, D_Parser.Dom.Expressions.PostfixExpression_MethodCall call, out System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, out D_Parser.Resolver.ExpressionSemantics.ISymbolValue delegateValue, bool returnBaseTypeOnly, D_Parser.Resolver.ExpressionSemantics.AbstractSymbolValueProvider ValueProvider) Line 229 + 0x3b bytes C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.Visit(D_Parser.Dom.Expressions.PostfixExpression_MethodCall call) Line 109 + 0x6e bytes C#
D_Parser.dll!D_Parser.Dom.Expressions.PostfixExpression_MethodCall.Accept<D_Parser.Resolver.AbstractType>(D_Parser.Dom.ExpressionVisitor<D_Parser.Resolver.AbstractType> vis) Line 65 + 0x1d bytes C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.EvaluateType(D_Parser.Dom.Expressions.IExpression x, D_Parser.Resolver.ResolutionContext ctxt, bool tryReturnMethodReturnType) Line 85 + 0x5b bytes C#
D_Parser.dll!D_Parser.Resolver.TypeResolution.TypeDeclarationResolver.GetMethodReturnType(D_Parser.Dom.DMethod method, D_Parser.Resolver.ResolutionContext ctxt) Line 940 + 0x16 bytes C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.HandleDMethodOverload(D_Parser.Resolver.ResolutionContext ctxt, bool eval, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, bool returnBaseTypeOnly, System.Collections.Generic.List<D_Parser.Resolver.AbstractType> argTypeFilteredOverloads, ref bool hasHandledUfcsResultBefore, D_Parser.Resolver.MemberSymbol ms, ref D_Parser.Resolver.AbstractType untemplatedMethod) Line 365 + 0xa bytes C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.Evaluation.EvalMethodCall(D_Parser.Resolver.AbstractType[] baseExpression, D_Parser.Resolver.ExpressionSemantics.ISymbolValue baseValue, D_Parser.Dom.Expressions.TemplateInstanceExpression tix, D_Parser.Resolver.ResolutionContext ctxt, D_Parser.Dom.Expressions.PostfixExpression_MethodCall call, out System.Collections.Generic.List<D_Parser.Resolver.ISemantic> callArguments, out D_Parser.Resolver.ExpressionSemantics.ISymbolValue delegateValue, bool returnBaseTypeOnly, D_Parser.Resolver.ExpressionSemantics.AbstractSymbolValueProvider ValueProvider) Line 229 + 0x3b bytes C#
D_Parser.dll!D_Parser.Resolver.ExpressionSemantics.ExpressionTypeEvaluation.Visit(D_Parser.Dom.Expressions.PostfixExpression_MethodCall call) Line 109 + 0x6e bytes C#
@rainers The SO part should be resolved now. Still, it does not compare method parameter types atm.
@aBothe Thanks. Works fine now.
I had to change the line https://github.com/aBothe/D_Parser/commit/56c57a7df31ca0965ccfe674fdb430d3ad134b65#diff-cac2168692965ba74c9fbdb7b584bdfdR153 as I'm still compiling with VS2013 (.?
is not supported).