[PATCH] D69518: [Diagnostics] Warn for std::is_constant_evaluated in constexpr mode

Dávid Bolvanský via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 28 10:25:49 PDT 2019


xbolva00 created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69518

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/SemaCXX/warn-std-is-constant-evaluated-constexpr.cpp


Index: clang/test/SemaCXX/warn-std-is-constant-evaluated-constexpr.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/warn-std-is-constant-evaluated-constexpr.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify -Wtautological-compare %s
+
+namespace std {
+constexpr bool is_constant_evaluated() noexcept {
+  return __builtin_is_constant_evaluated();
+}
+}
+
+constexpr int fn1() {
+  if constexpr (std::is_constant_evaluated()) // expected-warning {{'std::is_constant_evaluated' will always evaluate to 'true' in constexpr mode}}
+    return 0;
+  else
+    return 1;
+}
+
+constexpr int fn2() {
+  if (std::is_constant_evaluated())
+    return 0;
+  else
+    return 1;
+}
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -3675,6 +3675,10 @@
   // expression, implicitly converted to bool.
   //
   // FIXME: Return this value to the caller so they don't need to recompute it.
+  CallExpr *Call = dyn_cast<CallExpr>(CondExpr->IgnoreParens());
+  if (IsConstexpr && Call && Call->isCallToStdIsConstantEvaluated())
+    Diag(Call->getBeginLoc(),
+         diag::warn_std_is_constant_evaluated_always_true_constexpr);
   llvm::APSInt Value(/*BitWidth*/1);
   return (IsConstexpr && !CondExpr->isValueDependent())
              ? CheckConvertedConstantExpression(CondExpr, Context.BoolTy, Value,
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8405,6 +8405,9 @@
   "%select{self-|array }0comparison always evaluates to "
   "%select{a constant|true|false|'std::strong_ordering::equal'}1">,
   InGroup<TautologicalCompare>;
+def warn_std_is_constant_evaluated_always_true_constexpr : Warning<
+  "'std::is_constant_evaluated' will always evaluate to "
+  "'true' in constexpr mode">, InGroup<TautologicalCompare>;
 def warn_comparison_bitwise_always : Warning<
   "bitwise comparison always evaluates to %select{false|true}0">,
   InGroup<TautologicalBitwiseCompare>, DefaultIgnore;
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -2777,6 +2777,13 @@
            FD->getIdentifier() && FD->getIdentifier()->isStr("move");
   }
 
+  bool isCallToStdIsConstantEvaluated() const {
+    const FunctionDecl *FD = getDirectCallee();
+    return getNumArgs() == 0 && FD && FD->isInStdNamespace() &&
+           FD->getIdentifier() &&
+           FD->getIdentifier()->isStr("is_constant_evaluated");
+  }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() >= firstCallExprConstant &&
            T->getStmtClass() <= lastCallExprConstant;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69518.226702.patch
Type: text/x-patch
Size: 3033 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191028/b638ac34/attachment.bin>


More information about the cfe-commits mailing list