]> granicus.if.org Git - clang/commitdiff
Fix determination of whether one set of cvr-qualifiers is compatible
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 11 Jul 2018 21:07:04 +0000 (21:07 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 11 Jul 2018 21:07:04 +0000 (21:07 +0000)
with another in template argument deduction.

We happened to typically get away with getting this wrong, because the
cases where we'd produce a bogus deduction were caught by the final
"deduced A is compatible with A" check.

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

lib/Sema/SemaTemplateDeduction.cpp
test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p1.cpp [new file with mode: 0644]

index fd4197ce2adaf9effbfb516b8adc282c0b45058b..760207fece572762373f8bf327beb61754ea07e7 100644 (file)
@@ -1019,8 +1019,10 @@ DeduceTemplateArguments(Sema &S,
   return Sema::TDK_Success;
 }
 
-/// Determine whether the parameter has qualifiers that are either
-/// inconsistent with or a superset of the argument's qualifiers.
+/// Determine whether the parameter has qualifiers that the argument
+/// lacks. Put another way, determine whether there is no way to add
+/// a deduced set of qualifiers to the ParamType that would result in
+/// its qualifiers matching those of the ArgType.
 static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType,
                                                   QualType ArgType) {
   Qualifiers ParamQs = ParamType.getQualifiers();
@@ -1044,10 +1046,8 @@ static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType,
       ParamQs.hasObjCLifetime())
     return true;
 
-  // CVR qualifier superset.
-  return (ParamQs.getCVRQualifiers() != ArgQs.getCVRQualifiers()) &&
-      ((ParamQs.getCVRQualifiers() | ArgQs.getCVRQualifiers())
-                                                == ParamQs.getCVRQualifiers());
+  // CVR qualifiers inconsistent or a superset.
+  return (ParamQs.getCVRQualifiers() & ~ArgQs.getCVRQualifiers()) != 0;
 }
 
 /// Compare types for equality with respect to possibly compatible
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p1.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p1.cpp
new file mode 100644 (file)
index 0000000..33d8182
--- /dev/null
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -verify %s
+
+// an attempt is made to find template argument values that will make P, after
+// substitution of the deduced values, compatible with A
+
+namespace cv_mismatch {
+  template<typename> struct X {};
+  template<typename T> void f(X<const T>); // expected-note {{cannot deduce a type for 'T' that would make 'const T' equal 'volatile int'}}
+  void g() { f(X<volatile int>()); } // expected-error {{no matching}}
+}