https://github.com/shermpay updated 
https://github.com/llvm/llvm-project/pull/185800

>From 333fdc15089ebf28f10d88f8a9fe4c1e5e10eb2a Mon Sep 17 00:00:00 2001
From: Sherman Pay <[email protected]>
Date: Tue, 10 Mar 2026 20:54:59 -0700
Subject: [PATCH] Suppress printing lambda body for constexpr diagnostics

closes: 125914

Introduce `SupressLambdaBody` `PrintingPolicy` that is used only for
constexpr diagnostics. This ensures `--print-ast` still works the same.

Add two tests:
1. To ast-printer-lambda to ensure `--print-ast` works the same.
2. Ensure lambda body is not printed for constexpr diagnostics.
---
 clang/docs/ReleaseNotes.rst                   |  2 +
 clang/include/clang/AST/PrettyPrinter.h       |  6 ++-
 clang/lib/AST/ByteCode/InterpFrame.cpp        |  8 ++--
 clang/lib/AST/ExprConstant.cpp                | 12 +++---
 clang/lib/AST/StmtPrinter.cpp                 |  2 +-
 clang/test/AST/ast-printer-lambda.cpp         | 10 ++++-
 .../test/AST/constexpr-lambda-diagnostic.cpp  | 43 +++++++++++++++++++
 7 files changed, 72 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/AST/constexpr-lambda-diagnostic.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fd58d7847717c..98aeaaf1e0d96 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -366,6 +366,8 @@ Improvements to Clang's diagnostics
   code can automatically be made portable to other host platforms that don't
   support backslashes.
 
+- Removed the body of lambdas from some diagnostic messages.
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/AST/PrettyPrinter.h 
b/clang/include/clang/AST/PrettyPrinter.h
index a937d020b7277..f95d54c0f05b9 100644
--- a/clang/include/clang/AST/PrettyPrinter.h
+++ b/clang/include/clang/AST/PrettyPrinter.h
@@ -94,7 +94,7 @@ struct PrintingPolicy {
         UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false),
         CleanUglifiedParameters(false), EntireContentsOfLargeArray(true),
         UseEnumerators(true), UseHLSLTypes(LO.HLSL),
-        SuppressDeclAttributes(false) {}
+        SuppressDeclAttributes(false), SuppressLambdaBody(false) {}
 
   /// Adjust this printing policy for cases where it's known that we're
   /// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -371,6 +371,10 @@ struct PrintingPolicy {
   LLVM_PREFERRED_TYPE(bool)
   unsigned SuppressDeclAttributes : 1;
 
+  /// Whether to suppress printing the body of a lambda.
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned SuppressLambdaBody : 1;
+
   /// Callbacks to use to allow the behavior of printing to be customized.
   const PrintingCallbacks *Callbacks = nullptr;
 };
