From 0dd5bb0f651ea89bcfcf742310c4ef133b9fb99c Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Mon, 16 Jan 2017 00:31:51 -0500 Subject: [PATCH] Bug 510484 - Restore the recursion protection set in CPPVariable.getInitialValue() The set was moved to EvalUtil.getVariableValue() in bug 508254, but this left some paths unprotected. This restores the set to CPPVariable.getInitialValue() (while keeping the EvalUtil one too). Change-Id: I4a579720f4bc23d41e50c484649a73c29698373d --- .../tests/IndexCPPBindingResolutionTest.java | 8 ++++ .../core/dom/parser/cpp/CPPVariable.java | 46 ++++++++++++++----- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java index 8b307687d8d..8223d492c87 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java @@ -2428,4 +2428,12 @@ public class IndexCPPBindingResolutionTest extends IndexBindingResolutionTestBas public void testDelegatingConstructorCallInConstexprConstructor_509871() throws Exception { checkBindings(); } + + // enum class NoneType { None }; + // const NoneType None = None; + + // // empty file + public void testSelfReferencingVariable_510484() throws Exception { + checkBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java index d83ed3c0816..8cfeb850575 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java @@ -17,6 +17,9 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti 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 java.util.HashSet; +import java.util.Set; + import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; @@ -56,6 +59,17 @@ public class CPPVariable extends PlatformObject implements ICPPInternalVariable private IType fType; private boolean fAllResolved; + /** + * The set of CPPVariable objects for which initial value computation is in progress on each thread. + * This is used to guard against recursion during initial value computation. + */ + private static final ThreadLocal> fInitialValueInProgress = new ThreadLocal>() { + @Override + protected Set initialValue() { + return new HashSet<>(); + } + }; + public CPPVariable(IASTName name) { boolean isDef = name != null && name.isDefinition(); if (name instanceof ICPPASTQualifiedName) { @@ -223,19 +237,27 @@ public class CPPVariable extends PlatformObject implements ICPPInternalVariable @Override public IValue getInitialValue() { - IValue initialValue = null; - final IType nestedType = SemanticUtil.getNestedType(getType(), TDEF | REF | CVTYPE); - if (nestedType instanceof ICPPClassType || (initialValue = VariableHelpers.getInitialValue(fDefinition, fDeclarations, getType())) == IntegralValue.UNKNOWN) { - ICPPEvaluation initEval = getInitializerEvaluation(); - if (initEval == null) { - return null; - } - if (!initEval.isValueDependent() ) { - return initEval.getValue(fDefinition); - } - return DependentValue.create(initEval); + Set recursionProtectionSet = fInitialValueInProgress.get(); + if (!recursionProtectionSet.add(this)) { + return IntegralValue.UNKNOWN; + } + try { + IValue initialValue = null; + final IType nestedType = SemanticUtil.getNestedType(getType(), TDEF | REF | CVTYPE); + if (nestedType instanceof ICPPClassType || (initialValue = VariableHelpers.getInitialValue(fDefinition, fDeclarations, getType())) == IntegralValue.UNKNOWN) { + ICPPEvaluation initEval = getInitializerEvaluation(); + if (initEval == null) { + return null; + } + if (!initEval.isValueDependent() ) { + return initEval.getValue(fDefinition); + } + return DependentValue.create(initEval); + } + return initialValue; + } finally { + recursionProtectionSet.remove(this); } - return initialValue; } private IASTDeclarator findDeclarator() {