[clang] 880fa7f - Revert "[clang][SemaCXX] Diagnose tautological uses of consteval if and is_constant_evaluated"

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 27 09:58:13 PDT 2023


Author: Sam McCall
Date: 2023-09-27T18:58:01+02:00
New Revision: 880fa7faa97bad63e403c924263b01fb81783227

URL: https://github.com/llvm/llvm-project/commit/880fa7faa97bad63e403c924263b01fb81783227
DIFF: https://github.com/llvm/llvm-project/commit/880fa7faa97bad63e403c924263b01fb81783227.diff

LOG: Revert "[clang][SemaCXX] Diagnose tautological uses of consteval if and is_constant_evaluated"

This reverts commit 491b2810fb7fe5f080fa9c4f5945ed0a6909dc92.

This change broke valid code and generated incorrect diagnostics, see
https://reviews.llvm.org/D155064

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticASTKinds.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Parse/Parser.h
    clang/include/clang/Sema/Sema.h
    clang/lib/AST/ExprConstant.cpp
    clang/lib/Parse/ParseDecl.cpp
    clang/lib/Parse/ParseDeclCXX.cpp
    clang/lib/Parse/ParseExpr.cpp
    clang/lib/Parse/ParseExprCXX.cpp
    clang/lib/Parse/ParseStmt.cpp
    clang/lib/Sema/SemaChecking.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaLambda.cpp
    clang/lib/Sema/SemaStmt.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/test/AST/Interp/builtins.cpp
    clang/test/AST/Interp/if.cpp
    clang/test/AST/Interp/literals.cpp
    clang/test/CXX/expr/expr.const/p2-0x.cpp
    clang/test/CXX/expr/expr.const/p6-2a.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
    clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p4.cpp
    clang/test/Parser/pragma-fenv_access.c
    clang/test/SemaCXX/constant-conversion.cpp
    clang/test/SemaCXX/constant-expression-cxx11.cpp
    clang/test/SemaCXX/cxx2a-consteval.cpp
    clang/test/SemaCXX/cxx2b-consteval-if.cpp
    clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
    clang/test/SemaCXX/vartemplate-lambda.cpp
    clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
    clang/test/SemaTemplate/concepts.cpp
    clang/unittests/Support/TimeProfilerTest.cpp
    libcxx/include/__type_traits/is_constant_evaluated.h
    libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp
    libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.verify.cpp

Removed: 
    clang/test/SemaCXX/fixit-tautological-meta-constant.cpp
    clang/test/SemaCXX/warn-tautological-meta-constant.cpp


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fb52b90ae4a3cb9..68172d5317a13ba 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -206,12 +206,6 @@ Improvements to Clang's diagnostics
 - Clang no longer emits irrelevant notes about unsatisfied constraint expressions
   on the left-hand side of ``||`` when the right-hand side constraint is satisfied.
   (`#54678: <https://github.com/llvm/llvm-project/issues/54678>`_).
-- Clang now diagnoses wider cases of tautological use of consteval if or
-  ``std::is_constant_evaluated``. This also suppresses some false positives.
-  (`#43760: <https://github.com/llvm/llvm-project/issues/43760>`_)
-  (`#51567: <https://github.com/llvm/llvm-project/issues/51567>`_)
-- Clang now diagnoses narrowing implicit conversions on variable initializers in immediate
-  function context and on constexpr variable template initializers.
 - Clang now prints its 'note' diagnostic in cyan instead of black, to be more compatible
   with terminals with dark background colors. This is also more consistent with GCC.
 

diff  --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 1abb0b89af9f1c1..d2656310e79c9b8 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -413,6 +413,10 @@ def warn_constexpr_unscoped_enum_out_of_range : Warning<
 def note_unimplemented_constexpr_lambda_feature_ast : Note<
     "unimplemented constexpr lambda feature: %0 (coming soon!)">;
 
+def warn_is_constant_evaluated_always_true_constexpr : Warning<
+  "'%0' will always evaluate to 'true' in a manifestly constant-evaluated expression">,
+  InGroup<DiagGroup<"constant-evaluated">>;
+
 // inline asm related.
 let CategoryName = "Inline Assembly Issue" in {
   def err_asm_invalid_escape : Error<

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3f30681a378e24f..f4eb02fd9570c2f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1591,8 +1591,8 @@ def err_static_assert_message_constexpr : Error<
   "the message in a static assertion must be produced by a "
   "constant expression">;
 
-def warn_tautological_consteval_if : Warning<
-  "consteval if is always %select{true|false}0 in this context">,
+def warn_consteval_if_always_true : Warning<
+  "consteval if is always true in an %select{unevaluated|immediate}0 context">,
   InGroup<DiagGroup<"redundant-consteval-if">>;
 
 def ext_inline_variable : ExtWarn<
@@ -8897,9 +8897,6 @@ def warn_side_effects_unevaluated_context : Warning<
 def warn_side_effects_typeid : Warning<
   "expression with side effects will be evaluated despite being used as an "
   "operand to 'typeid'">, InGroup<PotentiallyEvaluatedExpression>;
-def warn_tautological_is_constant_evaluated : Warning<
-  "'%select{std::is_constant_evaluated|__builtin_is_constant_evaluated}0' will always evaluate to %select{false|true}1 in this context">,
-  InGroup<DiagGroup<"constant-evaluated">>;
 def warn_unused_result : Warning<
   "ignoring return value of function declared with %0 attribute">,
   InGroup<UnusedResult>;

diff  --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index ae3c265f40a2c76..f599b8b98d031fb 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2003,10 +2003,12 @@ class Parser : public CodeCompletionHandler {
   //===--------------------------------------------------------------------===//
   // C++ if/switch/while/for condition expression.
   struct ForRangeInfo;
-  Sema::ConditionResult ParseCXXCondition(
-      StmtResult *InitStmt, SourceLocation Loc, Sema::ConditionKind CK,
-      bool MissingOK, ForRangeInfo *FRI = nullptr,
-      bool EnterForConditionScope = false, SourceLocation ConstexprLoc = {});
+  Sema::ConditionResult ParseCXXCondition(StmtResult *InitStmt,
+                                          SourceLocation Loc,
+                                          Sema::ConditionKind CK,
+                                          bool MissingOK,
+                                          ForRangeInfo *FRI = nullptr,
+                                          bool EnterForConditionScope = false);
   DeclGroupPtrTy ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
                                                       ParsedAttributes &Attrs);
 
@@ -2104,8 +2106,7 @@ class Parser : public CodeCompletionHandler {
                                  Sema::ConditionResult &CondResult,
                                  SourceLocation Loc, Sema::ConditionKind CK,
                                  SourceLocation &LParenLoc,
-                                 SourceLocation &RParenLoc,
-                                 SourceLocation ConstexprLoc = {});
+                                 SourceLocation &RParenLoc);
   StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
   StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
   StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e4366170005a044..712db0a3dd895d5 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1358,9 +1358,6 @@ class Sema final {
     bool InDiscardedStatement;
     bool InImmediateFunctionContext;
     bool InImmediateEscalatingFunctionContext;
-    // The immediate occurances of consteval if or std::is_constant_evaluated()
-    // are tautologically false
-    bool IsRuntimeEvaluated;
 
     bool IsCurrentlyCheckingDefaultArgumentOrInitializer = false;
 
@@ -1390,8 +1387,7 @@ class Sema final {
           NumCleanupObjects(NumCleanupObjects), NumTypos(0),
           ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext),
           InDiscardedStatement(false), InImmediateFunctionContext(false),
-          InImmediateEscalatingFunctionContext(false),
-          IsRuntimeEvaluated(false) {}
+          InImmediateEscalatingFunctionContext(false) {}
 
     bool isUnevaluated() const {
       return Context == ExpressionEvaluationContext::Unevaluated ||
@@ -1430,10 +1426,6 @@ class Sema final {
   /// A stack of expression evaluation contexts.
   SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
 
-  /// Source location of the start of `constexpr` in constexpr-if
-  /// used for diagnostics
-  SourceLocation ConstexprIfLoc;
-
   // Set of failed immediate invocations to avoid double diagnosing.
   llvm::SmallPtrSet<ConstantExpr *, 4> FailedImmediateInvocations;
 

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 310debe327017cd..fea06b97259fe31 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -12178,6 +12178,22 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
   }
 
   case Builtin::BI__builtin_is_constant_evaluated: {
+    const auto *Callee = Info.CurrentCall->getCallee();
+    if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
+        (Info.CallStackDepth == 1 ||
+         (Info.CallStackDepth == 2 && Callee->isInStdNamespace() &&
+          Callee->getIdentifier() &&
+          Callee->getIdentifier()->isStr("is_constant_evaluated")))) {
+      // FIXME: Find a better way to avoid duplicated diagnostics.
+      if (Info.EvalStatus.Diag)
+        Info.report((Info.CallStackDepth == 1)
+                        ? E->getExprLoc()
+                        : Info.CurrentCall->getCallRange().getBegin(),
+                    diag::warn_is_constant_evaluated_always_true_constexpr)
+            << (Info.CallStackDepth == 1 ? "__builtin_is_constant_evaluated"
+                                         : "std::is_constant_evaluated");
+    }
+
     return Success(Info.InConstantContext, E);
   }
 

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index f5b4107cc32c1f0..748b9d53c9f5b33 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2461,15 +2461,6 @@ Decl *Parser::ParseDeclarationAfterDeclarator(
   return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
 }
 
-/// Determine whether the given declaration is a global variable or
-/// static data member.
-static bool isNonlocalVariable(const Decl *D) {
-  if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(D))
-    return Var->hasGlobalStorage();
-
-  return false;
-}
-
 Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
     Declarator &D, const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
   // RAII type used to track whether we're inside an initializer.
