1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

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
This commit is contained in:
Nathan Ridge 2017-01-16 00:31:51 -05:00
parent eb795e9518
commit 89d1521d24
2 changed files with 43 additions and 13 deletions

View file

@ -2452,4 +2452,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();
}
}

View file

@ -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,20 +237,28 @@ 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() ) {
IASTNode point = fDefinition != null ? fDefinition : fDeclarations[0];
return initEval.getValue(point);
}
return DependentValue.create(initEval);
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() ) {
IASTNode point = fDefinition != null ? fDefinition : fDeclarations[0];
return initEval.getValue(point);
}
return DependentValue.create(initEval);
}
return initialValue;
} finally {
recursionProtectionSet.remove(this);
}
return initialValue;
}
private IASTDeclarator findDeclarator() {