1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fixed StackOverflowError in auto type calculation for "for (auto a : a)"

This commit is contained in:
Sergey Prigogin 2012-12-05 19:22:08 -08:00
parent b7807b8a16
commit 8a97926f2b
3 changed files with 97 additions and 85 deletions

View file

@ -713,19 +713,20 @@ public class AST2BaseTest extends BaseTestCase {
} }
private IBinding binding(String section, int len) { private IBinding binding(String section, int len) {
IASTName name = findName(section, len); IASTName astName = findName(section, len);
final String selection = section.substring(0, len); final String selection = section.substring(0, len);
assertNotNull("Did not find \"" + selection + "\"", name); assertNotNull("No AST name for \"" + selection + "\"", astName);
assertEquals(selection, name.getRawSignature()); assertEquals(selection, astName.getRawSignature());
IBinding binding = name.resolveBinding(); IBinding binding = astName.resolveBinding();
assertNotNull("No binding for " + name.getRawSignature(), binding); assertNotNull("No binding for " + astName.getRawSignature(), binding);
return name.resolveBinding(); return astName.resolveBinding();
} }
private IBinding binding(String context, String name) { private IBinding binding(String context, String name) {
IASTName astName = findName(context, name); IASTName astName = findName(context, name);
assertNotNull("No AST name for \"" + name + "\"", astName);
assertEquals(name, astName.getRawSignature()); assertEquals(name, astName.getRawSignature());
IBinding binding = astName.resolveBinding(); IBinding binding = astName.resolveBinding();

View file

@ -8436,13 +8436,20 @@ public class AST2CPPTests extends AST2BaseTest {
assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE, pt.getID()); assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE, pt.getID());
} }
// auto x = x; // Self referring type. // auto x = y + z;
// auto y = x;
// auto z = x;
// void test() {
// for (auto a : a) {}
// }
public void testAutoType_305970() throws Exception { public void testAutoType_305970() throws Exception {
String code= getAboveComment(); BindingAssertionHelper bh = getAssertionHelper();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true); ICPPVariable x= bh.assertNonProblem("x =", 1, ICPPVariable.class);
ICPPVariable x= bh.assertNonProblem("x =", 1); IProblemType xt= (IProblemType) x.getType();
IProblemType pt= (IProblemType) x.getType(); assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE, xt.getID());
assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE, pt.getID()); ICPPVariable a= bh.assertNonProblem("a :", "a", ICPPVariable.class);
IProblemType at= (IProblemType) a.getType();
assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE, at.getID());
} }
// struct A { auto a = 1; }; // Auto-typed non-static fields are not allowed. // struct A { auto a = 1; }; // Auto-typed non-static fields are not allowed.

View file

