diff options
| author | Lei Liu <lei.liu2@windriver.com> | 2018-05-03 01:43:23 +0000 |
|---|---|---|
| committer | Lei Liu <lei.liu2@windriver.com> | 2018-05-03 01:43:23 +0000 |
| commit | 413f3c55955537552b556a556d678d5756a9f16b (patch) | |
| tree | 92e419afe91e967fb8859cc8e9f2c56520ee6535 | |
| parent | 87f1343a73fa56729571fb93deeb4f795d3e042b (diff) | |
| download | bcm5719-llvm-413f3c55955537552b556a556d678d5756a9f16b.tar.gz bcm5719-llvm-413f3c55955537552b556a556d678d5756a9f16b.zip | |
[Sema] Do not match function type with const T in template argument deduction
From http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584,
function type should not match cv-qualified type in template argument
deduction. This also matches what GCC and EDG do in template argument
deduction.
Differential Revision: https://reviews.llvm.org/D45755
llvm-svn: 331424
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 6 | ||||
| -rw-r--r-- | clang/test/CXX/drs/dr15xx.cpp | 13 | ||||
| -rw-r--r-- | clang/test/CXX/drs/dr4xx.cpp | 17 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/function-pointer-qualifier.cpp | 29 |
4 files changed, 49 insertions, 16 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 22e5b73a243..e4a158f6507 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1273,6 +1273,12 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, return Sema::TDK_Underqualified; } + // Do not match a function type with a cv-qualified type. + // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584 + if (Arg->isFunctionType() && Param.hasQualifiers()) { + return Sema::TDK_NonDeducedMismatch; + } + assert(TemplateTypeParm->getDepth() == Info.getDeducedDepth() && "saw template type parameter with wrong depth"); assert(Arg != S.Context.OverloadTy && "Unresolved overloaded function"); diff --git a/clang/test/CXX/drs/dr15xx.cpp b/clang/test/CXX/drs/dr15xx.cpp index a68928f727e..20600475715 100644 --- a/clang/test/CXX/drs/dr15xx.cpp +++ b/clang/test/CXX/drs/dr15xx.cpp @@ -357,6 +357,19 @@ auto DR1579_lambda_invalid = []() -> GenericMoveOnly<char> { }; } // end namespace dr1579 +namespace dr1584 { + // Deducing function types from cv-qualified types + template<typename T> void f(const T *); // expected-note {{candidate template ignored}} + template<typename T> void g(T *, const T * = 0); + template<typename T> void h(T *) { T::error; } // expected-error {{no members}} + template<typename T> void h(const T *); + void i() { + f(&i); // expected-error {{no matching function}} + g(&i); + h(&i); // expected-note {{here}} + } +} + namespace dr1589 { // dr1589: 3.7 c++11 // Ambiguous ranking of list-initialization sequences diff --git a/clang/test/CXX/drs/dr4xx.cpp b/clang/test/CXX/drs/dr4xx.cpp index b7d65e347aa..2d30831fd4a 100644 --- a/clang/test/CXX/drs/dr4xx.cpp +++ b/clang/test/CXX/drs/dr4xx.cpp @@ -796,24 +796,9 @@ namespace dr468 { // dr468: yes c++11 } namespace dr469 { // dr469: no - // FIXME: The core issue here didn't really answer the question. We don't - // deduce 'const T' from a function or reference type in a class template... - template<typename T> struct X; // expected-note 2{{here}} + template<typename T> struct X; // expected-note {{here}} template<typename T> struct X<const T> {}; X<int&> x; // expected-error {{undefined}} - X<int()> y; // expected-error {{undefined}} - - // ... but we do in a function template. GCC and EDG fail deduction of 'f' - // and the second 'h'. - template<typename T> void f(const T *); - template<typename T> void g(T *, const T * = 0); - template<typename T> void h(T *) { T::error; } - template<typename T> void h(const T *); - void i() { - f(&i); - g(&i); - h(&i); - } } namespace dr470 { // dr470: yes diff --git a/clang/test/SemaTemplate/function-pointer-qualifier.cpp b/clang/test/SemaTemplate/function-pointer-qualifier.cpp new file mode 100644 index 00000000000..97d160738a2 --- /dev/null +++ b/clang/test/SemaTemplate/function-pointer-qualifier.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +template<class _Ty> inline + void testparam(_Ty **, _Ty **) + { + } + +template<class _Ty> inline + void testparam(_Ty *const *, _Ty **) + { + } + +template<class _Ty> inline + void testparam(_Ty **, const _Ty **) + { + } + +template<class _Ty> inline + void testparam(_Ty *const *, const _Ty **) + { + } + +void case0() +{ + void (**p1)(); + void (**p2)(); + testparam(p1, p2); +} |

