From 8fc812ee27f84b2034bed005e56427e5620c063a Mon Sep 17 00:00:00 2001 From: "Igor V. Kovalenko" Date: Fri, 6 Jan 2023 00:32:35 +0300 Subject: [PATCH] Fix pack expansion for array elements When parameter pack contains array type the EvalCompositeAccess.getType() will attempt to return type of array element. Fix this by providing EvalPackAccess which returns pack elements as is. --- .../parser/tests/ast2/AST2TemplateTests.java | 19 +++++++ .../core/dom/parser/ITypeMarshalBuffer.java | 2 +- .../dom/parser/cpp/semantics/EvalBinding.java | 2 +- .../cpp/semantics/EvalCompositeAccess.java | 2 +- .../parser/cpp/semantics/EvalPackAccess.java | 52 +++++++++++++++++++ .../core/pdom/dom/cpp/PDOMCPPLinkage.java | 3 ++ 6 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalPackAccess.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index ab237d266b2..e61c0672344 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -18,6 +18,7 @@ * Nathan Ridge * Danny Ferreira * Marc-Andre Laperle (Ericsson) + * Igor V. Kovalenko *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -11400,4 +11401,22 @@ public void testIntegerPack_553794() throws Exception { ITypedef type2 = helper.assertNonProblem("type2"); assertSameType(type1, type2); } + + // using size_t = decltype(sizeof(int)); + // + // template struct A { + // static constexpr size_t f(const T& arg) noexcept { return sizeof(arg); } + // }; + // + // template + // constexpr size_t g(const Pack&... pack) { return A::f(pack...); } + // + // static constexpr auto val1 = g("123"); + // static constexpr auto val2 = g((const char*)"123"); + public void testParameterPackExpansions_array() throws Exception { + parseAndCheckBindings(); + BindingAssertionHelper helper = getAssertionHelper(); + helper.assertVariableValue("val1", 4); + helper.assertVariableValue("val2", 8); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java index b7e352d7bf1..1de702f182a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java @@ -45,7 +45,7 @@ public interface ITypeMarshalBuffer { EVAL_FUNCTION_SET = 0x09, EVAL_ID = 0x0A, EVAL_INIT_LIST = 0x0B, EVAL_MEMBER_ACCESS = 0x0C, EVAL_PACK_EXPANSION = 0x0D, EVAL_TYPE_ID = 0x0E, EVAL_UNARY = 0x0F, EVAL_UNARY_TYPE_ID = 0x10, EVAL_CONSTRUCTOR = 0x11, EVAL_REFERENCE = 0x12, EVAL_POINTER = 0x13, EVAL_COMPOSITE_ACCESS = 0x14, - EVAL_NARY_TYPE_ID = 0x15; + EVAL_NARY_TYPE_ID = 0x15, EVAL_PACK_ACCESS = 0x16; // Can add more evaluations up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE. final static byte EXEC_COMPOUND_STATEMENT = 0x01, EXEC_BREAK = 0x02, EXEC_CASE = 0x03, EXEC_CONTINUE = 0x04, diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index 3ba549e475a..55c14076dd3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -454,7 +454,7 @@ public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) { newBindingEval = new EvalBinding(newBinding, newBinding.getType(), getTemplateDefinition()); } if (context.hasPackOffset()) { - return new EvalCompositeAccess(newBindingEval, packOffset); + return new EvalPackAccess(newBindingEval, packOffset); } else { return newBindingEval; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompositeAccess.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompositeAccess.java index 7adf5900108..d3a33f2ac3f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompositeAccess.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompositeAccess.java @@ -39,7 +39,7 @@ * Represents an access to a sub-value of a composite value, identified by an index. * Composite values can include arrays, structures, and parameter packs (see {@code CompositeValue}). */ -public final class EvalCompositeAccess implements ICPPEvaluation { +public class EvalCompositeAccess implements ICPPEvaluation { private final ICPPEvaluation parent; // The composite value being accessed private final int elementId; // The index of the sub-value being accessed diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalPackAccess.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalPackAccess.java new file mode 100644 index 00000000000..760903585e5 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalPackAccess.java @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (c) 2016,2022 Institute for Software, HSR Hochschule fuer Technik and others +* Rapperswil, University of applied sciences and others +* +* 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 + * + * Contributors: + * Igor V. Kovalenko - factor out EvalPackAccess +*******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; + +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; + +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.core.runtime.CoreException; + +public class EvalPackAccess extends EvalCompositeAccess { + + public EvalPackAccess(ICPPEvaluation parent, int elementId) { + super(parent, elementId); + } + + @Override + public IType getType() { + IType type = getParent().getType(); + type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); + + return type; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putShort(ITypeMarshalBuffer.EVAL_PACK_ACCESS); + buffer.marshalEvaluation(getParent(), includeValue); + buffer.putInt(getElementId()); + } + + public static ICPPEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException { + ICPPEvaluation parent = buffer.unmarshalEvaluation(); + int elementId = buffer.getInt(); + return new EvalPackAccess(parent, elementId); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 991f3ef73eb..e92eb94b25f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -136,6 +136,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalNaryTypeId; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPackAccess; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPackExpansion; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPointer; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalReference; @@ -1726,6 +1727,8 @@ public ICPPEvaluation unmarshalEvaluation(ITypeMarshalBuffer buffer) throws Core return EvalCompositeAccess.unmarshal(firstBytes, buffer); case ITypeMarshalBuffer.EVAL_NARY_TYPE_ID: return EvalNaryTypeId.unmarshal(firstBytes, buffer); + case ITypeMarshalBuffer.EVAL_PACK_ACCESS: + return EvalPackAccess.unmarshal(firstBytes, buffer); } throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal an evaluation, first bytes=" + firstBytes)); //$NON-NLS-1$ }