From 477aa9c798aef206e55bb2282cc69a99a95ff4ef Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Sat, 2 May 2020 00:38:50 -0400 Subject: [PATCH] Bug 562697 - Fix comparison of qualifier type and pointer type CDT has two representations for a pointer type wrapped in a qualifier type: it can be an IPointerType with some qualifiers set on it directly, or an IPointerType wrapped in an IQualifierType. (We prefer the first representation to avoid creating too many wrappers, but sometimes the second one arises during template instantiation.) This patch makes sure that two such types can compare equal even if they use different representations. Change-Id: Ia8c7d227c74378aae74f04545b9a69103c14e74b --- .../cdt/core/parser/tests/ast2/AST2CPPTests.java | 11 +++++++++++ .../core/dom/parser/cpp/CPPQualifierType.java | 14 +++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 2e0fd4a2d7d..96b72dcd5bf 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -13563,4 +13563,15 @@ public class AST2CPPTests extends AST2CPPTestBase { assertTrue(((ICPPEnumeration) col.getType()).isNoDiscard()); assertFalse(((ICPPEnumeration) f.getType()).isNoDiscard()); } + + // template + // void waldo(const T&) {} + // + // typedef int* IntPtr; + // + // template <> + // void waldo(const IntPtr&) {} + public void testExplicitSpecPointerType_562697() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java index 6a2eb7e0e7a..2186b88c1c9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java @@ -15,12 +15,14 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.CoreException; public class CPPQualifierType implements IQualifierType, ITypeContainer, ISerializableType { @@ -38,8 +40,18 @@ public class CPPQualifierType implements IQualifierType, ITypeContainer, ISerial public boolean isSameType(IType o) { if (o instanceof ITypedef) return o.isSameType(this); - if (!(o instanceof IQualifierType)) + if (!(o instanceof IQualifierType)) { + // Handle the case where we store the qualifiers in the IPointerType. + if (o instanceof IPointerType) { + IType nested = SemanticUtil.getSimplifiedType(type); + if (nested instanceof IPointerType) { + IPointerType pt = (IPointerType) o; + return isConst() == pt.isConst() && isVolatile() == pt.isVolatile() + && ((IPointerType) nested).getType().isSameType(pt.getType()); + } + } return false; + } IQualifierType pt = (IQualifierType) o; if (isConst() == pt.isConst() && isVolatile() == pt.isVolatile() && type != null)