From 944ec0e06edcf5869b5af2322da7dd863f3b2dc9 Mon Sep 17 00:00:00 2001 From: Hannes Vogt Date: Fri, 13 Sep 2019 23:44:17 +0200 Subject: [PATCH] Bug 549367 - [C++17] Aggregate init of base Implements http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0017r1.html: Types with non-private, non-protected, non-virtual base classes can be aggregate initialized. Change-Id: Idad341d45d6aaf1d8c36691cf8d7bc7cd049e28b Signed-off-by: Hannes Vogt --- .../ast2/cxx17/CXX17ExtensionsTests.java | 34 +++++++++++++++++++ .../semantics/AggregateInitialization.java | 10 ++++++ .../dom/parser/cpp/semantics/TypeTraits.java | 11 ++++-- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/CXX17ExtensionsTests.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/CXX17ExtensionsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/CXX17ExtensionsTests.java new file mode 100644 index 00000000000..b91cb51f6bd --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/CXX17ExtensionsTests.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.core.parser.tests.ast2.cxx17; + +import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase; + +import junit.framework.TestSuite; + +public class CXX17ExtensionsTests extends AST2CPPTestBase { + + public static TestSuite suite() { + return suite(CXX17ExtensionsTests.class); + } + + // struct Base { + // int foo; + // }; + // struct MyStruct : public Base { + // int a; + // }; + // + // int main() { + // MyStruct test = { {0}, 9 }; + // } + public void testAggregateInitializationOfBaseClass_549367() throws Exception { + parseAndCheckImplicitNameBindings(); + } +} 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 71790051d2e..49798f6f32c 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 @@ -14,6 +14,7 @@ import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; 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.ICPPField; @@ -131,6 +132,15 @@ class AggregateInitialization { */ private Cost checkInitializationOfElements(IType type, Cost worstCost) throws DOMException { if (type instanceof ICPPClassType && isAggregate(type)) { + ICPPBase[] bases = ((ICPPClassType) type).getBases(); + for (ICPPBase base : bases) { + Cost cost = checkElement(base.getBaseClassType(), null, worstCost); + if (!cost.converts()) + return cost; + if (cost.compareTo(worstCost) > 0) { + worstCost = cost; + } + } ICPPField[] fields = getFieldsForAggregateInitialization((ICPPClassType) type); for (ICPPField field : fields) { Cost cost = checkElement(field.getType(), field.getInitialValue(), worstCost); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java index cbba16a0c70..07b7aee8e91 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java @@ -271,8 +271,15 @@ public class TypeTraits { // 8.1.5.1 p.2 (N4659): The closure type is not an aggregate type. if (classType instanceof CPPClosureType) return false; - if (classType.getBases().length > 0) - return false; + if (classType.getBases().length > 0) { + // c++17 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0017r1.html + for (ICPPBase base : classType.getBases()) { + if (base.isVirtual()) + return false; + if (base.getVisibility() == ICPPBase.v_private || base.getVisibility() == ICPPBase.v_protected) + return false; + } + } ICPPMethod[] methods = classType.getDeclaredMethods(); for (ICPPMethod m : methods) { if (m instanceof ICPPConstructor)