@@ -2502,36 +2493,6 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
       ThisDecl = nullptr;
     }
   };
-  struct EnterInitializerExpressionEvaluationContext {
-    Sema &S;
-    bool Entered;
-
-    EnterInitializerExpressionEvaluationContext(Sema &S, Declarator &D,
-                                                Decl *ThisDecl)
-        : S(S), Entered(false) {
-      if (ThisDecl && S.getLangOpts().CPlusPlus && !ThisDecl->isInvalidDecl()) {
-        Entered = true;
-        bool RuntimeEvaluated = S.ExprEvalContexts.back().IsRuntimeEvaluated;
-        Sema::ExpressionEvaluationContext NewEEC =
-            S.ExprEvalContexts.back().Context;
-        if ((D.getDeclSpec().getTypeQualifiers() == DeclSpec::TQ_const ||
-             isNonlocalVariable(ThisDecl)) &&
-            S.ExprEvalContexts.back().IsRuntimeEvaluated) {
-          RuntimeEvaluated = false;
-        }
-        if (D.getDeclSpec().hasConstexprSpecifier()) {
-          NewEEC = Sema::ExpressionEvaluationContext::ConstantEvaluated;
-          RuntimeEvaluated = false;
-        }
-        S.PushExpressionEvaluationContext(NewEEC, ThisDecl);
-        S.ExprEvalContexts.back().IsRuntimeEvaluated = RuntimeEvaluated;
-      }
-    }
-    ~EnterInitializerExpressionEvaluationContext() {
-      if (Entered)
-        S.PopExpressionEvaluationContext();
-    }
-  };
 
   enum class InitKind { Uninitialized, Equal, CXXDirect, CXXBraced };
   InitKind TheInitKind;
@@ -2631,7 +2592,6 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
             << getLangOpts().CPlusPlus20;
     } else {
       InitializerScopeRAII InitScope(*this, D, ThisDecl);
-      EnterInitializerExpressionEvaluationContext InitEC(Actions, D, ThisDecl);
 
       if (Tok.is(tok::code_completion)) {
         cutOffParsing();
@@ -2679,7 +2639,6 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
     ExprVector Exprs;
 
     InitializerScopeRAII InitScope(*this, D, ThisDecl);
-    EnterInitializerExpressionEvaluationContext InitEC(Actions, D, ThisDecl);
 
     auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
     auto RunSignatureHelp = [&]() {
@@ -2730,7 +2689,6 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
     Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
 
     InitializerScopeRAII InitScope(*this, D, ThisDecl);
-    EnterInitializerExpressionEvaluationContext InitEC(Actions, D, ThisDecl);
 
     PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl);
     ExprResult Init(ParseBraceInitializer());

diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index e5a278c598cfb63..5a6b5efbf6c1223 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -3234,14 +3234,9 @@ ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
 
   bool IsFieldInitialization = isa_and_present<FieldDecl>(D);
 
-  bool IsConstexpr = false;
-  if (const auto *VD = dyn_cast_if_present<VarDecl>(D))
-    IsConstexpr = VD->isConstexpr();
-
   EnterExpressionEvaluationContext Context(
       Actions,
-      IsConstexpr ? Sema::ExpressionEvaluationContext::ConstantEvaluated
-      : IsFieldInitialization
+      IsFieldInitialization
           ? Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed
           : Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
       D);

diff  --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 0e69be6bcb3ce4e..74664c34abdbd89 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2093,13 +2093,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
       };
       if (OpKind == tok::l_paren || !LHS.isInvalid()) {
         if (Tok.isNot(tok::r_paren)) {
-          // FIXME: arguments in consteval functions are constant expression
-          // regardless of the evaluation context of callsite. However, we
-          // cannot know whether the called function is constevasl before the
-          // declaration is resolved.
-          bool IsRuntimeEvaluated =
-              Actions.ExprEvalContexts.back().IsRuntimeEvaluated;
-          Actions.ExprEvalContexts.back().IsRuntimeEvaluated = false;
           if (ParseExpressionList(ArgExprs, [&] {
                 PreferredType.enterFunctionArgument(Tok.getLocation(),
                                                     RunSignatureHelp);
@@ -2116,8 +2109,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
             for (auto &E : ArgExprs)
               Actions.CorrectDelayedTyposInExpr(E);
           }
-          Actions.ExprEvalContexts.back().IsRuntimeEvaluated =
-              IsRuntimeEvaluated;
         }
       }
 

diff  --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index d20d400e3076e9f..99b4931004546c1 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -2041,8 +2041,7 @@ Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
 Sema::ConditionResult
 Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc,
                           Sema::ConditionKind CK, bool MissingOK,
-                          ForRangeInfo *FRI, bool EnterForConditionScope,
-                          SourceLocation ConstexprLoc) {
+                          ForRangeInfo *FRI, bool EnterForConditionScope) {
   // Helper to ensure we always enter a continue/break scope if requested.
   struct ForConditionScopeRAII {
     Scope *S;
@@ -2099,28 +2098,9 @@ Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc,
       *InitStmt = Actions.ActOnNullStmt(SemiLoc);
       return ParseCXXCondition(nullptr, Loc, CK, MissingOK);
     }
-    bool InitStmtIsExprStmt = false;
-    if (InitStmt) {
-      RevertingTentativeParsingAction PA(*this);
-      SkipUntil(tok::r_paren, tok::semi, StopBeforeMatch);
-      InitStmtIsExprStmt = Tok.is(tok::semi);
-    }
 
-    ExprResult Expr; // expression
-    {
-      EnterExpressionEvaluationContext Consteval(
-          Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated,
-          /*LambdaContextDecl=*/nullptr,
-          Sema::ExpressionEvaluationContextRecord::EK_Other,
-          /*ShouldEnter=*/CK == Sema::ConditionKind::ConstexprIf &&
-              !InitStmtIsExprStmt);
-      SourceLocation OuterConstexprIfLoc = Actions.ConstexprIfLoc;
-      Actions.ConstexprIfLoc = ConstexprLoc;
-
-      // Parse the expression.
-      Expr = ParseExpression(); // expression
-      Actions.ConstexprIfLoc = OuterConstexprIfLoc;
-    }
+    // Parse the expression.
+    ExprResult Expr = ParseExpression(); // expression
     if (Expr.isInvalid())
       return Sema::ConditionError();
 
@@ -2208,21 +2188,6 @@ Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc,
   if (CopyInitialization)
     ConsumeToken();
 
-  Sema::ExpressionEvaluationContext NewEEC =
-      Actions.ExprEvalContexts.back().Context;
-  bool RuntimeEvaluated = Actions.ExprEvalContexts.back().IsRuntimeEvaluated;
-  if (DS.getTypeQualifiers() == DeclSpec::TQ_const)
-    RuntimeEvaluated = false;
-
-  if (CK == Sema::ConditionKind::ConstexprIf || DS.hasConstexprSpecifier()) {
-    RuntimeEvaluated = false;
-    NewEEC = Sema::ExpressionEvaluationContext::ConstantEvaluated;
-  }
-  EnterExpressionEvaluationContext Initializer(Actions, NewEEC, DeclOut);
-  Actions.ExprEvalContexts.back().IsRuntimeEvaluated = RuntimeEvaluated;
-  SourceLocation OuterConstexprIfLoc = Actions.ConstexprIfLoc;
-  Actions.ConstexprIfLoc = ConstexprLoc;
-
   ExprResult InitExpr = ExprError();
   if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
     Diag(Tok.getLocation(),
@@ -2249,7 +2214,6 @@ Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc,
     Actions.ActOnInitializerError(DeclOut);
 
   Actions.FinalizeDeclaration(DeclOut);
-  Actions.ConstexprIfLoc = OuterConstexprIfLoc;
   return Actions.ActOnConditionVariable(DeclOut, Loc, CK);
 }
 

diff  --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 75c689f21efa2b1..2531147c23196ae 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1293,17 +1293,18 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
 /// errors in the condition.
 /// Additionally, it will assign the location of the outer-most '(' and ')',
 /// to LParenLoc and RParenLoc, respectively.
-bool Parser::ParseParenExprOrCondition(
-    StmtResult *InitStmt, Sema::ConditionResult &Cond, SourceLocation Loc,
-    Sema::ConditionKind CK, SourceLocation &LParenLoc,
-    SourceLocation &RParenLoc, SourceLocation ConstexprLoc) {
+bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,
+                                       Sema::ConditionResult &Cond,
+                                       SourceLocation Loc,
+                                       Sema::ConditionKind CK,
+                                       SourceLocation &LParenLoc,
+                                       SourceLocation &RParenLoc) {
   BalancedDelimiterTracker T(*this, tok::l_paren);
   T.consumeOpen();
   SourceLocation Start = Tok.getLocation();
 
   if (getLangOpts().CPlusPlus) {
-    Cond = ParseCXXCondition(InitStmt, Loc, CK, false, nullptr, false,
-                             ConstexprLoc);
+    Cond = ParseCXXCondition(InitStmt, Loc, CK, false);
   } else {
     ExprResult CondExpr = ParseExpression();
 
@@ -1463,13 +1464,12 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
   bool IsConsteval = false;
   SourceLocation NotLocation;
   SourceLocation ConstevalLoc;
-  SourceLocation ConstexprLoc;
 
   if (Tok.is(tok::kw_constexpr)) {
     Diag(Tok, getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if
                                         : diag::ext_constexpr_if);
     IsConstexpr = true;
-    ConstexprLoc = ConsumeToken();
+    ConsumeToken();
   } else {
     if (Tok.is(tok::exclaim)) {
       NotLocation = ConsumeToken();
@@ -1515,7 +1515,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
     if (ParseParenExprOrCondition(&InitStmt, Cond, IfLoc,
                                   IsConstexpr ? Sema::ConditionKind::ConstexprIf
                                               : Sema::ConditionKind::Boolean,
-                                  LParen, RParen, ConstexprLoc))
+                                  LParen, RParen))
       return StmtError();
 
     if (IsConstexpr)
@@ -1558,16 +1558,11 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
     if (NotLocation.isInvalid() && IsConsteval) {
       Context = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
       ShouldEnter = true;
-    } else if (NotLocation.isValid() && IsConsteval) {
-      Context = Actions.ExprEvalContexts.back().Context;
-      ShouldEnter = true;
     }
 
     EnterExpressionEvaluationContext PotentiallyDiscarded(
         Actions, Context, nullptr,
         Sema::ExpressionEvaluationContextRecord::EK_Other, ShouldEnter);
-    if (NotLocation.isValid() && IsConsteval)
-      Actions.ExprEvalContexts.back().IsRuntimeEvaluated = true;
     ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
   }
 
@@ -1608,16 +1603,11 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
     if (NotLocation.isValid() && IsConsteval) {
       Context = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
       ShouldEnter = true;
-    } else if (NotLocation.isInvalid() && IsConsteval) {
-      Context = Actions.ExprEvalContexts.back().Context;
-      ShouldEnter = true;
     }
 
     EnterExpressionEvaluationContext PotentiallyDiscarded(
         Actions, Context, nullptr,
         Sema::ExpressionEvaluationContextRecord::EK_Other, ShouldEnter);
-    if (NotLocation.isInvalid() && IsConsteval)
-      Actions.ExprEvalContexts.back().IsRuntimeEvaluated = true;
     ElseStmt = ParseStatement();
 
     if (ElseStmt.isUsable())

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d4bedf75963ac7..6a3b5fa61d59456 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14836,8 +14836,7 @@ static void DiagnoseIntInBoolContext(Sema &S, Expr *E) {
 static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
                                     SourceLocation CC,
                                     bool *ICContext = nullptr,
-                                    bool IsListInit = false,
-                                    bool IsConstexprInit = false) {
+                                    bool IsListInit = false) {
   if (E->isTypeDependent() || E->isValueDependent()) return;
 
   const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr();
@@ -15146,14 +15145,11 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
           SmallString<32> PrettyTargetValue;
           TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
 
-          PartialDiagnostic PD =
+          S.DiagRuntimeBehavior(
+              E->getExprLoc(), E,
               S.PDiag(diag::warn_impcast_integer_float_precision_constant)
-              << PrettySourceValue << PrettyTargetValue << E->getType() << T
-              << E->getSourceRange() << clang::SourceRange(CC);
-          if (IsConstexprInit)
-            S.Diag(E->getExprLoc(), PD);
-          else
-            S.DiagRuntimeBehavior(E->getExprLoc(), E, PD);
+                  << PrettySourceValue << PrettyTargetValue << E->getType() << T
+                  << E->getSourceRange() << clang::SourceRange(CC));
         }
       } else {
         // Otherwise, the implicit conversion may lose precision.
@@ -15207,14 +15203,11 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
       std::string PrettySourceValue = toString(Value, 10);
       std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange);
 
-      PartialDiagnostic PD =
+      S.DiagRuntimeBehavior(
+          E->getExprLoc(), E,
           S.PDiag(diag::warn_impcast_integer_precision_constant)
-          << PrettySourceValue << PrettyTargetValue << E->getType() << T
-          << E->getSourceRange() << SourceRange(CC);
-      if (IsConstexprInit)
-        S.Diag(E->getExprLoc(), PD);
-      else
-        S.DiagRuntimeBehavior(E->getExprLoc(), E, PD);
+              << PrettySourceValue << PrettyTargetValue << E->getType() << T
+              << E->getSourceRange() << SourceRange(CC));
       return;
     }
 
@@ -15256,14 +15249,11 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
         std::string PrettySourceValue = toString(Value, 10);
         std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange);
 
-        PartialDiagnostic PD =
+        S.DiagRuntimeBehavior(
+            E->getExprLoc(), E,
             S.PDiag(diag::warn_impcast_integer_precision_constant)
-            << PrettySourceValue << PrettyTargetValue << E->getType() << T
-            << E->getSourceRange() << SourceRange(CC);
-        if (IsConstexprInit)
-          S.Diag(E->getExprLoc(), PD);
-        else
-          S.DiagRuntimeBehavior(E->getExprLoc(), E, PD);
+                << PrettySourceValue << PrettyTargetValue << E->getType() << T
+                << E->getSourceRange() << SourceRange(CC));
         return;
       }
     }
