mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 509255 - Unresolved symbol due to invalid selection of template
specialization Change-Id: I130219f4ec7c3339b449d5c1af8a35150362613b
This commit is contained in:
parent
f247b3141c
commit
a8872762d0
2 changed files with 125 additions and 15 deletions
|
@ -2631,6 +2631,107 @@ public class AST2TemplateTests extends AST2TestBase {
|
|||
}
|
||||
}
|
||||
|
||||
// template<typename T>
|
||||
// struct A { typedef char type; };
|
||||
//
|
||||
// template <typename T, typename U>
|
||||
// struct B { typedef int type; };
|
||||
//
|
||||
// template <typename T>
|
||||
// struct B<T, typename A<T>::type> {};
|
||||
//
|
||||
// typename B<A<int>, int>::type a;
|
||||
public void testSpecializationSelection_509255a() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// template <typename T>
|
||||
// struct A {
|
||||
// typedef T type;
|
||||
// };
|
||||
//
|
||||
// template <typename T>
|
||||
// void waldo(T t, typename T::type u);
|
||||
//
|
||||
// void test() {
|
||||
// A<char> a;
|
||||
// waldo(a, 1);
|
||||
// }
|
||||
public void testSpecializationSelection_509255b() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// struct true_type {
|
||||
// static constexpr bool v = true;
|
||||
// };
|
||||
//
|
||||
// struct false_type {
|
||||
// static constexpr bool v = false;
|
||||
// };
|
||||
//
|
||||
// template<typename T>
|
||||
// T d();
|
||||
//
|
||||
// template<typename T, typename U>
|
||||
// struct E : public true_type {};
|
||||
//
|
||||
// template<bool, typename T = void>
|
||||
// struct enable_if {};
|
||||
//
|
||||
// template<typename T>
|
||||
// struct enable_if<true, T> {
|
||||
// typedef T type;
|
||||
// };
|
||||
//
|
||||
// template <typename T>
|
||||
// struct D {
|
||||
// template <typename F>
|
||||
// struct S;
|
||||
//
|
||||
// template <typename R, typename U>
|
||||
// struct S<R(U::*)()> {
|
||||
// using type = R();
|
||||
// };
|
||||
//
|
||||
// using type = typename S<decltype(&T::m)>::type;
|
||||
// };
|
||||
//
|
||||
// template <typename F, typename S, typename T = void>
|
||||
// struct C : false_type {};
|
||||
//
|
||||
// template <typename F, typename R, typename... U>
|
||||
// struct C<
|
||||
// F, R(U...),
|
||||
// typename enable_if<E<decltype(d<F>()(d<U>()...)), R>::v>::type>
|
||||
// : true_type {};
|
||||
//
|
||||
// template <typename F, typename S>
|
||||
// constexpr bool g() { return C<F, S>::v; }
|
||||
//
|
||||
// template <typename F>
|
||||
// struct B {
|
||||
// template <
|
||||
// typename T,
|
||||
// typename = typename enable_if<g<F, typename D<T>::type>()>::type>
|
||||
// operator T*();
|
||||
// };
|
||||
//
|
||||
// template <typename F>
|
||||
// B<F> f(F p);
|
||||
//
|
||||
// struct A {
|
||||
// void m();
|
||||
// };
|
||||
//
|
||||
// void waldo(A* a);
|
||||
//
|
||||
// void test() {
|
||||
// waldo(f([]() {}));
|
||||
// }
|
||||
public void testSpecializationSelection_509255c() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// template<typename _Tp>
|
||||
// class A {
|
||||
// public:
|
||||
|
@ -9856,6 +9957,6 @@ public class AST2TemplateTests extends AST2TestBase {
|
|||
public void testOOM_508254() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
// Just check that resolution does not throw an exception.
|
||||
helper.findName("waldo", 5).resolveBinding();
|
||||
helper.findName("waldo").resolveBinding();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -205,8 +205,7 @@ public class TemplateArgumentDeduction {
|
|||
IType type1 = ((ICPPTemplateNonTypeParameter) tpar).getType();
|
||||
type1= CPPTemplates.instantiateType(type1, new InstantiationContext(map, point));
|
||||
IType type2= arg.getTypeOfNonTypeValue();
|
||||
// Template-argument deduced from an array bound may be of any integral
|
||||
// type.
|
||||
// Template-argument deduced from an array bound may be of any integral type.
|
||||
if (type2 instanceof TypeOfValueDeducedFromArraySize && isIntegralType(type1)) {
|
||||
IValue value = isBooleanType(type1) ? IntegralValue.create(true) : arg.getNonTypeValue();
|
||||
arg = new CPPTemplateNonTypeArgument(value, type1);
|
||||
|
@ -310,7 +309,7 @@ public class TemplateArgumentDeduction {
|
|||
}
|
||||
}
|
||||
|
||||
return deduct.fromType(par, arg, true, point);
|
||||
return deduct.fromType(par, arg, true, false, point);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -337,7 +336,7 @@ public class TemplateArgumentDeduction {
|
|||
TemplateArgumentDeduction deduct=
|
||||
new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0);
|
||||
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF);
|
||||
if (arg != null && !deduct.fromType(par, arg, false, point))
|
||||
if (arg != null && !deduct.fromType(par, arg, false, false, point))
|
||||
return null;
|
||||
if (!map.addDeducedArgs(deduct.fDeducedArgs))
|
||||
return null;
|
||||
|
@ -370,7 +369,7 @@ public class TemplateArgumentDeduction {
|
|||
p= getArgumentTypeForDeduction(p, a instanceof ICPPReferenceType);
|
||||
a= SemanticUtil.getNestedType(a, SemanticUtil.REF | SemanticUtil.TDEF);
|
||||
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, null, map, 0);
|
||||
if (!deduct.fromType(p, a, true, point)) {
|
||||
if (!deduct.fromType(p, a, true, false, point)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -410,7 +409,7 @@ public class TemplateArgumentDeduction {
|
|||
|
||||
TemplateArgumentDeduction deduct=
|
||||
new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0);
|
||||
if (!deduct.fromType(p, a, false, point)) {
|
||||
if (!deduct.fromType(p, a, false, false, point)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -562,7 +561,7 @@ public class TemplateArgumentDeduction {
|
|||
par= getNestedType(par, TDEF | REF | ALLCVQ);
|
||||
arg= getNestedType(arg, TDEF | REF | ALLCVQ);
|
||||
|
||||
if (!deduct.fromType(par, arg, false, point))
|
||||
if (!deduct.fromType(par, arg, false, false, point))
|
||||
return -1;
|
||||
|
||||
return isMoreCVQualified ? 1 : 0;
|
||||
|
@ -838,12 +837,13 @@ public class TemplateArgumentDeduction {
|
|||
|
||||
// Try to deduce from the original argument type, but if it fails, fall back to the simplified
|
||||
// argument type.
|
||||
return fromType(p.getTypeValue(), a.getOriginalTypeValue(), false, point)
|
||||
return fromType(p.getTypeValue(), a.getOriginalTypeValue(), false, true, point)
|
||||
|| (a.getTypeValue() != a.getOriginalTypeValue()
|
||||
&& fromType(p.getTypeValue(), a.getTypeValue(), false, point));
|
||||
&& fromType(p.getTypeValue(), a.getTypeValue(), false, true, point));
|
||||
}
|
||||
|
||||
private boolean fromType(IType p, IType a, boolean allowCVQConversion, IASTNode point) throws DOMException {
|
||||
private boolean fromType(IType p, IType a, boolean allowCVQConversion, boolean verifyNonDeduced,
|
||||
IASTNode point) throws DOMException {
|
||||
IType originalArgType = a;
|
||||
a = SemanticUtil.getSimplifiedType(a);
|
||||
while (p != null) {
|
||||
|
@ -860,7 +860,7 @@ public class TemplateArgumentDeduction {
|
|||
final ICPPPointerToMemberType ptrA = (ICPPPointerToMemberType) a;
|
||||
if (!allowCVQConversion && (ptrP.isConst() != ptrA.isConst() || ptrP.isVolatile() != ptrA.isVolatile()))
|
||||
return false;
|
||||
if (!fromType(ptrP.getMemberOfClass(), ptrA.getMemberOfClass(), false, point)) {
|
||||
if (!fromType(ptrP.getMemberOfClass(), ptrA.getMemberOfClass(), false, false, point)) {
|
||||
return false;
|
||||
}
|
||||
p = ptrP.getType();
|
||||
|
@ -980,7 +980,16 @@ public class TemplateArgumentDeduction {
|
|||
return false;
|
||||
return fromTemplateInstance((ICPPTemplateInstance) p, (ICPPTemplateInstance) a, point);
|
||||
} else if (p instanceof ICPPUnknownBinding) {
|
||||
if (!verifyNonDeduced)
|
||||
return true; // An unknown type may match anything.
|
||||
|
||||
// Verify that the resolved binding matches the argument type.
|
||||
InstantiationContext context = new InstantiationContext(fDeducedArgs, point);
|
||||
IBinding binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) p, context);
|
||||
if (binding instanceof ICPPUnknownBinding)
|
||||
return true; // An unknown type may match anything.
|
||||
|
||||
return binding instanceof IType && ((IType) binding).isSameType(a);
|
||||
} else {
|
||||
return p.isSameType(a);
|
||||
}
|
||||
|
@ -1065,7 +1074,7 @@ public class TemplateArgumentDeduction {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!fromType(ftp.getReturnType(), fta.getReturnType(), false, point))
|
||||
if (!fromType(ftp.getReturnType(), fta.getReturnType(), false, false, point))
|
||||
return false;
|
||||
|
||||
IType[] pParams = ftp.getParameterTypes();
|
||||
|
@ -1103,7 +1112,7 @@ public class TemplateArgumentDeduction {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (!deduct.fromType(p, aParams[i], false, point))
|
||||
if (!deduct.fromType(p, aParams[i], false, true, point))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue