1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-30 20:35:38 +02:00

Bug 546805 - Infinite recursion in self-aggregation

Protects for infinite recursion in case the type (illegally) aggregates itself.

Change-Id: I2e70f85a73b3d2ed6fec432fa2f768f2bcf8d1bf
Signed-off-by: Hannes Vogt <hannes@havogt.de>
This commit is contained in:
Hannes Vogt 2019-04-30 08:26:20 +02:00
parent f938b4d08e
commit 1cd0e1df35
2 changed files with 46 additions and 3 deletions

View file

@ -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);
}
}

View file

@ -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;
}
/**