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 0194f2664b9..5279ba4925e 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 @@ -9306,4 +9306,15 @@ public class AST2CPPTests extends AST2BaseTest { parseAndCheckBindings(); } + // struct S { + // void f(); + // }; + // void g() { + // S array[5]; + // for (auto& s : array) + // s.f(); // ERROR HERE + // } + public void testAutoTypeInRangeBasedFor_332883() throws Exception { + parseAndCheckBindings(); + } } 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 109b4d218c1..6bb3f274196 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 @@ -1748,7 +1748,7 @@ public class CPPVisitor extends ASTQueries { if (declarator instanceof ICPPASTFunctionDeclarator) { return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator); } - + boolean rangeBasedFor= false; parent = parent.getParent(); if (parent instanceof ICPPASTNewExpression) { IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer(); @@ -1758,12 +1758,16 @@ public class CPPVisitor extends ASTQueries { initClause = arguments[0]; } } + } else if (parent instanceof ICPPASTRangeBasedForStatement) { + ICPPASTRangeBasedForStatement forStmt= (ICPPASTRangeBasedForStatement) parent; + initClause= forStmt.getInitializerClause(); + rangeBasedFor= true; } 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); } - return createAutoType(initClause, declSpec, declarator); + return createAutoType(initClause, declSpec, declarator, rangeBasedFor); } IType type = createType(declSpec); @@ -1786,7 +1790,8 @@ public class CPPVisitor extends ASTQueries { return type; } - private static IType createAutoType(IASTNode initClause, IASTDeclSpecifier declSpec, IASTDeclarator declarator) { + private static IType createAutoType(IASTNode initClause, IASTDeclSpecifier declSpec, IASTDeclarator declarator, + boolean rangeBasedFor) { // C++0x: 7.1.6.4 if (!autoTypeDeclSpecs.get().add(declSpec)) { // Detected a self referring auto type, e.g.: auto x = x; @@ -1837,6 +1842,14 @@ public class CPPVisitor extends ASTQueries { type = (IType) CPPTemplates.instantiate(initializer_list_template, new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, true); } + if (rangeBasedFor) { + if (type instanceof IArrayType) { + type= ((IArrayType) type).getType(); + } else { + // todo: handle non-array types in for based range loops + // (c++-spec 6.5.4): 'typeof (* begin(type &&))' + } + } return decorateType(type, declSpec, declarator); }