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 111203a785d..eae38c57ac0 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 @@ -13342,4 +13342,30 @@ public class AST2CPPTests extends AST2CPPTestBase { BindingAssertionHelper helper = getAssertionHelper(); helper.assertVariableValue("is_not_noexcept", 0); } + + // struct B{ + // B a; + // }; + // B t{1}; + public void testSelfAggregation_546805() throws Exception { + // Note that ideally we would report an error already on the declaration of B as + // the class is aggregating itself. Today, we only report an error because of a + // wrong constructor argument. + BindingAssertionHelper bh = getAssertionHelper(); + bh.assertImplicitName("t{1};", 1, IProblemBinding.class); + } + + // struct B; + // struct A{ + // B b; + // }; + // struct B{ + // A a; + // }; + // B t{1}; + public void testIndirectSelfAggregation_546805() throws Exception { + // See comment in previous test + BindingAssertionHelper bh = getAssertionHelper(); + bh.assertImplicitName("t{1};", 1, IProblemBinding.class); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java index 9397d19ee41..35b839e671f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java @@ -128,7 +128,7 @@ class AggregateInitialization { * checkElement() for each element of an array or each field of a class aggregate. */ private Cost checkInitializationOfElements(IType type, Cost worstCost) throws DOMException { - if (type instanceof ICPPClassType && TypeTraits.isAggregateClass((ICPPClassType) type)) { + if (type instanceof ICPPClassType && isAggregate(type)) { ICPPField[] fields = getFieldsForAggregateInitialization((ICPPClassType) type); for (ICPPField field : fields) { Cost cost = checkElement(field.getType(), field.getInitialValue(), worstCost); @@ -180,8 +180,25 @@ class AggregateInitialization { } private static boolean isAggregate(IType type) { - return (type instanceof ICPPClassType && TypeTraits.isAggregateClass((ICPPClassType) type)) - || type instanceof IArrayType; + return (type instanceof ICPPClassType && TypeTraits.isAggregateClass((ICPPClassType) type) + && !isSelfAggregate((ICPPClassType) type, null)) || type instanceof IArrayType; + } + + // Check if a class is (illegally) aggregating itself + private static boolean isSelfAggregate(ICPPClassType type, ICPPClassType subType) { + if (type.isSameType(subType)) + return true; + + if (subType == null) + subType = type; + for (ICPPField field : subType.getDeclaredFields()) { + IType fieldType = field.getType(); + if (fieldType instanceof ICPPClassType && TypeTraits.isAggregateClass((ICPPClassType) fieldType)) { + if (isSelfAggregate(type, (ICPPClassType) fieldType)) + return true; + } + } + return false; } /**