From ebe2158c23aa1bed2713f0a6b92ee48973d9586c Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 20 Jun 2007 07:05:13 +0000 Subject: [PATCH] Fix for 189299, stack overflow in name resolution, 2nd attempt. --- .../core/dom/parser/cpp/CPPASTName.java | 4 ++-- .../core/dom/parser/cpp/CPPASTTemplateId.java | 19 ++++++++++++++----- .../core/dom/parser/cpp/CPPVisitor.java | 3 +++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java index 23767087098..a34e62ba801 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java @@ -31,7 +31,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; * @author jcamelon */ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionContext { - private final static class RecursionResolvingBinding extends ProblemBinding { + final static class RecursionResolvingBinding extends ProblemBinding { public RecursionResolvingBinding() { super(null, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, CharArrayUtils.EMPTY); } @@ -45,7 +45,7 @@ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionCo private static final char[] EMPTY_CHAR_ARRAY = {}; private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - private static final int MAX_RESOLUTION_DEPTH = 5; + static final int MAX_RESOLUTION_DEPTH = 5; private IBinding binding = null; private int fResolutionDepth= 0; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java index d58f66c706b..a395d42ea63 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java @@ -66,17 +66,20 @@ public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId, I private IASTNode [] templateArguments = null; private IBinding binding = null; - private boolean resolving = false; + private int fResolutionDepth= 0; /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTName#resolveBinding() */ public IBinding resolveBinding() { - if (binding == null && !resolving) { + if (binding == null) { // protect for infinite recursion - resolving = true; - binding = CPPTemplates.createBinding( this ); - resolving = false; + if (++fResolutionDepth > CPPASTName.MAX_RESOLUTION_DEPTH) { + binding= new CPPASTName.RecursionResolvingBinding(this); + } + else { + binding = CPPTemplates.createBinding( this ); + } } return binding; @@ -155,6 +158,7 @@ public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId, I */ public void setBinding(IBinding binding) { this.binding = binding; + fResolutionDepth= 0; } public void replace(IASTNode child, IASTNode other) { @@ -178,4 +182,9 @@ public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId, I return false; } + public void incResolutionDepth() { + if (binding == null && ++fResolutionDepth > CPPASTName.MAX_RESOLUTION_DEPTH) { + binding= new CPPASTName.RecursionResolvingBinding(this); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 420cb2eccdf..a0bf57c3354 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -996,6 +996,9 @@ public class CPPVisitor { if (name instanceof CPPASTName) { ((CPPASTName) name).incResolutionDepth(); } + else if (name instanceof CPPASTTemplateId) { + ((CPPASTTemplateId) name).incResolutionDepth(); + } IBinding binding = name.getBinding(); if( binding == null ){ binding = CPPSemantics.resolveBinding( name );