@ -1980,71 +1980,79 @@ public class CPPVisitor extends ASTQueries {
return type; return type;
} }
private static IType createAutoType(IASTDeclSpecifier declSpec, IASTDeclarator declarator) { private static IType createAutoType(final IASTDeclSpecifier declSpec, IASTDeclarator declarator) {
if (declarator instanceof ICPPASTFunctionDeclarator) { Set<IASTDeclSpecifier> recursionProtectionSet = autoTypeDeclSpecs.get();
return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator); try {
} if (!recursionProtectionSet.add(declSpec)) {
ICPPASTInitializerClause autoInitClause= null; // Detected a self referring auto type, e.g.: auto x = x;
IASTNode parent = declarator.getParent().getParent(); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
if (parent instanceof ICPPASTNewExpression) {
IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer();
if (initializer != null) {
IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments();
if (arguments.length == 1) {
autoInitClause = (ICPPASTInitializerClause) arguments[0];
}
} }
} else if (parent instanceof ICPPASTRangeBasedForStatement) { if (declarator instanceof ICPPASTFunctionDeclarator) {
// See 6.5.4 The range-based for statement [stmt.ranged] return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator);
ICPPASTRangeBasedForStatement forStmt= (ICPPASTRangeBasedForStatement) parent;
IASTInitializerClause forInit = forStmt.getInitializerClause();
IASTExpression beginExpr= null;
if (forInit instanceof IASTExpression) {
final IASTExpression expr = (IASTExpression) forInit;
IType type= SemanticUtil.getNestedType(expr.getExpressionType(), TDEF | CVTYPE);
if (type instanceof IArrayType) {
beginExpr= expr.copy();
}
} }
if (beginExpr == null) { ICPPASTInitializerClause autoInitClause= null;
IASTImplicitName[] implicits= forStmt.getImplicitNames(); IASTNode parent = declarator.getParent().getParent();
if (implicits.length > 0) { if (parent instanceof ICPPASTNewExpression) {
IBinding b= implicits[0].getBinding(); IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer();
CPPASTName name= new CPPASTName(); if (initializer != null) {
name.setBinding(b); IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments();
if (b instanceof ICPPMethod && forInit instanceof IASTExpression) { if (arguments.length == 1) {
beginExpr= new CPPASTFunctionCallExpression( autoInitClause = (ICPPASTInitializerClause) arguments[0];
new CPPASTFieldReference(name, (IASTExpression) forInit.copy()), NO_ARGS);
} else {
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS);
} }
} else { }
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); } else if (parent instanceof ICPPASTRangeBasedForStatement) {
// See 6.5.4 The range-based for statement [stmt.ranged]
ICPPASTRangeBasedForStatement forStmt= (ICPPASTRangeBasedForStatement) parent;
IASTInitializerClause forInit = forStmt.getInitializerClause();
IASTExpression beginExpr= null;
if (forInit instanceof IASTExpression) {
final IASTExpression expr = (IASTExpression) forInit;
IType type= SemanticUtil.getNestedType(expr.getExpressionType(), TDEF | CVTYPE);
if (type instanceof IArrayType) {
beginExpr= expr.copy();
}
}
if (beginExpr == null) {
IASTImplicitName[] implicits= forStmt.getImplicitNames();
if (implicits.length > 0) {
IBinding b= implicits[0].getBinding();
CPPASTName name= new CPPASTName();
name.setBinding(b);
if (b instanceof ICPPMethod && forInit instanceof IASTExpression) {
beginExpr= new CPPASTFunctionCallExpression(
new CPPASTFieldReference(name, (IASTExpression) forInit.copy()), NO_ARGS);
} else {
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS);
}
} else {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
}
}
autoInitClause= new CPPASTUnaryExpression(IASTUnaryExpression.op_star, beginExpr);
autoInitClause.setParent(forStmt);
autoInitClause.setPropertyInParent(ICPPASTRangeBasedForStatement.INITIALIZER);
} else if (parent instanceof IASTCompositeTypeSpecifier &&
declSpec.getStorageClass() != IASTDeclSpecifier.sc_static) {
// Non-static auto-typed class members are not allowed.
return new ProblemType(ISemanticProblem.TYPE_AUTO_FOR_NON_STATIC_FIELD);
} else {
IASTInitializer initClause= declarator.getInitializer();
if (initClause instanceof IASTEqualsInitializer) {
autoInitClause= (ICPPASTInitializerClause) ((IASTEqualsInitializer) initClause).getInitializerClause();
} else if (initClause instanceof ICPPASTInitializerClause) {
autoInitClause= (ICPPASTInitializerClause) initClause;
} }
} }
autoInitClause= new CPPASTUnaryExpression(IASTUnaryExpression.op_star, beginExpr); return createAutoType(autoInitClause, declSpec, declarator);
autoInitClause.setParent(forStmt); } finally {
autoInitClause.setPropertyInParent(ICPPASTRangeBasedForStatement.INITIALIZER); recursionProtectionSet.remove(declSpec);
} else if (parent instanceof IASTCompositeTypeSpecifier &&
declSpec.getStorageClass() != IASTDeclSpecifier.sc_static) {
// Non-static auto-typed class members are not allowed.
return new ProblemType(ISemanticProblem.TYPE_AUTO_FOR_NON_STATIC_FIELD);
} else {
IASTInitializer initClause= declarator.getInitializer();
if (initClause instanceof IASTEqualsInitializer) {
autoInitClause= (ICPPASTInitializerClause) ((IASTEqualsInitializer) initClause).getInitializerClause();
} else if (initClause instanceof ICPPASTInitializerClause) {
autoInitClause= (ICPPASTInitializerClause) initClause;
}
} }
return createAutoType(autoInitClause, declSpec, declarator);
} }
private static IType createAutoType(ICPPASTInitializerClause initClause, IASTDeclSpecifier declSpec, private static IType createAutoType(ICPPASTInitializerClause initClause, IASTDeclSpecifier declSpec,
IASTDeclarator declarator) { IASTDeclarator declarator) {
// C++0x: 7.1.6.4 // C++0x: 7.1.6.4
if (initClause == null || !autoTypeDeclSpecs.get().add(declSpec)) { if (initClause == null) {
// Detected a self referring auto type, e.g.: auto x = x;
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
} }
@ -2052,27 +2060,23 @@ public class CPPVisitor extends ASTQueries {
IType initType = null; IType initType = null;
ValueCategory valueCat= null; ValueCategory valueCat= null;
ICPPClassTemplate initializer_list_template = null; ICPPClassTemplate initializer_list_template = null;
try { if (initClause instanceof ICPPASTInitializerList) {
if (initClause instanceof ICPPASTInitializerList) { initializer_list_template = get_initializer_list(declSpec);
initializer_list_template = get_initializer_list(declSpec); if (initializer_list_template == null) {
if (initializer_list_template == null) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
}
type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateTypeArgument(type) }, initClause);
if (type instanceof IProblemBinding) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
}
}
type = decorateType(type, declSpec, declarator);
final ICPPEvaluation evaluation = initClause.getEvaluation();
initType= evaluation.getTypeOrFunctionSet(declarator);
valueCat= evaluation.getValueCategory(declarator);
if (initType == null) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
} }
} finally { type = (IType) CPPTemplates.instantiate(initializer_list_template,
autoTypeDeclSpecs.get().remove(declSpec); new ICPPTemplateArgument[] { new CPPTemplateTypeArgument(type) }, initClause);
if (type instanceof IProblemBinding) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
}
}
type = decorateType(type, declSpec, declarator);
final ICPPEvaluation evaluation = initClause.getEvaluation();
initType= evaluation.getTypeOrFunctionSet(declarator);
valueCat= evaluation.getValueCategory(declarator);
if (initType == null || initType instanceof ISemanticProblem) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
} }
ICPPFunctionTemplate template = new AutoTypeResolver(type); ICPPFunctionTemplate template = new AutoTypeResolver(type);
CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1); CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1);