aBothe / D_Parser

Parser & Resolver & Abstract Completion library for D
Other
30 stars 7 forks source link

Stack overflow in Visual D's D_parser component #195

Open rainers opened 8 years ago

rainers commented 8 years ago

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.]

rainers commented 8 years ago

I can reproduce it now with just this code:

void foo()
{
    Object o;
    o. // invoke completion list after dot => crash
}
aBothe commented 8 years ago

So it basically wants to

Gotta have a look where to build in the SO check.

rainers commented 8 years ago

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#
thedeemon commented 8 years ago

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#
aBothe commented 8 years ago

@rainers The SO part should be resolved now. Still, it does not compare method parameter types atm.

rainers commented 8 years ago

@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).