Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2017-01-16 00:31:51 -0500
committerNathan Ridge2017-01-27 17:45:10 -0500
commit0dd5bb0f651ea89bcfcf742310c4ef133b9fb99c (patch)
tree1be9b6f050960561a1d10f19a237ff9ff5e2282d
parent56d950b863dd1555a2526f5915d3453ee6d539ff (diff)
downloadorg.eclipse.cdt-0dd5bb0f651ea89bcfcf742310c4ef133b9fb99c.tar.gz
org.eclipse.cdt-0dd5bb0f651ea89bcfcf742310c4ef133b9fb99c.tar.xz
org.eclipse.cdt-0dd5bb0f651ea89bcfcf742310c4ef133b9fb99c.zip
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
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java8
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java44
2 files changed, 41 insertions, 11 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 8b307687d8..8223d492c8 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 d83ed3c081..8cfeb85057 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<Set<CPPVariable>> fInitialValueInProgress = new ThreadLocal<Set<CPPVariable>>() {
+ @Override
+ protected Set<CPPVariable> 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);
+ Set<CPPVariable> 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 DependentValue.create(initEval);
+ return initialValue;
+ } finally {
+ recursionProtectionSet.remove(this);
}
- return initialValue;
}
private IASTDeclarator findDeclarator() {

Back to the top