From 1f700ff1000033ef15ce433336a62f85c88b6475 Mon Sep 17 00:00:00 2001 From: "Igor V. Kovalenko" Date: Mon, 13 Mar 2023 09:13:45 +0300 Subject: [PATCH] Return IntegralValue.UNKNOWN if recursed creating CompositeValue Currently CDT would return empty CompositeValue if recursion creating for class type is detected. If this happens inside CompositeValue.computeForFunctionCall() and class type has fields, this leads to an attempt to assign a value to non-existent index into empty values array. Fix this by returning usual IntegralValue.UNKNOWN and additionally checking whether created value is actually a CompositeValue instance. --- .../cdt/internal/core/dom/parser/CompositeValue.java | 6 +++--- .../core/dom/parser/cpp/semantics/EvalConstructor.java | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CompositeValue.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CompositeValue.java index 4c8a1eb6515..362920b8ad3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CompositeValue.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/CompositeValue.java @@ -176,7 +176,7 @@ public final class CompositeValue implements IValue { * determined by the default member initializers only. Constructors are not considered * when determining the values of the fields. */ - public static CompositeValue create(ICPPClassType classType) { + public static IValue create(ICPPClassType classType) { return create(classType, 0); } @@ -185,10 +185,10 @@ public final class CompositeValue implements IValue { * determined by the default member initializers only. Constructors are not considered * when determining the values of the fields. */ - public static CompositeValue create(ICPPClassType classType, int nestingLevel) { + public static IValue create(ICPPClassType classType, int nestingLevel) { Set recursionProtectionSet = fCreateInProgress.get(); if (!recursionProtectionSet.add(classType)) { - return new CompositeValue(null, ICPPEvaluation.EMPTY_ARRAY); + return IntegralValue.UNKNOWN; } try { if (sDEBUG && nestingLevel > 0) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java index c31c059260e..c6fe267f5bb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java @@ -160,11 +160,15 @@ public final class EvalConstructor extends CPPDependentEvaluation { return this; } final ICPPClassType classType = (ICPPClassType) unwrappedType; - final CompositeValue compositeValue = CompositeValue.create(classType); + final IValue classObject = CompositeValue.create(classType); ICPPEvaluation[] argList = evaluateArguments(fArguments, callSiteRecord, context); - EvalFixed constructedObject = new EvalFixed(fType, ValueCategory.PRVALUE, compositeValue); + EvalFixed constructedObject = new EvalFixed(fType, ValueCategory.PRVALUE, classObject); CPPVariable binding = new CPPVariable(TEMP_NAME); + if (!(classObject instanceof CompositeValue compositeValue)) { + return constructedObject; + } + ActivationRecord localRecord = EvalFunctionCall.createActivationRecord(fConstructor.getParameters(), argList, constructedObject); localRecord.update(binding, constructedObject);