mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 06:10:12 +00:00
[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
This commit is contained in:
parent
87f1343a73
commit
413f3c5595
@ -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");
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
29
clang/test/SemaTemplate/function-pointer-qualifier.cpp
Normal file
29
clang/test/SemaTemplate/function-pointer-qualifier.cpp
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user