From 0a634c54feb4b82d2dab5eddefa5511eed78e4bd Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Mon, 22 Mar 2010 22:23:22 +0000 Subject: [PATCH] Fixed stack overflow while processing invalid self-referring auto-type declarations. Bug 305970. --- .../core/parser/tests/ast2/AST2CPPTests.java | 10 +++- .../dom/parser/cpp/semantics/CPPVisitor.java | 58 +++++++++++++------ 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 2cb8f63ff45..bcdcb8d438e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -8320,7 +8320,15 @@ public class AST2CPPTests extends AST2BaseTest { ICPPVariable y= bh.assertNonProblem("y =", 1); assertNull(y.getType()); } - + + // auto x = x; // Self referring type. + public void testAutoType_305970() throws Exception { + String code= getAboveComment(); + BindingAssertionHelper bh= new BindingAssertionHelper(code, true); + ICPPVariable x= bh.assertNonProblem("x =", 1); + assertNull(x.getType()); + } + // auto fpif1(int)->int(*)(int) // auto fpif2(int)->int(*)(int) {} public void testNewFunctionDeclaratorSyntax_305972() throws Exception { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 0823ef86f3a..e865c11418a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -16,6 +16,8 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import java.util.BitSet; +import java.util.HashSet; +import java.util.Set; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -188,6 +190,16 @@ public class CPPVisitor extends ASTQueries { public static final String STD = "std"; //$NON-NLS-1$ public static final String TYPE_INFO= "type_info"; //$NON-NLS-1$ private static final String INITIALIZER_LIST = "initializer_list"; //$NON-NLS-1$ + // Thread-local set of DeclSpecifiers for which auto types are being created. + // Used for preventing infinite recursion while processing invalid self-referring + // auto-type declarations. + private static final ThreadLocal> autoTypeDeclSpecs = + new ThreadLocal>() { + @Override + protected Set initialValue() { + return new HashSet(); + } + }; public static IBinding createBinding(IASTName name) { IASTNode parent = name.getParent(); @@ -1476,8 +1488,7 @@ public class CPPVisitor extends ASTQueries { private static final int KIND_TYPE = 3; private static final int KIND_NAMESPACE = 4; private static final int KIND_COMPOSITE = 5; - - + public CollectReferencesAction(IBinding binding) { shouldVisitNames = true; this.refs = new IASTName[DEFAULT_LIST_SIZE]; @@ -1817,27 +1828,36 @@ public class CPPVisitor extends ASTQueries { if (declarator instanceof ICPPASTFunctionDeclarator) { return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator); } - + + if (!autoTypeDeclSpecs.get().add(declSpec)) { + // Detected a self referring auto type, e.g.: auto x = x; + return null; + } + IType type = AutoTypeResolver.AUTO_TYPE; + IType initType = null; ICPPClassTemplate initializer_list_template = null; - if (initClause instanceof ICPPASTInitializerList) { - initializer_list_template = get_initializer_list(declSpec); - if (initializer_list_template == null) { + try { + if (initClause instanceof ICPPASTInitializerList) { + initializer_list_template = get_initializer_list(declSpec); + if (initializer_list_template == null) { + return null; + } + type = (IType) CPPTemplates.instantiate(initializer_list_template, + new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, true); + } + type = decorateType(type, declSpec, declarator); + + if (initClause instanceof IASTExpression) { + initType = ((IASTExpression) initClause).getExpressionType(); + } else if (initClause instanceof ICPPASTInitializerList) { + initType = new InitializerListType((ICPPASTInitializerList) initClause); + } + if (initType == null) { return null; } - type = (IType) CPPTemplates.instantiate(initializer_list_template, - new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, true); - } - type = decorateType(type, declSpec, declarator); - - IType initType = null; - if (initClause instanceof IASTExpression) { - initType = ((IASTExpression) initClause).getExpressionType(); - } else if (initClause instanceof ICPPASTInitializerList) { - initType = new InitializerListType((ICPPASTInitializerList) initClause); - } - if (initType == null) { - return null; + } finally { + autoTypeDeclSpecs.get().remove(declSpec); } ICPPFunctionTemplate template = new AutoTypeResolver(type); CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1);