When comparing parameters of reference-to-qualified type during

partial ordering of function templates, use a simple superset
relationship rather than the convertibility-implying
isMoreQualifiedThan/compatibilyIncludes relationship. Fixes partial
ordering between references and address-space-qualified references.

llvm-svn: 130612
This commit is contained in:
Douglas Gregor 2011-04-30 17:07:52 +00:00
parent bde52bca69
commit 85894a8f85
4 changed files with 32 additions and 2 deletions

View File

@ -299,6 +299,10 @@ public:
(((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
}
/// \brief Determine whether this set of qualifiers is a strict superset of
/// another set of qualifiers, not considering qualifier compatibility.
bool isStrictSupersetOf(Qualifiers Other) const;
bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }

View File

@ -27,6 +27,18 @@
#include <algorithm>
using namespace clang;
bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {
return (*this != Other) &&
// CVR qualifiers superset
(((Mask & CVRMask) | (Other.Mask & CVRMask)) == (Mask & CVRMask)) &&
// ObjC GC qualifiers superset
((getObjCGCAttr() == Other.getObjCGCAttr()) ||
(hasObjCGCAttr() && !Other.hasObjCGCAttr())) &&
// Address space superset.
((getAddressSpace() == Other.getAddressSpace()) ||
(hasAddressSpace()&& !Other.hasAddressSpace()));
}
bool QualType::isConstant(QualType T, ASTContext &Ctx) {
if (T.isConstQualified())
return true;

View File

@ -901,9 +901,12 @@ DeduceTemplateArguments(Sema &S,
Comparison.ParamIsRvalueRef = ParamRef->getAs<RValueReferenceType>();
Comparison.ArgIsRvalueRef = ArgRef->getAs<RValueReferenceType>();
Comparison.Qualifiers = NeitherMoreQualified;
if (Param.isMoreQualifiedThan(Arg))
Qualifiers ParamQuals = Param.getQualifiers();
Qualifiers ArgQuals = Arg.getQualifiers();
if (ParamQuals.isStrictSupersetOf(ArgQuals))
Comparison.Qualifiers = ParamMoreQualified;
else if (Arg.isMoreQualifiedThan(Param))
else if (ArgQuals.isStrictSupersetOf(ParamQuals))
Comparison.Qualifiers = ArgMoreQualified;
RefParamComparisons->push_back(Comparison);
}

View File

@ -73,3 +73,14 @@ void test_arg_in_address_space_1() {
identity<int> ii = accept_arg_in_address_space_1(int_1);
identity<int __attribute__((address_space(1)))> ii2 = accept_any_arg(int_1);
}
// Partial ordering
template<typename T> int &order1(__attribute__((address_space(1))) T&);
template<typename T> float &order1(T&);
void test_order1() {
static __attribute__((address_space(1))) int i1;
int i;
int &ir = order1(i1);
float &fr = order1(i);
}