@@ -15425,17 +15415,6 @@ static void AnalyzeImplicitConversions(
     if (auto *Src = OVE->getSourceExpr())
       SourceExpr = Src;
 
-  bool IsConstexprInit =
-      S.isConstantEvaluated() &&
-      isa_and_present<VarDecl>(S.ExprEvalContexts.back().ManglingContextDecl);
-  // Constant-evaluated initializers are not diagnosed by DiagRuntimeBehavior,
-  // but narrowings from the evaluated result to the variable type should be
-  // diagnosed.
-  if (IsConstexprInit && SourceExpr->getType() != T) {
-    CheckImplicitConversion(S, SourceExpr, T, CC, nullptr, IsListInit,
-                            /*IsConstexprInit=*/true);
-  }
-
   if (const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
     if (UO->getOpcode() == UO_Not &&
         UO->getSubExpr()->isKnownToHaveBooleanValue())
@@ -15471,7 +15450,7 @@ static void AnalyzeImplicitConversions(
   // Go ahead and check any implicit conversions we might have skipped.
   // The non-canonical typecheck is just an optimization;
   // CheckImplicitConversion will filter out dead implicit conversions.
-  if (!IsConstexprInit && SourceExpr->getType() != T)
+  if (SourceExpr->getType() != T)
     CheckImplicitConversion(S, SourceExpr, T, CC, nullptr, IsListInit);
 
   // Now continue drilling into this expression.

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 30e4af16944ab5f..7d92e93188610c0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15443,7 +15443,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
 
   // Do not push if it is a lambda because one is already pushed when building
   // the lambda in ActOnStartOfLambdaDefinition().
-  if (!isLambdaCallOperator(FD)) {
+  if (!isLambdaCallOperator(FD))
     // [expr.const]/p14.1
     // An expression or conversion is in an immediate function context if it is
     // potentially evaluated and either: its innermost enclosing non-block scope
@@ -15451,9 +15451,6 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
     PushExpressionEvaluationContext(
         FD->isConsteval() ? ExpressionEvaluationContext::ImmediateFunctionContext
                           : ExprEvalContexts.back().Context);
-    if (!FD->isConsteval() && !FD->isConstexpr())
-      ExprEvalContexts.back().IsRuntimeEvaluated = true;
-  }
 
   // Each ExpressionEvaluationContextRecord also keeps track of whether the
   // context is nested in an immediate function context, so smaller contexts

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 3d5ecfc2eb2562a..0091e0ecf6f3986 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18241,6 +18241,15 @@ void Sema::ActOnPureSpecifier(Decl *D, SourceLocation ZeroLoc) {
     Diag(D->getLocation(), diag::err_illegal_initializer);
 }
 
+/// Determine whether the given declaration is a global variable or
+/// static data member.
+static bool isNonlocalVariable(const Decl *D) {
+  if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(D))
+    return Var->hasGlobalStorage();
+
+  return false;
+}
+
 /// Invoked when we are about to parse an initializer for the declaration
 /// 'Dcl'.
 ///
@@ -18263,6 +18272,9 @@ void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
   // If we are parsing the initializer for a static data member, push a
   // new expression evaluation context that is associated with this static
   // data member.
+  if (isNonlocalVariable(D))
+    PushExpressionEvaluationContext(
+        ExpressionEvaluationContext::PotentiallyEvaluated, D);
 }
 
 /// Invoked after we are finished parsing an initializer for the declaration D.
@@ -18271,6 +18283,9 @@ void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) {
   if (!D || D->isInvalidDecl())
     return;
 
+  if (isNonlocalVariable(D))
+    PopExpressionEvaluationContext();
+
   if (S && D->isOutOfLine())
     ExitDeclaratorContext(S);
 }

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 305b43743774788..92496b03ecabe54 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7091,32 +7091,6 @@ static void DiagnosedUnqualifiedCallsToStdFunctions(Sema &S,
       << FixItHint::CreateInsertion(DRE->getLocation(), "std::");
 }
 
