]> granicus.if.org Git - clang/commitdiff
When comparing parameters of reference-to-qualified type during
authorDouglas Gregor <dgregor@apple.com>
Sat, 30 Apr 2011 17:07:52 +0000 (17:07 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 30 Apr 2011 17:07:52 +0000 (17:07 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130612 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Type.h
lib/AST/Type.cpp
lib/Sema/SemaTemplateDeduction.cpp
test/SemaTemplate/address-spaces.cpp

index c1b8a775a6866da6c4d1573f40fc57e972b4cc27..f01e2351abf21f9c3b50ece1f657fa67c2a68d85 100644 (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; }
 
index 59cd5a3dc7cf4ee57cc4a821b64c4dd569b6a2f4..0ca9b1fd2fd2355b2a0e663624fbc5914b07c3ee 100644 (file)
 #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;
index 73d523f8bb1216119c86688c0fa3a01a6ffa9c75..7df6de4a3097b0c0c2a5d5fee591ff2c440249f3 100644 (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);
     }
index df262e1dc6657c6e44787b4fa0e06bdf32849d94..eda03dbac2bda62aad2c463ca9e8e190a767fcb5 100644 (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);
+}