yronglin created this revision.
Herald added a project: All.
yronglin requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Signed-off-by: yronglin <yronglin...@gmail.com>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152259

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/bool-SFINAE-friendly.cpp


Index: clang/test/SemaCXX/bool-SFINAE-friendly.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/bool-SFINAE-friendly.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %std_cxx98-14 -fsyntax-only -verify=precxx17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify=expected %s
+// RUN: %clang_cc1 %std_cxx20- -fsyntax-only -verify=cxx20 %s
+// expected-no-diagnostics
+
+template<class T> auto f(T t) -> decltype(++t); // precxx17-warning 
{{incrementing expression of type bool is deprecated}}
+
+auto f(...) -> void;
+void g() { f(true); }
+
+#if __cplusplus >= 202002L
+template <class T>
+concept can_increment = requires(T t) {
+  ++t;
+};
+
+template <class T>
+void f() {
+  static_assert(requires(T t) { ++t; }); // cxx20-error {{static assertion 
failed due to requirement 'requires (bool t) { <<error-expression>>; }'}}
+}
+
+int main() {
+  f<bool>(); // cxx20-note {{in instantiation of function template 
specialization 'f<bool>' requested here}}
+  static_assert(!can_increment<bool>); 
+
+  return 0;
+}
+#endif
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14594,10 +14594,17 @@
       S.Diag(OpLoc, diag::err_decrement_bool) << Op->getSourceRange();
       return QualType();
     }
-    // Increment of bool sets it to true, but is deprecated.
-    S.Diag(OpLoc, S.getLangOpts().CPlusPlus17 ? diag::ext_increment_bool
-                                              : diag::warn_increment_bool)
-      << Op->getSourceRange();
+
+    if (S.getLangOpts().CPlusPlus17) {
+      // Increment of bool sets it to true, but is deprecated.
+      S.Diag(OpLoc, diag::ext_increment_bool) << Op->getSourceRange();
+
+      // Ensure increment bool SFINAE-friendly.
+      if (S.isUnevaluatedContext() || S.isSFINAEContext())
+        return QualType();
+    } else {
+      S.Diag(OpLoc, diag::warn_increment_bool) << Op->getSourceRange();
+    }
   } else if (S.getLangOpts().CPlusPlus && ResType->isEnumeralType()) {
     // Error on enum increments and decrements in C++ mode
     S.Diag(OpLoc, diag::err_increment_decrement_enum) << IsInc << ResType;


Index: clang/test/SemaCXX/bool-SFINAE-friendly.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/bool-SFINAE-friendly.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %std_cxx98-14 -fsyntax-only -verify=precxx17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify=expected %s
+// RUN: %clang_cc1 %std_cxx20- -fsyntax-only -verify=cxx20 %s
+// expected-no-diagnostics
+
+template<class T> auto f(T t) -> decltype(++t); // precxx17-warning {{incrementing expression of type bool is deprecated}}
+
+auto f(...) -> void;
+void g() { f(true); }
+
+#if __cplusplus >= 202002L
+template <class T>
+concept can_increment = requires(T t) {
+  ++t;
+};
+
+template <class T>
+void f() {
+  static_assert(requires(T t) { ++t; }); // cxx20-error {{static assertion failed due to requirement 'requires (bool t) { <<error-expression>>; }'}}
+}
+
+int main() {
+  f<bool>(); // cxx20-note {{in instantiation of function template specialization 'f<bool>' requested here}}
+  static_assert(!can_increment<bool>); 
+
+  return 0;
+}
+#endif
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14594,10 +14594,17 @@
       S.Diag(OpLoc, diag::err_decrement_bool) << Op->getSourceRange();
       return QualType();
     }
-    // Increment of bool sets it to true, but is deprecated.
-    S.Diag(OpLoc, S.getLangOpts().CPlusPlus17 ? diag::ext_increment_bool
-                                              : diag::warn_increment_bool)
-      << Op->getSourceRange();
+
+    if (S.getLangOpts().CPlusPlus17) {
+      // Increment of bool sets it to true, but is deprecated.
+      S.Diag(OpLoc, diag::ext_increment_bool) << Op->getSourceRange();
+
+      // Ensure increment bool SFINAE-friendly.
+      if (S.isUnevaluatedContext() || S.isSFINAEContext())
+        return QualType();
+    } else {
+      S.Diag(OpLoc, diag::warn_increment_bool) << Op->getSourceRange();
+    }
   } else if (S.getLangOpts().CPlusPlus && ResType->isEnumeralType()) {
     // Error on enum increments and decrements in C++ mode
     S.Diag(OpLoc, diag::err_increment_decrement_enum) << IsInc << ResType;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to