summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-05-09 05:17:00 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-05-09 05:17:00 +0000
commit6f8d2c6c9c3451effdf075a7034bbe77045bfeba (patch)
tree9f37148d4c839abe13285781974985cee8bcf443 /clang/test
parent9133c34a2a35c26692c8387763b517f808117c6f (diff)
downloadbcm5719-llvm-6f8d2c6c9c3451effdf075a7034bbe77045bfeba.tar.gz
bcm5719-llvm-6f8d2c6c9c3451effdf075a7034bbe77045bfeba.zip
A little tweak to the SFINAE condition reporting. Don't say:
candidate template ignored: substitution failed [with T = int]: no type named 'type' in 'std::enable_if<false, void>' Instead, just say: candidate template ignored: disabled by 'enable_if' [with T = int] ... and point at the enable_if condition which (we assume) failed. This is applied to all cases where the user writes 'typename enable_if<...>::type' (optionally prefixed with a nested name specifier), and 'enable_if<...>' names a complete class type which does not have a member named 'type', and this results in a candidate function being ignored in a SFINAE context. Thus it catches 'std::enable_if', 'std::__1::enable_if', 'boost::enable_if' and 'llvm::enable_if'. llvm-svn: 156463
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/SemaTemplate/overload-candidates.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index 23ca1d47f1a..dc6d2a51ec2 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -40,3 +40,25 @@ struct X {
void test_X_min(X x) {
(void)x.min(1, 2l); // expected-error{{no matching member function for call to 'min'}}
}
+
+namespace boost {
+ template<bool, typename = void> struct enable_if {};
+ template<typename T> struct enable_if<true, T> { typedef T type; };
+}
+template<typename T> typename boost::enable_if<sizeof(T) == 4, int>::type if_size_4(); // expected-note{{candidate template ignored: disabled by 'enable_if' [with T = char]}}
+int k = if_size_4<char>(); // expected-error{{no matching function}}
+
+namespace llvm {
+ template<typename Cond, typename T = void> struct enable_if : boost::enable_if<Cond::value, T> {};
+}
+template<typename T> struct is_int { enum { value = false }; };
+template<> struct is_int<int> { enum { value = true }; };
+template<typename T> typename llvm::enable_if<is_int<T> >::type if_int(); // expected-note{{candidate template ignored: disabled by 'enable_if' [with T = char]}}
+void test_if_int() {
+ if_int<char>(); // expected-error{{no matching function}}
+}
+
+template<typename T> struct NonTemplateFunction {
+ typename boost::enable_if<sizeof(T) == 4, int>::type f(); // expected-error{{no type named 'type' in 'boost::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration}}
+};
+NonTemplateFunction<char> NTFC; // expected-note{{here}}
OpenPOWER on IntegriCloud