-// Diagnose uses of std::is_constant_evaluated or
-// __builtin_is_constant_evaluated in contexts where the result is known at
-// compile time.
-static void DiagnoseTautologicalCallToIsConstantEvaluated(Sema &S,
-                                                          const CallExpr *CE) {
-  if (S.inTemplateInstantiation() || CE->getBeginLoc().isMacroID())
-    return;
-  if (const FunctionDecl *FD = CE->getDirectCallee()) {
-    bool IsBuiltin =
-        FD->getBuiltinID() == Builtin::BI__builtin_is_constant_evaluated;
-    SourceLocation ConstexprIfLoc = S.ConstexprIfLoc;
-
-    if ((FD->isInStdNamespace() &&
-         FD->getNameAsString() == "is_constant_evaluated") ||
-        IsBuiltin) {
-      bool AlwaysTrue = S.ExprEvalContexts.back().isConstantEvaluated() ||
-                        S.ExprEvalContexts.back().isUnevaluated();
-      bool AlwaysFalse = S.ExprEvalContexts.back().IsRuntimeEvaluated;
-      if (AlwaysTrue || AlwaysFalse)
-        S.Diag(CE->getBeginLoc(), diag::warn_tautological_is_constant_evaluated)
-            << IsBuiltin << AlwaysTrue
-            << FixItHint::CreateRemoval(ConstexprIfLoc);
-    }
-  }
-}
-
 ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
                                MultiExprArg ArgExprs, SourceLocation RParenLoc,
                                Expr *ExecConfig) {
@@ -7141,10 +7115,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
     Call = ActOnOpenMPCall(Call, Scope, LParenLoc, ArgExprs, RParenLoc,
                            ExecConfig);
   if (LangOpts.CPlusPlus) {
-    if (const auto *CE = dyn_cast<CallExpr>(Call.get())) {
+    if (const auto *CE = dyn_cast<CallExpr>(Call.get()))
       DiagnosedUnqualifiedCallsToStdFunctions(*this, CE);
-      DiagnoseTautologicalCallToIsConstantEvaluated(*this, CE);
-    }
   }
   return Call;
 }
@@ -18636,8 +18608,6 @@ void Sema::PopExpressionEvaluationContext() {
       } else
         llvm_unreachable("Couldn't infer lambda error message.");
 
-      if (auto *VD = dyn_cast_if_present<VarDecl>(Rec.ManglingContextDecl))
-        VD->setInvalidDecl();
       for (const auto *L : Rec.Lambdas)
         Diag(L->getBeginLoc(), D);
     }

diff  --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index bd2c3c2f45d4c0c..1702ddb3ee0fbf0 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1444,13 +1444,12 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
 
   // Enter a new evaluation context to insulate the lambda from any
   // cleanups from the enclosing full-expression.
-  bool InImmediateFunctionContext = isImmediateFunctionContext();
   PushExpressionEvaluationContext(
-      LSI->CallOperator->isConsteval() || InImmediateFunctionContext
+      LSI->CallOperator->isConsteval()
           ? ExpressionEvaluationContext::ImmediateFunctionContext
           : ExpressionEvaluationContext::PotentiallyEvaluated);
   ExprEvalContexts.back().InImmediateFunctionContext =
-      LSI->CallOperator->isConsteval() || InImmediateFunctionContext;
+      LSI->CallOperator->isConsteval();
   ExprEvalContexts.back().InImmediateEscalatingFunctionContext =
       getLangOpts().CPlusPlus20 && LSI->CallOperator->isImmediateEscalating();
 }

