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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to