Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java139
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java182
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java120
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java10
5 files changed, 347 insertions, 114 deletions
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 b32453e95e7..93aeab5dc0a 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
@@ -12843,11 +12843,150 @@ public class AST2CPPTests extends AST2CPPTestBase {
//
// int main() {
// type(1, 2);
+ // type{1, 2};
// type(other_type());
// }
public void testCtorWithWrongArguments_543913() throws Exception {
BindingAssertionHelper bh = getAssertionHelper();
bh.assertImplicitName("type(1, 2)", 4, IProblemBinding.class);
+ bh.assertImplicitName("type{1, 2}", 4, IProblemBinding.class);
bh.assertImplicitName("type(other_type())", 4, IProblemBinding.class);
}
+
+ // struct array{
+ // int data[1];
+ // };
+ //
+ // void foo(array) {}
+ //
+ // int main() {
+ // array{{1}};
+ // array{1};
+ // array a = {1};
+ // foo({1});
+ // foo({{1}});
+ // }
+ public void testBraceElisionForAggregateInit0_SimpleValid_543038() throws Exception {
+ parseAndCheckBindings();
+ }
+
+ // struct array{
+ // int data[1];
+ // };
+ //
+ // void foo(array) {}
+ //
+ // int main() {
+ // array{{1,2}};
+ // array{1,2};
+ // array a0 = {1,2};
+ // foo({1,2});
+ // foo({{1,2}});
+ // }
+ public void testBraceElisionForAggregateInit1_SimpleTooManyInitializers_543038() throws Exception {
+ BindingAssertionHelper bh = getAssertionHelper();
+ // bh.assertProblem("array{{1,2}}", 5); // TODO not implemented
+ // bh.assertProblem("array{1,2}", 5); // TODO not implemented
+ bh.assertImplicitName("a0", 2, IProblemBinding.class);
+ bh.assertProblem("foo({1,2})", 3);
+ bh.assertProblem("foo({{1,2}})", 3);
+ }
+
+ // struct level0{
+ // int a;
+ // int b;
+ // };
+ //
+ // struct level1{
+ // public:
+ // level1(level0 a): a(a){}
+ // private:
+ // level0 a;
+ // };
+ //
+ // struct level2{
+ // level1 data;
+ // };
+ //
+ // void foo(level2) {}
+ //
+ // int main() {
+ // level1{{1,2}}; // ok
+ // foo({level1{{1,2}}}); // ok
+ // level1{1,2}; // ERROR: calling level1 constructor, not aggregate init of level0
+ // foo({{{1,2,3}}}); // ERROR: not aggregate init
+ // }
+ public void testBraceElisionForAggregateInit2_WithNonAggregate_543038() throws Exception {
+ BindingAssertionHelper bh = getAssertionHelper();
+
+ bh.assertNonProblem("foo({level1{{1,2}}})", 3);
+
+ ICPPConstructor ctor = bh.assertNonProblem("level1(level0 a)", "level1");
+ ICPPASTSimpleTypeConstructorExpression typeConstructorExpr = bh.assertNode("level1{{1,2}};", "level1{{1,2}}");
+ IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) typeConstructorExpr).getImplicitNames();
+ assertEquals(ctor, implicitNames[0].resolveBinding());
+
+ bh.assertImplicitName("level1{1,2};", 6, IProblemBinding.class);
+ bh.assertProblem("foo({{{1,2,3}}}", 3);
+ }
+
+ // struct array2D{
+ // int data[2][3];
+ // };
+ //
+ // void foo(array2D) {}
+ //
+ // int main() {
+ // foo({{{1,2,3},{1,2,3}}}); // no elision
+ // foo({{1,2,3,1,2,3}}); // eliding one level
+ // foo({{1,2}}); // eliding one level, but with only 2 elements which seems to initialize the outer level
+ // foo({1,2,3,1,2,3}); // eliding all levels
+ // foo({{1,2,3},{1,2,3}}); // ERROR eliding outer-most is not allowed
+ // }
+ public void testBraceElisionForAggregateInit3_543038() throws Exception {
+ BindingAssertionHelper bh = getAssertionHelper();
+ bh.assertNonProblem("foo({{{1,2,3},{1,2,3}}});", 3);
+ bh.assertNonProblem("foo({{1,2,3,1,2,3}});", 3);
+ bh.assertNonProblem("foo({{1,2}});", 3);
+ bh.assertNonProblem("foo({1,2,3,1,2,3});", 3);
+ bh.assertProblem("foo({{1,2,3},{1,2,3}});", 3);
+ }
+
+ // struct type{
+ // type(int){};
+ // };
+ //
+ // struct array{
+ // type data[2];
+ // };
+ //
+ // void foo(array){}
+ //
+ // int main() {
+ // foo({type{1},type{2}});
+ // foo({type{1}}); // ERROR: type is not default constructible
+ // }
+ public void testBraceElisionForAggregateInit4_nonDefaultConstructible_543038() throws Exception {
+ BindingAssertionHelper bh = getAssertionHelper();
+ bh.assertNonProblem("foo({type{1},type{2}});", 3);
+ bh.assertProblem("foo({type{1}});", 3);
+ }
+
+ // struct array2D{
+ // int data[2][3];
+ // };
+ //
+ // void foo(array2D) {}
+ //
+ // int main() {
+ // foo({{{1,2,3},1,2,3}}); // ok: data[0] is initialized without elision, data[1] with elision
+ // foo({{1,2,3,{1,2,3}}}); // ok: data[1] is initialized without elision, data[0] with elision
+ // foo({{1,2,{1,2,3}}}); // ERROR: trying to initialize data[0][2] with {1,2,3}
+ // }
+ public void testBraceElisionForAggregateInit5_partlyEliding_543038() throws Exception {
+ BindingAssertionHelper bh = getAssertionHelper();
+ bh.assertNonProblem("foo({{{1,2,3},1,2,3}});", 3);
+ bh.assertNonProblem("foo({{1,2,3,{1,2,3}}});", 3);
+ bh.assertProblem("foo({{1,2,{1,2,3}}});", 3);
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
index 00ccb61ae42..6c2498d59e1 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
@@ -150,12 +150,18 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
@Override
public String getName() {
- return node instanceof IASTName ? new String(((IASTName) node).getSimpleID()) : CPPSemantics.EMPTY_NAME;
+ if (node instanceof IASTName)
+ return new String(((IASTName) node).getSimpleID());
+ else
+ return arg != null ? new String(arg) : CPPSemantics.EMPTY_NAME;
}
@Override
public char[] getNameCharArray() {
- return node instanceof IASTName ? ((IASTName) node).getSimpleID() : CharArrayUtils.EMPTY;
+ if (node instanceof IASTName)
+ return ((IASTName) node).getSimpleID();
+ else
+ return arg != null ? arg : CharArrayUtils.EMPTY;
}
@Override
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
new file mode 100644
index 00000000000..68401ab2834
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
+
+import org.eclipse.cdt.core.dom.ast.DOMException;
+import org.eclipse.cdt.core.dom.ast.IArrayType;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
+import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
+
+class AggregateInitialization {
+ private ICPPEvaluation[] fInitializers;
+ private int fIndex = 0;
+
+ /**
+ * Checks whether 'target' can be initialized from 'list' according to the rules for
+ * aggregate initialization ([dcl.init.aggr]).
+ */
+ public static Cost check(IType target, EvalInitList list) throws DOMException {
+ return new AggregateInitialization().checkImpl(target, list);
+ }
+
+ private AggregateInitialization() {
+ }
+
+ private Cost checkImpl(IType target, EvalInitList list) throws DOMException {
+ fInitializers = list.getClauses();
+ fIndex = 0;
+
+ Cost worstCost = new Cost(list.getType(), target, Rank.IDENTITY);
+
+ Cost cost = checkInitializationOfElements(target, worstCost);
+ if (!cost.converts())
+ return cost;
+
+ if (fIndex < fInitializers.length)
+ // p7: An initializer-list is ill-formed if the number of initializer-clauses exceeds
+ // the number of members to initialize.
+ return Cost.NO_CONVERSION;
+ else
+ return worstCost;
+ }
+
+ /**
+ * If no braces are elided, check initialization of element by taking the next clause from the EvalInitList,
+ * else recurses into the subaggregate.
+ */
+ private Cost checkElement(IType type, IValue initialValue, Cost worstCost) throws DOMException {
+ if (fIndex >= fInitializers.length)
+ // TODO for arrays we could short-circuit default init instead of trying to init each element
+ return checkInitializationFromDefaultMemberInitializer(type, initialValue, worstCost);
+ worstCost = new Cost(fInitializers[fIndex].getType(), type, Rank.IDENTITY);
+
+ if (fInitializers[fIndex].isInitializerList() || !isAggregate(type)) { // no braces are elided
+ // p3: The elements of the initializer list are taken as initializers for the elements
+ // of the aggregate, in order.
+ ICPPEvaluation initializer = fInitializers[fIndex];
+ fIndex++;
+ Cost cost = Conversions.checkImplicitConversionSequence(type, initializer.getType(),
+ initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY);
+ if (!cost.converts()) {
+ return cost;
+ }
+ // If the initializer-clause is an expression and a narrowing conversion is
+ // required to convert the expression, the program is ill-formed.
+ if (!(initializer instanceof EvalInitList) && cost.isNarrowingConversion()) {
+ return Cost.NO_CONVERSION;
+ }
+ if (cost.compareTo(worstCost) > 0) {
+ worstCost = cost;
+ }
+ } else { // braces are elided: need to check on subaggregates
+ Cost cost = checkInitializationOfElements(type, worstCost);
+ if (!cost.converts())
+ return cost;
+ if (cost.compareTo(worstCost) > 0) {
+ worstCost = cost;
+ }
+ }
+ return worstCost;
+ }
+
+ /**
+ * 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)) {
+ ICPPField[] fields = getFieldsForAggregateInitialization((ICPPClassType) type);
+ for (ICPPField field : fields) {
+ Cost cost = checkElement(field.getType(), field.getInitialValue(), worstCost);
+ if (!cost.converts())
+ return cost;
+ if (cost.compareTo(worstCost) > 0) {
+ worstCost = cost;
+ }
+ }
+ } else if (type instanceof IArrayType) {
+ IArrayType arrayType = (IArrayType) type;
+ Number arraySize = arrayType.getSize().numberValue();
+ if (arraySize != null)
+ for (long i = 0; i < arraySize.longValue(); i++) {
+ Cost cost = checkElement(arrayType.getType(), null, worstCost);
+ if (!cost.converts())
+ return cost;
+ if (cost.compareTo(worstCost) > 0) {
+ worstCost = cost;
+ }
+ }
+ }
+ return worstCost;
+ }
+
+ /**
+ * p8: If there are fewer initializer-clauses than there are elements in the
+ * aggregate, then each element not explicitly initialized shall be
+ * initialized from its default member initializer or, if there is no
+ * default member initializer, from an empty initializer list.
+ */
+ private Cost checkInitializationFromDefaultMemberInitializer(IType type, IValue initialValue, Cost worstCost)
+ throws DOMException {
+ if (initialValue != null) {
+ return worstCost; // has a default member initializer
+ }
+
+ // p11: If an incomplete or empty initializer-list leaves a member of
+ // reference type uninitialized, the program is ill-formed.
+ IType fieldType = SemanticUtil.getNestedType(type, SemanticUtil.TDEF);
+ if (fieldType instanceof ICPPReferenceType) {
+ return Cost.NO_CONVERSION;
+ }
+
+ // Empty initializer list
+ EvalInitList emptyInit = new EvalInitList(ICPPEvaluation.EMPTY_ARRAY, CPPSemantics.getCurrentLookupPoint());
+ Cost cost = Conversions.listInitializationSequence(emptyInit, fieldType, UDCMode.ALLOWED, false);
+ return cost;
+ }
+
+ private static boolean isAggregate(IType type) {
+ return (type instanceof ICPPClassType && TypeTraits.isAggregateClass((ICPPClassType) type))
+ || type instanceof IArrayType;
+ }
+
+ /**
+ * Get those fields of 'targetClass' which participate in aggregate initialization.
+ * These are the declared fields, excluding static fields and anonymous bit-fields
+ * ([decl.init.aggr] p6).
+ */
+ private static ICPPField[] getFieldsForAggregateInitialization(ICPPClassType targetClass) {
+ ICPPField[] fields = targetClass.getDeclaredFields();
+ ICPPField[] result = fields;
+ int j = 0;
+ for (int i = 0; i < fields.length; ++i) {
+ // TODO: Check for anonymous bit-fields. ICPPField doesn't currently expose whether
+ // it's a bit-field.
+ if (fields[i].isStatic()) {
+ if (fields == result) {
+ result = new ICPPField[fields.length - 1];
+ System.arraycopy(fields, 0, result, 0, i);
+ }
+ } else if (fields != result) {
+ result[j] = fields[i];
+ ++j;
+ }
+ }
+ return ArrayUtil.trim(result);
+ }
+
+} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
index 189d802e8e2..61627f970d6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
@@ -49,7 +49,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@@ -58,7 +57,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
-import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
@@ -335,97 +333,6 @@ public class Conversions {
}
/**
- * Get those fields of 'targetClass' which participate in aggregate initialization.
- * These are the declared fields, excluding static fields and anonymous bit-fields
- * ([decl.init.aggr] p6).
- */
- static ICPPField[] getFieldsForAggregateInitialization(ICPPClassType targetClass) {
- ICPPField[] fields = targetClass.getDeclaredFields();
- ICPPField[] result = fields;
- int j = 0;
- for (int i = 0; i < fields.length; ++i) {
- // TODO: Check for anonymous bit-fields. ICPPField doesn't currently expose whether
- // it's a bit-field.
- if (fields[i].isStatic()) {
- if (fields == result) {
- result = new ICPPField[fields.length - 1];
- System.arraycopy(fields, 0, result, 0, i);
- }
- } else if (fields != result) {
- result[j] = fields[i];
- ++j;
- }
- }
- return ArrayUtil.trim(result);
- }
-
- /**
- * Checks whether 'targetClass' can be initialized from 'list' according to the rules for
- * aggregate initialization ([dcl.init.aggr]).
- */
- static boolean checkAggregateInitialization(EvalInitList list, ICPPClassType targetClass) throws DOMException {
- ICPPField[] fields = getFieldsForAggregateInitialization(targetClass);
- ICPPEvaluation[] initializers = list.getClauses();
-
- // p7: An initializer-list is ill-formed if the number of initializer-clauses exceeds
- // the number of members to initialize.
- if (initializers.length > fields.length) {
- return false;
- }
-
- // p3: The elements of the initializer list are taken as initializers for the elements
- // of the aggregate, in order.
- int i = 0;
- for (; i < initializers.length; ++i) {
- ICPPEvaluation initializer = initializers[i];
- ICPPField field = fields[i];
-
- // Each element is copy-initialized from the corresponding initializer-clause.
- Cost cost = checkImplicitConversionSequence(field.getType(), initializer.getType(),
- initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY);
- if (!cost.converts()) {
- return false;
- }
-
- // If the initializer-clause is an expression and a narrowing conversion is
- // required to convert the expression, the program is ill-formed.
- if (!(initializer instanceof EvalInitList) && cost.isNarrowingConversion()) {
- return false;
- }
- }
-
- // p8: If there are fewer initializer-clauses than there are elements in the
- // aggregate, then each element not explicitly initialized shall be
- // initialized from its default member initializer or, if there is no
- // default member initializer, from an empty initializer list.
- for (; i < fields.length; ++i) {
- ICPPField field = fields[i];
- IValue initialValue = field.getInitialValue();
- if (initialValue != null) {
- continue; // has a default member initializer
- }
-
- // p11: If an incomplete or empty initializer-list leaves a member of
- // reference type uninitialized, the program is ill-formed.
- IType fieldType = SemanticUtil.getNestedType(field.getType(), TDEF);
- if (fieldType instanceof ICPPReferenceType) {
- return false;
- }
-
- // Empty initializer list
- EvalInitList emptyInit = new EvalInitList(ICPPEvaluation.EMPTY_ARRAY, CPPSemantics.getCurrentLookupPoint());
- Cost cost = listInitializationSequence(emptyInit, fieldType, UDCMode.ALLOWED, false);
- if (!cost.converts()) {
- return false;
- }
- }
-
- // TODO: Implement brace elision rules.
-
- return true;
- }
-
- /**
* 13.3.3.1.5 List-initialization sequence [over.ics.list]
*/
static Cost listInitializationSequence(EvalInitList arg, IType target, UDCMode udc, boolean isDirect)
@@ -438,22 +345,9 @@ public class Conversions {
static Cost listInitializationSequenceHelper(EvalInitList arg, IType target, UDCMode udc, boolean isDirect)
throws DOMException {
IType listType = getInitListType(target);
- if (listType == null && target instanceof IArrayType) {
- Number arraySize = ((IArrayType) target).getSize().numberValue();
- if (arraySize != null) {
- IType elementType = ((IArrayType) target).getType();
- // TODO(nathanridge): If there are fewer initializer clauses than the array size,
- // then the element type is required to be default-constructible.
- if (arg.getClauses().length <= arraySize.longValue()) {
- listType = elementType;
- }
- }
- }
-
if (listType != null) {
- ICPPEvaluation[] clauses = arg.getClauses();
Cost worstCost = new Cost(arg.getType(), target, Rank.IDENTITY);
- for (ICPPEvaluation clause : clauses) {
+ for (ICPPEvaluation clause : arg.getClauses()) {
Cost cost = checkImplicitConversionSequence(listType, clause.getType(), clause.getValueCategory(),
UDCMode.ALLOWED, Context.ORDINARY);
if (!cost.converts())
@@ -467,6 +361,8 @@ public class Conversions {
}
}
return worstCost;
+ } else if (target instanceof IArrayType) {
+ return AggregateInitialization.check(target, arg);
}
IType noCVTarget = getNestedType(target, CVTYPE | TDEF);
@@ -475,10 +371,12 @@ public class Conversions {
return Cost.NO_CONVERSION;
ICPPClassType classTarget = (ICPPClassType) noCVTarget;
- if (TypeTraits.isAggregateClass(classTarget) && checkAggregateInitialization(arg, classTarget)) {
- Cost cost = new Cost(arg.getType(), target, Rank.IDENTITY);
- cost.setUserDefinedConversion(null);
- return cost;
+ if (TypeTraits.isAggregateClass(classTarget)) {
+ Cost cost = AggregateInitialization.check(classTarget, arg);
+ if (cost.converts()) {
+ cost.setUserDefinedConversion(null);
+ return cost;
+ }
}
return listInitializationOfClass(arg, classTarget, isDirect, udc == UDCMode.DEFER);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java
index 7cf484afb54..63837ab46f9 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java
@@ -272,7 +272,7 @@ public class EvalTypeId extends CPPDependentEvaluation {
ICPPClassType classType = (ICPPClassType) simplifiedType;
ICPPEvaluation[] arguments = fArguments;
ICPPConstructor[] constructors = classType.getConstructors();
- if (arguments.length == 1 && arguments[0] instanceof EvalInitList) {
+ if (arguments.length == 1 && arguments[0] instanceof EvalInitList && !fUsesBracedInitList) {
// List-initialization of a class (dcl.init.list-3).
if (TypeTraits.isAggregateClass(classType)) {
// Pretend that aggregate initialization is calling the default constructor.
@@ -299,10 +299,18 @@ public class EvalTypeId extends CPPDependentEvaluation {
if (binding instanceof ICPPFunction) {
return (ICPPFunction) binding;
}
+ // TODO check aggregate initialization
+ if (fUsesBracedInitList && allConstructorsAreCompilerGenerated(constructors)) {
+ return AGGREGATE_INITIALIZATION;
+ }
+ if (binding instanceof IProblemBinding && !(binding instanceof ICPPFunction))
+ return new CPPFunction.CPPFunctionProblem(null, ((IProblemBinding) binding).getID(),
+ classType.getNameCharArray());
} catch (DOMException e) {
CCorePlugin.log(e);
}
+ // TODO check aggregate initialization
if (fUsesBracedInitList && allConstructorsAreCompilerGenerated(constructors)) {
return AGGREGATE_INITIALIZATION;
}

Back to the top