mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-01 13:25:45 +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();
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
helper.assertVariableValue("is_not_noexcept", 0);
|
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.
|
* checkElement() for each element of an array or each field of a class aggregate.
|
||||||
*/
|
*/
|
||||||
private Cost checkInitializationOfElements(IType type, Cost worstCost) throws DOMException {
|
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);
|
ICPPField[] fields = getFieldsForAggregateInitialization((ICPPClassType) type);
|
||||||
for (ICPPField field : fields) {
|
for (ICPPField field : fields) {
|
||||||
Cost cost = checkElement(field.getType(), field.getInitialValue(), worstCost);
|
Cost cost = checkElement(field.getType(), field.getInitialValue(), worstCost);
|
||||||
|
@ -180,8 +180,25 @@ class AggregateInitialization {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isAggregate(IType type) {
|
private static boolean isAggregate(IType type) {
|
||||||
return (type instanceof ICPPClassType && TypeTraits.isAggregateClass((ICPPClassType) type))
|
return (type instanceof ICPPClassType && TypeTraits.isAggregateClass((ICPPClassType) type)
|
||||||
|| type instanceof IArrayType;
|
&& !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