1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 549508 - Avoid calling CPPBasicType.setAssociatedNumericalValue() without cloning the type

If we call it without cloning, we associate the value with every place
that has a reference to that CPPBasicType object, which could involve
completely unrelated entities.

Change-Id: Icff6c32d15ee6dbc55e363b2de9a166e03440f74
This commit is contained in:
Nathan Ridge 2019-08-02 00:54:29 -04:00
parent c252113586
commit f89c738b0b
2 changed files with 44 additions and 14 deletions

View file

@ -194,6 +194,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
@ -2321,11 +2322,11 @@ public class CPPVisitor extends ASTQueries {
if (initClause instanceof IASTEqualsInitializer) {
initClause = ((IASTEqualsInitializer) initClause).getInitializerClause();
if (initClause instanceof IASTLiteralExpression && SemanticUtil.isConst(type)) {
IType t = SemanticUtil.getNestedType(type, TDEF | ALLCVQ);
if (t instanceof CPPBasicType) {
IValue v = SemanticUtil.getValueOfInitializer(declarator.getInitializer(), t);
if (v.numberValue() != null)
((CPPBasicType) t).setAssociatedNumericalValue(v.numberValue().longValue());
// The check here avoids performing the computation in getValueOfInitialize()
// in cases where we wouldn't use it anyways because we don't have a CPPBasicType.
if (SemanticUtil.getNestedType(type, TDEF | ALLCVQ) instanceof CPPBasicType) {
type = associateTypeWithValue(type,
SemanticUtil.getValueOfInitializer(declarator.getInitializer(), type));
}
}
}
@ -2349,6 +2350,42 @@ public class CPPVisitor extends ASTQueries {
}
}
/**
* Returns an IType representing the same type as the argument, but
* which also knows its value.
*
* This only has an effect for built-in types (modulo cv-qualification
* and typedefs), and in cases where the a concrete numerical value
* is known.
*
* The returned IType object may be different from the argument.
*/
public static IType associateTypeWithValue(IType type, IValue value) {
Number numberValue = value.numberValue();
if (numberValue != null) {
return associateTypeWithValue(type, numberValue.longValue());
}
return type;
}
private static IType associateTypeWithValue(IType type, long value) {
if (type instanceof ITypeContainer) {
ITypeContainer typeContainer = (ITypeContainer) type;
IType oldInner = typeContainer.getType();
IType newInner = associateTypeWithValue(oldInner, value);
if (oldInner != newInner) {
ITypeContainer clone = (ITypeContainer) typeContainer.clone();
clone.setType(newInner);
return clone;
}
} else if (type instanceof CPPBasicType) {
CPPBasicType clone = ((CPPBasicType) type).clone();
clone.setAssociatedNumericalValue(value);
return clone;
}
return type;
}
private static IType createAutoParameterType(IASTDeclSpecifier declSpec, IASTDeclarator declarator,
ICPPASTParameterDeclaration declaration, PlaceholderKind placeholder) {
// decltype(auto) is not allowed in parameters.

View file

@ -161,15 +161,8 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
case op_sizeofParameterPack:
case op_alignof:
IType result = (IType) CPPVisitor.get_SIZE_T().clone();
IType simplifiedResult = SemanticUtil.getSimplifiedType(result);
if (simplifiedResult instanceof CPPBasicType) {
CPPBasicType t = (CPPBasicType) simplifiedResult;
IValue value = getValue();
if (value != null && value.numberValue() != null) {
t.setAssociatedNumericalValue(value.numberValue().longValue());
}
// We're still returning 'result', which is now modified.
// This preserves the 'size_t' typedef.
if (SemanticUtil.getSimplifiedType(result) instanceof CPPBasicType) {
result = CPPVisitor.associateTypeWithValue(result, getValue());
}
return result;
case op_typeid: