Skip to content

Commit

Permalink
Bug 510484 - Restore the recursion protection set in CPPVariable.getI…
Browse files Browse the repository at this point in the history
…nitialValue()

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
  • Loading branch information
HighCommander4 committed Jan 20, 2017
1 parent eb795e9 commit 89d1521
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2452,4 +2452,12 @@ public void testAnonymousStructInAnonymousNamespace_508254() throws Exception {
public void testDelegatingConstructorCallInConstexprConstructor_509871() throws Exception {
checkBindings();
}

// enum class NoneType { None };
// const NoneType None = None;

// // empty file
public void testSelfReferencingVariable_510484() throws Exception {
checkBindings();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -223,20 +237,28 @@ public IBinding getOwner() {

@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);
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 DependentValue.create(initEval);
return initialValue;
} finally {
recursionProtectionSet.remove(this);
}
return initialValue;
}

private IASTDeclarator findDeclarator() {
Expand Down

0 comments on commit 89d1521

Please sign in to comment.