diff  --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index c20d0c50b09e1fe..10adfbc406dfbb5 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -933,14 +933,16 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc,
   }
 
   if (ConstevalOrNegatedConsteval) {
-    bool AlwaysTrue = ExprEvalContexts.back().isConstantEvaluated() ||
-                      ExprEvalContexts.back().isUnevaluated();
-    bool AlwaysFalse = ExprEvalContexts.back().IsRuntimeEvaluated;
-    if (AlwaysTrue || AlwaysFalse)
-      Diags.Report(IfLoc, diag::warn_tautological_consteval_if)
-          << (AlwaysTrue
-                  ? StatementKind == IfStatementKind::ConstevalNegated
-                  : StatementKind == IfStatementKind::ConstevalNonNegated);
+    bool Immediate = ExprEvalContexts.back().Context ==
+                     ExpressionEvaluationContext::ImmediateFunctionContext;
+    if (CurContext->isFunctionOrMethod()) {
+      const auto *FD =
+          dyn_cast<FunctionDecl>(Decl::castFromDeclContext(CurContext));
+      if (FD && FD->isImmediateFunction())
+        Immediate = true;
+    }
+    if (isUnevaluatedContext() || Immediate)
+      Diags.Report(IfLoc, diag::warn_consteval_if_always_true) << Immediate;
   }
 
   return BuildIfStmt(IfLoc, StatementKind, LParenLoc, InitStmt, Cond, RParenLoc,

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index c4f1c4e06ac83b3..fa839e9b71a3cf9 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5378,11 +5378,8 @@ void Sema::InstantiateVariableInitializer(
     Var->setImplicitlyInline();
 
   if (OldVar->getInit()) {
-    Sema::ExpressionEvaluationContext InitEvalContext =
-        Var->isConstexpr()
-            ? Sema::ExpressionEvaluationContext::ConstantEvaluated
-            : Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
-    EnterExpressionEvaluationContext Evaluated(*this, InitEvalContext, Var);
+    EnterExpressionEvaluationContext Evaluated(
+        *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var);
 
     // Instantiate the initializer.
     ExprResult Init;

diff  --git a/clang/test/AST/Interp/builtins.cpp b/clang/test/AST/Interp/builtins.cpp
index 90bd290f1d6a4ba..5e2ffe50f374057 100644
--- a/clang/test/AST/Interp/builtins.cpp
+++ b/clang/test/AST/Interp/builtins.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -Wno-constant-evaluated -verify
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -Wno-constant-evaluated -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -verify
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -S -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated
 // RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated %s -S -emit-llvm -o - | FileCheck %s
 

diff  --git a/clang/test/AST/Interp/if.cpp b/clang/test/AST/Interp/if.cpp
index 3d1ed7b7ffe7623..86ae8de6f73ebb7 100644
--- a/clang/test/AST/Interp/if.cpp
+++ b/clang/test/AST/Interp/if.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fexperimental-new-constant-interpreter -Wno-redundant-consteval-if %s -verify
-// RUN: %clang_cc1 -std=c++23 -fsyntax-only -Wno-redundant-consteval-if %s -verify=ref
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fexperimental-new-constant-interpreter %s -verify
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify=ref
 
 // expected-no-diagnostics
 // ref-no-diagnostics

diff  --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp
index 67de4ef6dae2afa..aabc909b3328e48 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -225,11 +225,15 @@ namespace SizeOf {
 #if __cplusplus >= 202002L
   /// FIXME: The following code should be accepted.
   consteval int foo(int n) { // ref-error {{consteval function never produces a constant expression}}
-    return sizeof(int[n]); // ref-note 2 {{not valid in a constant expression}}
+    return sizeof(int[n]); // ref-note 3{{not valid in a constant expression}} \
+                           // expected-note {{not valid in a constant expression}}
   }
-  constinit int var = foo(5); // ref-note {{in call to}} \
+  constinit int var = foo(5); // ref-error {{not a constant expression}} \
+                              // ref-note 2{{in call to}} \
                               // ref-error {{does not have a constant initializer}} \
                               // ref-note {{required by 'constinit' specifier}} \
+                              // expected-error  {{is not a constant expression}} \
+                              // expected-note {{in call to}} \
                               // expected-error {{does not have a constant initializer}} \
                               // expected-note {{required by 'constinit' specifier}} \
 

diff  --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp
index 596df90243b1e20..e3cd057baba75f5 100644
--- a/clang/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp
@@ -244,8 +244,8 @@ namespace UndefinedBehavior {
     constexpr int n13 = n5 + n5; // expected-error {{constant expression}} expected-note {{value -4294967296 is outside the range of }}
     constexpr int n14 = n3 - n5; // expected-error {{constant expression}} expected-note {{value 4294967295 is outside the range of }}
     constexpr int n15 = n5 * n5; // expected-error {{constant expression}} expected-note {{value 4611686018427387904 is outside the range of }}
-    constexpr signed char c1 = 100 * 2; // ok expected-warning {{changes value from 200 to -56}}
-    constexpr signed char c2 = '\x64' * '\2'; // also ok expected-warning {{changes value from 200 to -56}}
+    constexpr signed char c1 = 100 * 2; // ok expected-warning{{changes value}}
+    constexpr signed char c2 = '\x64' * '\2'; // also ok  expected-warning{{changes value}}
     constexpr long long ll1 = 0x7fffffffffffffff; // ok
     constexpr long long ll2 = ll1 + 1; // expected-error {{constant}} expected-note {{ 9223372036854775808 }}
     constexpr long long ll3 = -ll1 - 1; // ok

diff  --git a/clang/test/CXX/expr/expr.const/p6-2a.cpp b/clang/test/CXX/expr/expr.const/p6-2a.cpp
index 7bcf6fdc3d99790..a937474d53b221c 100644
--- a/clang/test/CXX/expr/expr.const/p6-2a.cpp
+++ b/clang/test/CXX/expr/expr.const/p6-2a.cpp
@@ -43,11 +43,12 @@ struct Temporary {
 constexpr Temporary t = {3}; // expected-error {{must have constant destruction}} expected-note {{created here}} expected-note {{in call}}
 
 namespace P1073R3 {
-consteval int f() { return 42; } // expected-note {{declared here}}
+consteval int f() { return 42; } // expected-note 2 {{declared here}}
 consteval auto g() { return f; }
 consteval int h(int (*p)() = g()) { return p(); }
 constexpr int r = h();
-constexpr auto e = g(); // expected-error {{constexpr variable 'e' must be initialized by a constant expression}} \
-                           expected-note {{pointer to a consteval declaration is not a constant expression}}
+constexpr auto e = g();  // expected-error {{call to consteval function 'P1073R3::g' is not a constant expression}} \
+                            expected-error {{constexpr variable 'e' must be initialized by a constant expression}} \
+                            expected-note 2 {{pointer to a consteval declaration is not a constant expression}}
 static_assert(r == 42);
 } // namespace P1073R3

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
index 8b30b5eefd85fc2..db40bd5d1420ef3 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
@@ -16,5 +16,4 @@ constexpr auto literal = []{};
 #if __cplusplus < 201703L
 // expected-error at -2 {{constexpr variable cannot have non-literal type}}
 // expected-note at -3 {{lambda closure types are non-literal types before C++17}}
-// expected-error at -4 {{a lambda expression may not appear inside of a constant expression}}
 #endif

diff  --git a/clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p4.cpp b/clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p4.cpp
index fd2deee249016c2..8d43be6fc904781 100644
--- a/clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p4.cpp
+++ b/clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p4.cpp
@@ -38,8 +38,7 @@ void test_consteval() {
   }() == 1);
 
   if consteval [[likely]] { // expected-warning {{attribute 'likely' has no effect when annotating an 'if consteval' statement}}\
-                            // expected-note 2{{annotating the 'if consteval' statement here}} \
-                            // expected-warning {{consteval if is always false}}
+                            // expected-note 2{{annotating the 'if consteval' statement here}}
 
 
   }
@@ -50,8 +49,7 @@ void test_consteval() {
 }
 
 void test_consteval_jumps() {
-  if consteval { // expected-warning {{consteval if is always false}} \
-                 // expected-note 4{{jump enters controlled statement of consteval if}}
+  if consteval { // expected-note 4{{jump enters controlled statement of consteval if}}
     goto a;
     goto b; // expected-error {{cannot jump from this goto statement to its label}}
   a:;
@@ -67,16 +65,14 @@ void test_consteval_jumps() {
 void test_consteval_switch() {
   int x = 42;
   switch (x) {
-    if consteval { // expected-warning {{consteval if is always false}} \
-                   // expected-note 2{{jump enters controlled statement of consteval if}}
+    if consteval { // expected-note 2{{jump enters controlled statement of consteval if}}
     case 1:;       // expected-error {{cannot jump from switch statement to this case label}}
     default:;      // expected-error {{cannot jump from switch statement to this case label}}
     } else {
     }
   }
   switch (x) {
-    if consteval { // expected-warning {{consteval if is always false}} \
-                   // expected-note 2{{jump enters controlled statement of consteval if}}
+    if consteval { // expected-note 2{{jump enters controlled statement of consteval if}}
     } else {
     case 2:;  // expected-error {{cannot jump from switch statement to this case label}}
     default:; // expected-error {{cannot jump from switch statement to this case label}}
@@ -103,32 +99,32 @@ constexpr int h(int i) { // expected-note {{declared here}}
 }
 
 consteval void warn_in_consteval() {
-  if consteval { // expected-warning {{consteval if is always true in this context}}
-    if consteval {} // expected-warning {{consteval if is always true in this context}}
+  if consteval { // expected-warning {{consteval if is always true in an immediate context}}
+    if consteval {} // expected-warning {{consteval if is always true in an immediate context}}
   }
 }
 
 constexpr void warn_in_consteval2() {
   if consteval {
-    if consteval {} // expected-warning {{consteval if is always true in this context}}
+    if consteval {} // expected-warning {{consteval if is always true in an immediate context}}
   }
 }
 
 auto y = []() consteval {
-  if consteval { // expected-warning {{consteval if is always true in this context}}
-    if consteval {} // expected-warning {{consteval if is always true in this context}}
+  if consteval { // expected-warning {{consteval if is always true in an immediate context}}
+    if consteval {} // expected-warning {{consteval if is always true in an immediate context}}
   }
 };
 
 namespace test_transform {
 int f(auto n) {
-  if consteval { // expected-warning {{consteval if is always false}}
+  if consteval {
     n.foo; //expected-error {{no member named}}
   }
   else {
   }
 
-  if !consteval { // expected-warning {{consteval if is always true}}
+  if !consteval {
     n.foo; //expected-error {{no member named}}
   }
   else {

diff  --git a/clang/test/Parser/pragma-fenv_access.c b/clang/test/Parser/pragma-fenv_access.c
index a626453344ee6e8..76256cff1b49b54 100644
--- a/clang/test/Parser/pragma-fenv_access.c
+++ b/clang/test/Parser/pragma-fenv_access.c
@@ -33,7 +33,7 @@ int main(void) {
   CONST float fnot_too_big = not_too_big;
   CONST int too_big = 0x7ffffff0;
 #if defined(CPP)
-//expected-warning at +2{{implicit conversion from 'const int' to 'const float' changes value from 2147483632 to 2147483648}}
+//expected-warning at +2{{implicit conversion}}
 #endif
   CONST float fbig = too_big; // inexact
 #if !defined(CPP)

diff  --git a/clang/test/SemaCXX/constant-conversion.cpp b/clang/test/SemaCXX/constant-conversion.cpp
index 884166c419764b7..9be8b139e79e228 100644
--- a/clang/test/SemaCXX/constant-conversion.cpp
+++ b/clang/test/SemaCXX/constant-conversion.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify -triple x86_64-apple-darwin %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-apple-darwin %s
 
 // This file tests -Wconstant-conversion, a subcategory of -Wconversion
 // which is on by default.
@@ -31,59 +31,3 @@ void test_bitfield() {
   s.one_bit = 1;    // expected-warning {{implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1}}
   s.one_bit = true; // no-warning
 }
-
-namespace Initializers {
-constexpr char ok = true ? 0 : 200;
-constexpr char a = 200; // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 200 to -56}}
-char b = 200; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 200 to -56}}
-const char c = 200; // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 200 to -56}}
-
-void f() {
-  constexpr char a = 200; // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 200 to -56}}
-  char b = 200; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 200 to -56}}
-  const char c = 200; // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 200 to -56}}
-  static char d = 2 * 100; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 200 to -56}}
-}
-
-constexpr void g() {
-  constexpr char a = 2 * 100; // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 200 to -56}}
-  char b = 2 * 100; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 200 to -56}}
-  const char c = 2 * 100; // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 200 to -56}}
-}
-
-consteval void h() {
-  char ok = true ? 0 : 200;
-  constexpr char a = 200; // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 200 to -56}}
-  char b = 200; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 200 to -56}}
-  const char c = 200; // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 200 to -56}}
-}
-
-template <int N>
-int templ() {
-  constexpr char a = false ? 129 : N; // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 200 to -56}} \
-                                      // expected-warning {{implicit conversion from 'int' to 'const char' changes value from 345 to 89}}
-  return 3;
-}
-
-void call_templ() {
-  int ok = templ<127>();
-  int l = templ<3>();
-  int m = templ<200>(); // expected-note {{in instantiation of}}
-  int n = templ<345>(); // expected-note {{in instantiation of}}
-}
-
-template <int a, int b>
-constexpr signed char 
diff  = a > b ? a - b : b - a; // expected-warning{{changes value from 201 to -55}} \
-                                                    // expected-warning{{changes value from 199 to -57}} \
-                                                    // expected-warning{{changes value from 299 to 43}} \
-                                                    // expected-warning{{changes value from 301 to 45}}
-
-void test_
diff () {
-  char ok1 = 
diff <201, 100>;
-  char ok2 = 
diff <101, 200>;
-  char s1 = 
diff <301, 100>; // expected-note {{in instantiation of}}
-  char s2 = 
diff <101, 300>; // expected-note {{in instantiation of}}
-  char w1 = 
diff <101, 400>; // expected-note {{in instantiation of}}
-  char w2 = 
diff <401, 100>; // expected-note {{in instantiation of}}
-}
-}

diff  --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 8e6af7811a30b39..89d1b3ea6de05ea 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1961,7 +1961,7 @@ namespace ConstexprConstructorRecovery {
 
 namespace Lifetime {
   void f() {
-    constexpr int &n = n; // expected-error {{constant expression}} expected-note {{use of reference outside its lifetime}}
+    constexpr int &n = n; // expected-error {{constant expression}} expected-note {{use of reference outside its lifetime}} expected-warning {{not yet bound to a value}}
     constexpr int m = m; // expected-error {{constant expression}} expected-note {{read of object outside its lifetime}}
   }
 

diff  --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp
index 823778f25e16720..a091fadfa3094bd 100644
--- a/clang/test/SemaCXX/cxx2a-consteval.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -713,7 +713,7 @@ constexpr derp d;
 struct test {
   consteval int operator[](int i) const { return {}; }
   consteval const derp * operator->() const { return &d; }
-  consteval int f() const { return 12; } // expected-note {{declared here}}
+  consteval int f() const { return 12; } // expected-note 2{{declared here}}
 };
 
 constexpr test a;
@@ -726,7 +726,8 @@ constexpr int s = a.operator[](1);
 constexpr int t = a[1];
 constexpr int u = a.operator->()->b;
 constexpr int v = a->b;
-constexpr int w = (a.*&test::f)();
+// FIXME: I believe this case should work, but we currently reject.
+constexpr int w = (a.*&test::f)(); // expected-error {{cannot take address of consteval function 'f' outside of an immediate invocation}}
 constexpr int x = a.f();
 
 // Show that we reject when not in an immediate context.
@@ -1072,17 +1073,18 @@ struct tester {
 consteval const char* make_name(const char* name) { return name;}
 consteval const char* pad(int P) { return "thestring"; }
 
-int bad = 10; // expected-note 5{{declared here}}
+int bad = 10; // expected-note 6{{declared here}}
 
 tester glob1(make_name("glob1"));
 tester glob2(make_name("glob2"));
 constexpr tester cglob(make_name("cglob"));
-tester paddedglob(make_name(pad(bad))); // expected-error {{call to consteval function 'GH58207::tester::tester' is not a constant expression}} \
+tester paddedglob(make_name(pad(bad))); // expected-error {{call to consteval function 'GH58207::make_name' is not a constant expression}} \
                                         // expected-note {{read of non-const variable 'bad' is not allowed in a constant expression}}
 
 constexpr tester glob3 = { make_name("glob3") };
-constexpr tester glob4 = { make_name(pad(bad)) }; // expected-error {{constexpr variable 'glob4' must be initialized by a constant expression}} \
-                                                  // expected-note {{read of non-const variable 'bad' is not allowed in a constant expression}}
+constexpr tester glob4 = { make_name(pad(bad)) }; // expected-error {{call to consteval function 'GH58207::make_name' is not a constant expression}} \
+                                                  // expected-error {{constexpr variable 'glob4' must be initialized by a constant expression}} \
+                                                  // expected-note 2{{read of non-const variable 'bad' is not allowed in a constant expression}}
 
 auto V = make_name(pad(3));
 auto V1 = make_name(pad(bad)); // expected-error {{call to consteval function 'GH58207::make_name' is not a constant expression}} \
@@ -1092,12 +1094,12 @@ auto V1 = make_name(pad(bad)); // expected-error {{call to consteval function 'G
 void foo() {
   static tester loc1(make_name("loc1"));
   static constexpr tester loc2(make_name("loc2"));
-  static tester paddedloc(make_name(pad(bad))); // expected-error {{call to consteval function 'GH58207::tester::tester' is not a constant expression}} \
+  static tester paddedloc(make_name(pad(bad))); // expected-error {{call to consteval function 'GH58207::make_name' is not a constant expression}} \
                                                 // expected-note {{read of non-const variable 'bad' is not allowed in a constant expression}}
 }
 
 void bar() {
-  static tester paddedloc(make_name(pad(bad))); // expected-error {{call to consteval function 'GH58207::tester::tester' is not a constant expression}} \
+  static tester paddedloc(make_name(pad(bad))); // expected-error {{call to consteval function 'GH58207::make_name' is not a constant expression}} \
                                                 // expected-note {{read of non-const variable 'bad' is not allowed in a constant expression}}
 }
 }
@@ -1131,7 +1133,7 @@ namespace GH65985 {
 int consteval operator""_foo(unsigned long long V) {
     return 0;
 }
-int consteval operator""_bar(unsigned long long V); // expected-note 2{{here}}
+int consteval operator""_bar(unsigned long long V); // expected-note 3{{here}}
 
 int consteval f() {
   return 0;
@@ -1147,7 +1149,10 @@ struct C {
                                 // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \
                                 // expected-error {{in-class initializer for static data member is not a constant expression}}
 
-    static constexpr int d = 1_bar; // expected-error {{constexpr variable 'd' must be initialized by a constant expression}}  \
+    // FIXME: remove duplicate diagnostics
+    static constexpr int d = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \
+                                    // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \
+                                    // expected-error {{constexpr variable 'd' must be initialized by a constant expression}}  \
                                     // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}}
 
     static const int e = f();
@@ -1162,12 +1167,12 @@ namespace GH66562 {
 
 namespace ns
 {
-    consteval int foo(int x) { return 1; }
+    consteval int foo(int x) { return 1; } // expected-note {{declared here}}
 }
 
 template <class A>
 struct T {
-    static constexpr auto xx = ns::foo(A{});
+    static constexpr auto xx = ns::foo(A{}); // expected-error {{cannot take address of consteval function 'foo' outside of an immediate invocation}}
 };
 
 }

diff  --git a/clang/test/SemaCXX/cxx2b-consteval-if.cpp b/clang/test/SemaCXX/cxx2b-consteval-if.cpp
index 21413e58169b665..72ba58b676247f8 100644
--- a/clang/test/SemaCXX/cxx2b-consteval-if.cpp
+++ b/clang/test/SemaCXX/cxx2b-consteval-if.cpp
@@ -18,7 +18,7 @@ constexpr auto h() {
 
 constexpr auto i() {
   if consteval {
-    if consteval { // expected-warning {{consteval if is always true in this context}}
+    if consteval { // expected-warning {{consteval if is always true in an immediate context}}
       return 1;
     }
     return 2;

diff  --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
index 2daab2c75322c40..531a62622873357 100644
--- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
+++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
@@ -209,7 +209,7 @@ struct SS {
 SS::SS(){} // expected-note {{in the default initializer of 'x'}}
 
 consteval int f2(int x) {
-    if (!__builtin_is_constant_evaluated()) side_effect(); // expected-warning {{'__builtin_is_constant_evaluated' will always evaluate to true}}
+    if (!__builtin_is_constant_evaluated()) side_effect();
     return x;
 }
 struct S2 {
@@ -332,14 +332,16 @@ S s(0); // expected-note {{in the default initializer of 'j'}}
 }
 
 namespace GH65985 {
-consteval int invalid(); // expected-note {{declared here}}
+consteval int invalid(); // expected-note 2{{declared here}}
 constexpr int escalating(auto) {
     return invalid();
-    // expected-note at -1 {{undefined function 'invalid' cannot be used in a constant expression}}
+    // expected-note at -1 {{'escalating<int>' is an immediate function because its body contains a call to a consteval function 'invalid' and that call is not a constant expression}}
+    // expected-note at -2 2{{undefined function 'invalid' cannot be used in a constant expression}}
 }
 struct S {
-    static constexpr int a = escalating(0); // expected-note {{in call to}}
-    // expected-error at -1 {{constexpr variable 'a' must be initialized by a constant expression}}
+    static constexpr int a = escalating(0); // expected-note 2{{in call to}}
+    // expected-error at -1 {{call to immediate function 'GH65985::escalating<int>' is not a constant expression}}
+    // expected-error at -2 {{constexpr variable 'a' must be initialized by a constant expression}}
 };
 
 }

diff  --git a/clang/test/SemaCXX/fixit-tautological-meta-constant.cpp b/clang/test/SemaCXX/fixit-tautological-meta-constant.cpp
deleted file mode 100644
index 104dd2e75d25ab4..000000000000000
--- a/clang/test/SemaCXX/fixit-tautological-meta-constant.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 -std=c++2b -Wno-unused-value -fdiagnostics-parseable-fixits -fsyntax-only %s 2>&1 | FileCheck %s
-namespace std {
-constexpr inline bool
-  is_constant_evaluated() noexcept {
-    if consteval { return true; } else { return false; }
-  }
-} // namespace std
-
-constexpr void cexpr() {
-  if constexpr (std::is_constant_evaluated()) {}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:6-[[@LINE-1]]:16}:""
-  // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:6-[[@LINE-2]]:16}:""
-  constexpr int a = std::is_constant_evaluated();
-  // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:{{.*}}-[[@LINE-1]]:{{.*}}}:""
-
-  if constexpr (const int ce = __builtin_is_constant_evaluated()) {}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:6-[[@LINE-1]]:16}:""
-  // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:6-[[@LINE-2]]:16}:""
-  constexpr int b = std::is_constant_evaluated();
-  // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:{{.*}}-[[@LINE-1]]:{{.*}}}:""
-}

diff  --git a/clang/test/SemaCXX/vartemplate-lambda.cpp b/clang/test/SemaCXX/vartemplate-lambda.cpp
index ab187b2c2e7a2b3..d2b53b53dcd4922 100644
--- a/clang/test/SemaCXX/vartemplate-lambda.cpp
+++ b/clang/test/SemaCXX/vartemplate-lambda.cpp
@@ -12,7 +12,7 @@ template<typename T> auto v1 = [](int a = T()) { return a; }();
 
 struct S {
   template<class T>
-  static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{a lambda expression may not appear inside of a constant expression}}
+  static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{constexpr variable 't<int>' must be initialized by a constant expression}} expected-note{{cannot be used in a constant expression}}
 };
 
 template <typename X>
@@ -21,7 +21,7 @@ int foo2() {
   fn1<char>(a);
   (void)v1<int>;
   (void)v1<int *>; // expected-note{{in instantiation of variable template specialization 'v1' requested here}}
-  (void)S::t<int>;
+  (void)S::t<int>; // expected-note{{in instantiation of static data member 'S::t<int>' requested here}}
   return 0;
 }
 

diff  --git a/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp b/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
index 6ee5f86998eb606..35dc69cccb3a2e2 100644
--- a/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
+++ b/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
@@ -7,35 +7,35 @@ constexpr bool is_constant_evaluated() noexcept {
 } // namespace std
 
 constexpr int fn1() {
-  if constexpr (std::is_constant_evaluated()) // expected-warning {{'std::is_constant_evaluated' will always evaluate to true in this context}}
+  if constexpr (std::is_constant_evaluated()) // expected-warning {{'std::is_constant_evaluated' will always evaluate to 'true' in a manifestly constant-evaluated expression}}
     return 0;
   else
     return 1;
 }
 
 constexpr int fn2() {
-  if constexpr (!std::is_constant_evaluated()) // expected-warning {{'std::is_constant_evaluated' will always evaluate to true in this context}}
+  if constexpr (!std::is_constant_evaluated()) // expected-warning {{'std::is_constant_evaluated' will always evaluate to 'true' in a manifestly constant-evaluated expression}}
     return 0;
   else
     return 1;
 }
 
 constexpr int fn3() {
-  if constexpr (std::is_constant_evaluated() == false) // expected-warning {{'std::is_constant_evaluated' will always evaluate to true in this context}}
+  if constexpr (std::is_constant_evaluated() == false) // expected-warning {{'std::is_constant_evaluated' will always evaluate to 'true' in a manifestly constant-evaluated expression}}
     return 0;
   else
     return 1;
 }
 
 constexpr int fn4() {
-  if constexpr (__builtin_is_constant_evaluated() == true) // expected-warning {{'__builtin_is_constant_evaluated' will always evaluate to true in this context}}
+  if constexpr (__builtin_is_constant_evaluated() == true) // expected-warning {{'__builtin_is_constant_evaluated' will always evaluate to 'true' in a manifestly constant-evaluated expression}}
     return 0;
   else
     return 1;
 }
 
 constexpr int fn5() {
-  if constexpr (__builtin_is_constant_evaluated()) // expected-warning {{'__builtin_is_constant_evaluated' will always evaluate to true in this context}}
+  if constexpr (__builtin_is_constant_evaluated()) // expected-warning {{'__builtin_is_constant_evaluated' will always evaluate to 'true' in a manifestly constant-evaluated expression}}
     return 0;
   else
     return 1;

diff  --git a/clang/test/SemaCXX/warn-tautological-meta-constant.cpp b/clang/test/SemaCXX/warn-tautological-meta-constant.cpp
deleted file mode 100644
index eef944effd8eb8c..000000000000000
--- a/clang/test/SemaCXX/warn-tautological-meta-constant.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-// RUN: %clang_cc1 -std=c++2b -Wno-unused-value -fsyntax-only -verify %s
-
-namespace std {
-constexpr inline bool
-  is_constant_evaluated() noexcept {
-    if consteval { return true; } else { return false; }
-  }
-} // namespace std
-
-namespace P1938 {
-  constexpr int f1() {
-  if constexpr (!std::is_constant_evaluated() && sizeof(int) == 4) { // expected-warning {{always evaluate to true}}
-    return 0;
-  }
-  if (std::is_constant_evaluated()) {
-    return 42;
-  } else {
-    if constexpr (std::is_constant_evaluated()) { // expected-warning {{always evaluate to true}}
-      return 0;
-    }
-  }
-  return 7;
-}
-
-
-consteval int f2() {
-  if (std::is_constant_evaluated() && f1()) { // expected-warning {{always evaluate to true}}
-    return 42;
-  }
-  return 7;
-}
-
-
-int f3() {
-  if (std::is_constant_evaluated() && f1()) { // expected-warning {{always evaluate to false}}
-    return 42;
-  }
-  return 7;
-}
-}
-
-void non_qual() {
-  int ff = std::is_constant_evaluated(); // expected-warning {{always evaluate to false}}
-  const int aa = std::is_constant_evaluated();
-  constexpr int tt = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  static int bb = std::is_constant_evaluated();
-  constexpr int cc = [](){
-    if consteval {return 8;}
-  }();
-  auto lamda = []() {
-    if consteval {return 8;}
-    else {return 4;}
-  };
-  constexpr auto cexpr_lambda = []() {
-    if consteval {}
-    return __builtin_is_constant_evaluated();
-  };
-  auto lamda_const = []() consteval {
-    if consteval {return 8;} // expected-warning {{always true}}
-    else {return 4;}
-  };
-  if consteval { // expected-warning {{always false}}
-    int b = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  }
-}
-
-constexpr void in_constexpr() {
-  int aa = std::is_constant_evaluated();
-  constexpr int bb = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  const int cc = std::is_constant_evaluated();
-  if consteval {
-    int dd = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-    constexpr int ee = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-    const int ff = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  } else {
-    int dd = std::is_constant_evaluated(); // expected-warning {{always evaluate to false}}
-    constexpr int ee = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-    const int ff = std::is_constant_evaluated();
-    const int qq = std::is_constant_evaluated() ? dd : 3;
-  }
-
-  if consteval {
-    if consteval {} // expected-warning {{always true}}
-    if !consteval {} // expected-warning {{always false}}
-  } else {
-    if consteval {} // expected-warning {{always false}}
-    if !consteval {} // expected-warning {{always true}}
-  }
-  if !consteval {
-    if consteval {} // expected-warning {{always false}}
-    if !consteval {} // expected-warning {{always true}}
-  } else {
-    if consteval {} // expected-warning {{always true}}
-    if !consteval {} // expected-warning {{always false}}
-  }
-}
-
-consteval void in_consteval() {
-  int aa = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  constexpr int bb = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  const int cc = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  auto lambda = []() {
-  int a(std::is_constant_evaluated()); // expected-warning {{always evaluate to true}}
-  constexpr int b = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  const int c = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  };
-  if !consteval {} // expected-warning {{always false}}
-}
-
-static_assert(std::is_constant_evaluated()); // expected-warning {{always evaluate to true}}
-static_assert(__builtin_is_constant_evaluated()); // expected-warning {{always evaluate to true}}
-
-template <bool b>
-void templ() {
-  if constexpr(std::is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-  constexpr bool c = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  if consteval {} // expected-warning {{always false}}
-}
-
-template <> void templ<std::is_constant_evaluated()>() { // expected-warning {{always evaluate to true}}
-  if constexpr(std::is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-  constexpr bool c = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  if consteval {} // expected-warning {{always false}}
-  templ<false>();
-}
-
-static_assert([] {
-    if consteval {
-      return 0;
-    } else {
-      return 1;
-    }
-  }() == 0);
-constexpr bool b = __builtin_is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-constexpr bool c = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-constinit bool d = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-int p = __builtin_is_constant_evaluated();
-const int q = __builtin_is_constant_evaluated();
-
-template <bool c = std::is_constant_evaluated()> // expected-warning {{always evaluate to true}}
-void vvv() {
-  return;
-}
-
-template<> void vvv<true>() {}
-template<> void vvv<false>() {}
-
-template<typename T> concept C = __builtin_is_constant_evaluated();// expected-warning {{always evaluate to true}}
-
-struct Foo {
-  static constexpr bool ce = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  const static bool nonce = std::is_constant_evaluated();
-  bool b = std::is_constant_evaluated();
-
-  Foo() {
-    if constexpr(std::is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-    bool aa = std::is_constant_evaluated(); // expected-warning {{always evaluate to false}}
-    static bool bb = std::is_constant_evaluated();
-    constexpr bool cc = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-    if consteval {} // expected-warning {{always false}}
-  }
-  constexpr Foo(int) {
-    if constexpr(std::is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-    bool aa = std::is_constant_evaluated();
-    static bool bb = std::is_constant_evaluated();
-    constexpr bool cc = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  }
-  consteval Foo(int *) {
-    if constexpr(std::is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-    bool aa = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-    static bool bb = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-    constexpr bool cc = std::is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-  }
-};
-
-namespace condition {
-void f() {
-  if constexpr (int a = __builtin_is_constant_evaluated(); // expected-warning {{always evaluate to false}}
-                true) {}
-  if constexpr (const int a = __builtin_is_constant_evaluated();
-                true) {}
-  if constexpr (constexpr int a = __builtin_is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-                true) {}
-  if constexpr (;const int b = __builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-  if constexpr (;constexpr int b = __builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-
-  if (int a = __builtin_is_constant_evaluated(); // expected-warning {{always evaluate to false}}
-      true) {}
-  if (const int a = __builtin_is_constant_evaluated();
-      true) {}
-  if (constexpr int a = __builtin_is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-      true) {}
-  if (;int b = __builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to false}}
-  if (;const int b = __builtin_is_constant_evaluated()) {}
-  if (;constexpr int b = __builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-
-  if constexpr (__builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-  if (__builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to false}}
-
-  if constexpr (__builtin_is_constant_evaluated(); true) {} // expected-warning {{always evaluate to false}}
-  // False
-  if constexpr (({__builtin_is_constant_evaluated();2;3;}); true) {}
-
-  if (__builtin_is_constant_evaluated(); true) {} // expected-warning {{always evaluate to false}}
-  if constexpr (;__builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-  if (;__builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to false}}
-}
-
-constexpr void g() {
-  if constexpr (int a = __builtin_is_constant_evaluated();
-                true) {}
-  if constexpr (const int a = __builtin_is_constant_evaluated();
-                true) {}
-  if constexpr (constexpr int a = __builtin_is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-                true) {}
-  if constexpr (;const int b = __builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-  if constexpr (;constexpr int b = __builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-
-  if (int a = __builtin_is_constant_evaluated();
-      true) {}
-  if (const int a = __builtin_is_constant_evaluated();
-      true) {}
-  if (constexpr int a = __builtin_is_constant_evaluated(); // expected-warning {{always evaluate to true}}
-      true) {}
-  if (;int b = __builtin_is_constant_evaluated()) {}
-  if (;const int b = __builtin_is_constant_evaluated()) {}
-  if (;constexpr int b = __builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-
-  if constexpr (__builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-  if (__builtin_is_constant_evaluated()) {}
-
-  if constexpr (__builtin_is_constant_evaluated(); true) {}
-  if constexpr (({__builtin_is_constant_evaluated();2;3;}); true) {}
-
-  if (__builtin_is_constant_evaluated(); true) {}
-  if constexpr (;__builtin_is_constant_evaluated()) {} // expected-warning {{always evaluate to true}}
-  if (;__builtin_is_constant_evaluated()) {}
-}
-}
-
-namespace Arguments {
-  int nonc(int n) { return n;}
-  constexpr int cexpr(int n) { return n;}
-  consteval int ceval(int n) { return n; }
-  void f() {
-    // FIXME: These are tauologically-false;
-    int a1 = nonc(__builtin_is_constant_evaluated());
-    const int b1 = nonc(__builtin_is_constant_evaluated());
-    int a2 = cexpr(__builtin_is_constant_evaluated());
-
-    // ok
-    const int b2 = cexpr(__builtin_is_constant_evaluated());
-    constexpr int c2 = cexpr(__builtin_is_constant_evaluated()); // expected-warning {{always evaluate to true}}
-
-    // FIXME: These are tautologically-true;
-    int a3 = ceval(__builtin_is_constant_evaluated());
-    const int b3 = ceval(__builtin_is_constant_evaluated());
-
-    // ok
-    constexpr int c3 = ceval(__builtin_is_constant_evaluated()); // expected-warning {{always evaluate to true}}
-  }
-}

diff  --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index c90339e778bc182..e98ebcc9203a430 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -135,21 +135,21 @@ namespace PackInTypeConstraint {
 
 namespace BuiltinIsConstantEvaluated {
   // Check that we do all satisfaction and diagnostic checks in a constant context.
-  template<typename T> concept C = __builtin_is_constant_evaluated(); // expected-warning {{always evaluate to true}}
+  template<typename T> concept C = __builtin_is_constant_evaluated(); // expected-warning {{always}}
   static_assert(C<int>);
 
-  template<typename T> concept D = __builtin_is_constant_evaluated() == true; // expected-warning {{always evaluate to true}}
+  template<typename T> concept D = __builtin_is_constant_evaluated() == true; // expected-warning {{always}}
   static_assert(D<int>);
 
-  template<typename T> concept E = __builtin_is_constant_evaluated() == true && // expected-warning {{always evaluate to true}}
+  template<typename T> concept E = __builtin_is_constant_evaluated() == true && // expected-warning {{always}}
                                    false; // expected-note {{'false' evaluated to false}}
   static_assert(E<int>); // expected-error {{failed}} expected-note {{because 'int' does not satisfy 'E'}}
 
-  template<typename T> concept F = __builtin_is_constant_evaluated() == false; // expected-warning {{always evaluate to true}}
+  template<typename T> concept F = __builtin_is_constant_evaluated() == false; // expected-warning {{always}}
   // expected-note at -1 {{'__builtin_is_constant_evaluated() == false' (1 == 0)}}
   static_assert(F<int>); // expected-error {{failed}} expected-note {{because 'int' does not satisfy 'F'}}
 
-  template<typename T> concept G = __builtin_is_constant_evaluated() && // expected-warning {{always evaluate to true}}
+  template<typename T> concept G = __builtin_is_constant_evaluated() && // expected-warning {{always}}
                                    false; // expected-note {{'false' evaluated to false}}
   static_assert(G<int>); // expected-error {{failed}} expected-note {{because 'int' does not satisfy 'G'}}
 }

diff  --git a/clang/unittests/Support/TimeProfilerTest.cpp b/clang/unittests/Support/TimeProfilerTest.cpp
index 85173b23fc6497e..fdfbbfe4e3a9dff 100644
--- a/clang/unittests/Support/TimeProfilerTest.cpp
+++ b/clang/unittests/Support/TimeProfilerTest.cpp
@@ -188,6 +188,7 @@ Frontend
 | EvaluateAsBooleanCondition (<test.cc:8:21, col:25>)
 | | EvaluateAsRValue (<test.cc:8:21, col:25>)
 | EvaluateAsInitializer (slow_value)
+| EvaluateAsConstantExpr (<test.cc:17:33, col:59>)
 | EvaluateAsConstantExpr (<test.cc:18:11, col:37>)
 | EvaluateAsRValue (<test.cc:22:14, line:23:58>)
 | EvaluateAsInitializer (slow_init_list)

diff  --git a/libcxx/include/__type_traits/is_constant_evaluated.h b/libcxx/include/__type_traits/is_constant_evaluated.h
index 1649762ed6dc598..d7af462486e1316 100644
--- a/libcxx/include/__type_traits/is_constant_evaluated.h
+++ b/libcxx/include/__type_traits/is_constant_evaluated.h
@@ -24,14 +24,7 @@ _LIBCPP_INLINE_VISIBILITY inline constexpr bool is_constant_evaluated() noexcept
 #endif
 
 _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR bool __libcpp_is_constant_evaluated() _NOEXCEPT {
-// __builtin_is_constant_evaluated() in this function always evaluates to false in pre-C++11 mode
-// because this function is not constexpr-qualified.
-// The following macro use clarifies this and avoids warnings from compilers.
-#ifndef _LIBCPP_CXX03_LANG
   return __builtin_is_constant_evaluated();
-#else
-  return false;
-#endif
 }
 
 _LIBCPP_END_NAMESPACE_STD

diff  --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp
index abb9157df9abbbb..9291c0aa1f43404 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp
@@ -93,10 +93,12 @@ constexpr void test_join_view() {
 }
 
 int main(int, char**) {
-  test_containers<std::deque<int>, std::deque<int>>();
-  test_containers<std::deque<int>, std::vector<int>>();
-  test_containers<std::vector<int>, std::deque<int>>();
-  test_containers<std::vector<int>, std::vector<int>>();
+  if (!std::is_constant_evaluated()) {
+    test_containers<std::deque<int>, std::deque<int>>();
+    test_containers<std::deque<int>, std::vector<int>>();
+    test_containers<std::vector<int>, std::deque<int>>();
+    test_containers<std::vector<int>, std::vector<int>>();
+  }
 
   types::for_each(types::forward_iterator_list<int*>{}, []<class Iter> {
     test_join_view<Iter, Iter>();

diff  --git a/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.verify.cpp b/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.verify.cpp
index ef6e6f18ba6b5ca..f4865ff368079be 100644
--- a/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.verify.cpp
+++ b/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.verify.cpp
@@ -24,7 +24,7 @@ int main(int, char**)
 #else
   // expected-error-re at +1 {{{{(static_assert|static assertion)}} failed}}
   static_assert(!std::is_constant_evaluated(), "");
-  // expected-warning-re at -1 0-1 {{'std::is_constant_evaluated' will always evaluate to {{('true' in a manifestly constant-evaluated expression|true in this context)}}}}
+  // expected-warning at -1 0-1 {{'std::is_constant_evaluated' will always evaluate to 'true' in a manifestly constant-evaluated expression}}
 #endif
   return 0;
 }


        


More information about the cfe-commits mailing list