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
