This revision was automatically updated to reflect the committed changes.
Closed by commit rG2b4cad5e471c: [clang] Enable the special enable_if_t
diagnostics for libc++'s __enable_if_t… (authored by arthur.j.odwyer).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D109411/new/
https://reviews.llvm.org/D109411
Files:
clang/lib/Sema/SemaTemplate.cpp
clang/test/SemaTemplate/diagnose-enable-if-t.cpp
Index: clang/test/SemaTemplate/diagnose-enable-if-t.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaTemplate/diagnose-enable-if-t.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+namespace std {
+ inline namespace __1 {
+ template<bool, class = void> struct enable_if {};
+ template<class T> struct enable_if<true, T> { using type = T; };
+ template<bool B, class T = void> using enable_if_t = typename enable_if<B, T>::type;
+ }
+}
+
+namespace similar_to_user_code {
+ // expected-note@+2 {{candidate template ignored: requirement 'sizeof(char) != 1' was not satisfied [with T = char]}}
+ template<class T, class = std::enable_if_t<sizeof(T) != 1>>
+ void f(T, short);
+
+ // expected-note@+2 {{candidate template ignored: requirement 'sizeof(char) != 1' was not satisfied [with T = char]}}
+ template<class T, std::enable_if_t<sizeof(T) != 1>* = nullptr>
+ void f(T, int);
+
+ // expected-note@+2 {{candidate template ignored: requirement 'sizeof(char) != 1' was not satisfied [with T = char]}}
+ template<class T>
+ std::enable_if_t<sizeof(T) != 1, void> f(T, long);
+
+ void test() {
+ f('x', 0); // expected-error{{no matching function}}
+ }
+}
+
+namespace similar_to_libcxx_version_14 {
+ template<bool, class = void> struct enable_if {};
+ template<class T> struct enable_if<true, T> { using type = T; };
+ template<bool B, class T = void> using __enable_if_t = typename enable_if<B, T>::type;
+
+ // expected-note@+2 {{candidate template ignored: requirement 'sizeof(char) != 1' was not satisfied [with T = char]}}
+ template<class T, class = __enable_if_t<sizeof(T) != 1>>
+ void f(T, short);
+
+ // expected-note@+2 {{candidate template ignored: requirement 'sizeof(char) != 1' was not satisfied [with T = char]}}
+ template<class T, __enable_if_t<sizeof(T) != 1>* = nullptr>
+ void f(T, int);
+
+ // expected-note@+2 {{candidate template ignored: requirement 'sizeof(char) != 1' was not satisfied [with T = char]}}
+ template<class T>
+ __enable_if_t<sizeof(T) != 1, void> f(T, long);
+
+ void test() {
+ f('x', 0); // expected-error{{no matching function}}
+ }
+}
+
+namespace similar_to_libcxx_version_13 {
+ template<bool> struct _MetaBase {};
+ template<> struct _MetaBase<true> { template<class R> using _EnableIfImpl = R; };
+ template<bool B, class T = void> using _EnableIf = typename _MetaBase<B>::template _EnableIfImpl<T>;
+
+ // expected-note@+2 {{no member named '_EnableIfImpl'}}
+ template<class T, class = _EnableIf<sizeof(T) != 1>>
+ void f(T, short);
+
+ // expected-note@+2 {{no member named '_EnableIfImpl'}}
+ template<class T, _EnableIf<sizeof(T) != 1>* = nullptr>
+ void f(T, int);
+
+ // expected-note@+2 {{no member named '_EnableIfImpl'}}
+ template<class T>
+ _EnableIf<sizeof(T) != 1, void> f(T, long);
+
+ void test() {
+ f('x', 0); // expected-error{{no matching function}}
+ }
+}
+
+namespace not_all_names_are_magic {
+ template<bool, class = void> struct enable_if {};
+ template<class T> struct enable_if<true, T> { using type = T; };
+ template<bool B, class T = void> using a_pony = typename enable_if<B, T>::type;
+
+ // expected-note@-2 {{candidate template ignored: disabled by 'enable_if' [with T = char]}}
+ template<class T, class = a_pony<sizeof(T) != 1>>
+ void f(T, short);
+
+ // expected-note@-6 {{candidate template ignored: disabled by 'enable_if' [with T = char]}}
+ template<class T, a_pony<sizeof(T) != 1>* = nullptr>
+ void f(T, int);
+
+ // expected-note@-10 {{candidate template ignored: disabled by 'enable_if' [with T = char]}}
+ template<class T>
+ a_pony<sizeof(T) != 1, void> f(T, long);
+
+ void test() {
+ f('x', 0); // expected-error{{no matching function}}
+ }
+}
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -3511,8 +3511,10 @@
}
/// Determine whether this alias template is "enable_if_t".
+/// libc++ >=14 uses "__enable_if_t" in C++11 mode.
static bool isEnableIfAliasTemplate(TypeAliasTemplateDecl *AliasTemplate) {
- return AliasTemplate->getName().equals("enable_if_t");
+ return AliasTemplate->getName().equals("enable_if_t") ||
+ AliasTemplate->getName().equals("__enable_if_t");
}
/// Collect all of the separable terms in the given condition, which
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits