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:
parent
f938b4d08e
commit
1cd0e1df35
2 changed files with 46 additions and 3 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue