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:
parent
b7807b8a16
commit
8a97926f2b
3 changed files with 97 additions and 85 deletions
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue