summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-07-11 21:07:04 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-07-11 21:07:04 +0000
commit34c325028a9c36c00b8c49b93d4f280cebfeccf4 (patch)
tree998ef8ea9df137936bb3478f37aead41462f6ce0
parent5bfbae5cb180ef00cc5ce412fd0fb6566918028e (diff)
downloadbcm5719-llvm-34c325028a9c36c00b8c49b93d4f280cebfeccf4.tar.gz
bcm5719-llvm-34c325028a9c36c00b8c49b93d4f280cebfeccf4.zip
Fix determination of whether one set of cvr-qualifiers is compatible
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. llvm-svn: 336852
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp12
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p1.cpp10
2 files changed, 16 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index fd4197ce2ad..760207fece5 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p1.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p1.cpp
new file mode 100644
index 00000000000..33d8182ab14
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p1.cpp
@@ -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}}
+}
OpenPOWER on IntegriCloud