diff --git a/clang/lib/AST/ByteCode/InterpFrame.cpp 
b/clang/lib/AST/ByteCode/InterpFrame.cpp
index 1c7d65dc28e02..e4e18adcd10c9 100644
--- a/clang/lib/AST/ByteCode/InterpFrame.cpp
+++ b/clang/lib/AST/ByteCode/InterpFrame.cpp
@@ -165,6 +165,8 @@ void InterpFrame::describe(llvm::raw_ostream &OS) const {
 
   const Expr *CallExpr = Caller->getExpr(getRetPC());
   const FunctionDecl *F = getCallee();
+  auto PrintingPolicy = S.getASTContext().getPrintingPolicy();
+  PrintingPolicy.SuppressLambdaBody = true;
 
   bool IsMemberCall = false;
   bool ExplicitInstanceParam = false;
@@ -177,7 +179,7 @@ void InterpFrame::describe(llvm::raw_ostream &OS) const {
     if (const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
       const Expr *Object = MCE->getImplicitObjectArgument();
       Object->printPretty(OS, /*Helper=*/nullptr,
-                          S.getASTContext().getPrintingPolicy(),
+                          PrintingPolicy,
                           /*Indentation=*/0);
       if (Object->getType()->isPointerType())
         OS << "->";
@@ -186,7 +188,7 @@ void InterpFrame::describe(llvm::raw_ostream &OS) const {
     } else if (const auto *OCE =
                    dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
       OCE->getArg(0)->printPretty(OS, /*Helper=*/nullptr,
-                                  S.getASTContext().getPrintingPolicy(),
+                                  PrintingPolicy,
                                   /*Indentation=*/0);
       OS << ".";
     } else if (const auto *M = dyn_cast<CXXMethodDecl>(F)) {
@@ -197,7 +199,7 @@ void InterpFrame::describe(llvm::raw_ostream &OS) const {
     }
   }
 
-  F->getNameForDiagnostic(OS, S.getASTContext().getPrintingPolicy(),
+  F->getNameForDiagnostic(OS, PrintingPolicy,
                           /*Qualified=*/false);
   OS << '(';
   unsigned Off = 0;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 4f45fa728c605..8a468dcabe384 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1862,19 +1862,22 @@ APValue *EvalInfo::createHeapAlloc(const Expr *E, 
QualType T, LValue &LV) {
 void CallStackFrame::describe(raw_ostream &Out) const {
   bool IsMemberCall = false;
   bool ExplicitInstanceParam = false;
+  clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
+  PrintingPolicy.SuppressLambdaBody = true;
+
   if (const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
     IsMemberCall = !isa<CXXConstructorDecl>(MD) && !MD->isStatic();
     ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
   }
 
   if (!IsMemberCall)
-    Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
+    Callee->getNameForDiagnostic(Out, PrintingPolicy,
                                  /*Qualified=*/false);
 
   if (This && IsMemberCall) {
     if (const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
       const Expr *Object = MCE->getImplicitObjectArgument();
-      Object->printPretty(Out, /*Helper=*/nullptr, 
Info.Ctx.getPrintingPolicy(),
+      Object->printPretty(Out, /*Helper=*/nullptr, PrintingPolicy,
                           /*Indentation=*/0);
       if (Object->getType()->isPointerType())
           Out << "->";
@@ -1882,8 +1885,7 @@ void CallStackFrame::describe(raw_ostream &Out) const {
           Out << ".";
     } else if (const auto *OCE =
                    dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
-      OCE->getArg(0)->printPretty(Out, /*Helper=*/nullptr,
-                                  Info.Ctx.getPrintingPolicy(),
+      OCE->getArg(0)->printPretty(Out, /*Helper=*/nullptr, PrintingPolicy,
                                   /*Indentation=*/0);
       Out << ".";
     } else {
@@ -1894,7 +1896,7 @@ void CallStackFrame::describe(raw_ostream &Out) const {
           Info.Ctx.getLValueReferenceType(This->Designator.MostDerivedType));
       Out << ".";
     }
-    Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
+    Callee->getNameForDiagnostic(Out, PrintingPolicy,
                                  /*Qualified=*/false);
   }
 
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 4d364fdcd5502..86adf6626ed15 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -2463,7 +2463,7 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
 
   // Print the body.
   OS << ' ';
-  if (Policy.TerseOutput)
+  if (Policy.TerseOutput || Policy.SuppressLambdaBody)
     OS << "{}";
   else
     PrintRawCompoundStmt(Node->getCompoundStmtBody());
diff --git a/clang/test/AST/ast-printer-lambda.cpp 
b/clang/test/AST/ast-printer-lambda.cpp
index 08f1ff555b0b1..015aa7e791205 100644
--- a/clang/test/AST/ast-printer-lambda.cpp
+++ b/clang/test/AST/ast-printer-lambda.cpp
@@ -51,6 +51,14 @@ void test1(int i, T... t) {
   auto lambda = [k{t...}] {};
   //CHECK: [k{t...}] {
 }
+{
+  auto lambda = [i]{
+    (void)i;
+  };
+  //CHECK: [i] {
+  //CHECK-NEXT: (void)i;
+  //CHECK-NEXT: };
+}
 }
 
-};
\ No newline at end of file
+};
diff --git a/clang/test/AST/constexpr-lambda-diagnostic.cpp 
b/clang/test/AST/constexpr-lambda-diagnostic.cpp
new file mode 100644
index 0000000000000..ff053d514670c
--- /dev/null
+++ b/clang/test/AST/constexpr-lambda-diagnostic.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -std=c++17 
-verify=expected %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -std=c++17 
-verify=expected %s -fexperimental-new-constant-interpreter
+constexpr void undefined();  // expected-note 4 {{declared here}}
+static constexpr int r = [] { // expected-error {{constexpr variable 'r' must 
be initialized by a constant expression}} \
+                                 expected-note {{in call to '[] 
{}.operator()()'}}}
+  undefined();  // expected-note {{undefined function 'undefined' cannot be 
used in a constant expression}}
+  return 0;
+ }();
+
+static constexpr auto valid_lambda = [] {};
+
+static constexpr int nested = [] { // expected-error {{constexpr variable 
'nested' must be initialized by a constant expression}} \
+                                 expected-note {{in call to '[] 
{}.operator()()'}}}
+  valid_lambda();
+  auto inner = [] { // expected-note {{in call to '[] {}.operator()()'}}}
+       undefined(); // expected-note {{undefined function 'undefined' cannot 
be used in a constant expression}}
+       return 1;
+  }();
+  return 0;
+}();
+
+static constexpr float type_mismatch = [] { // expected-error {{cannot 
initialize a variable of type 'const float' with an rvalue of type 'void'}}
+}();
+
+constexpr auto named_lambda = [] {
+  undefined(); // expected-note {{undefined function 'undefined' cannot be 
used in a constant expression}}
+  return 0;
+};
+
+static constexpr int named_lambda_result = named_lambda(); // expected-error 
{{constexpr variable 'named_lambda_result' must be initialized by a constant 
expression}} \
+expected-note {{in call to 'named_lambda.operator()()'}}
+
+static constexpr int undeclared = []{ // expected-error {{constexpr variable 
'undeclared' must be initialized by a constant expression}}
+  foo();  // expected-error {{use of undeclared identifier 'foo'}}
+  return 0;
+}();
+
+
+static constexpr int with_param = [](int x) { // expected-error {{constexpr 
variable 'with_param' must be initialized by a constant expression}} \
+expected-note {{in call to '[](int x) {}.operator()(2)'}}
+  undefined(); // expected-note {{undefined function 'undefined' cannot be 
used in a constant expression}}
+  return x;
+}(2);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to