https://github.com/spavloff updated https://github.com/llvm/llvm-project/pull/155213
>From 52499a2a3fde7c66f398e5730f782e0faf6f6e2d Mon Sep 17 00:00:00 2001 From: Serge Pavlov <[email protected]> Date: Mon, 25 Aug 2025 12:20:21 +0700 Subject: [PATCH 1/3] [clang] Check captured variables for noreturn attribute Anaysis for noreturn attribute now misses the case when an assignment to a variable is made inside a lambda function call. This change fixes that case. --- clang/lib/Sema/AnalysisBasedWarnings.cpp | 35 ++++++++++++++++++++++++ clang/test/SemaCXX/noreturn-vars.cpp | 13 +++++++++ 2 files changed, 48 insertions(+) diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 0b94b1044f072..fe1498003e7da 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -467,6 +467,41 @@ struct TransferFunctions : public StmtVisitor<TransferFunctions> { AllValuesAreNoReturn = false; } } + + void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) { + if (CE->getOperator() == OO_Call && CE->getNumArgs() > 0) { + Expr *Obj = CE->getArg(0)->IgnoreParenCasts(); + if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Obj)) + Obj = MTE->getSubExpr(); + if (auto *DRE = dyn_cast<DeclRefExpr>(Obj)) { + auto *D = dyn_cast<VarDecl>(DRE->getDecl()); + if (D->hasInit()) + Obj = D->getInit(); + } + Visit(Obj); + } + } + + void VisitLambdaExpr(LambdaExpr *LE) { + for (const LambdaCapture &Capture : LE->captures()) + if (Capture.capturesVariable()) + if (const VarDecl *VD = dyn_cast<VarDecl>(Capture.getCapturedVar())) + if (VD == Var) + if (Capture.getCaptureKind() == LCK_ByRef) + AllValuesAreNoReturn = false; + } + + void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) { + Visit(MTE->getSubExpr()); + } + + void VisitExprWithCleanups(FullExpr *FE) { + Visit(FE->getSubExpr()); + } + + void VisitCXXConstructExpr(CXXConstructExpr *CE) { + Visit(CE->getArg(0)); + } }; } // namespace diff --git a/clang/test/SemaCXX/noreturn-vars.cpp b/clang/test/SemaCXX/noreturn-vars.cpp index ca65fcf5ca31d..3b2473c1bc670 100644 --- a/clang/test/SemaCXX/noreturn-vars.cpp +++ b/clang/test/SemaCXX/noreturn-vars.cpp @@ -225,3 +225,16 @@ extern void abc_02(func_type *); abc_02(&func_ptr); func_ptr(); } // expected-warning {{function declared 'noreturn' should not return}} + +[[noreturn]] void test_lambda() { + func_type func_ptr = noret; + [&func_ptr]() { func_ptr = ordinary; } (); + func_ptr(); +} // expected-warning {{function declared 'noreturn' should not return}} + +[[noreturn]] void test_lambda_var(int x) { + func_type func_ptr = noret; + auto LF = [&](){func_ptr = ordinary;}; + LF(); + func_ptr(); +} // expected-warning {{function declared 'noreturn' should not return}} >From 8c258f43414876636f9d4029cc6c3c2cbcc7b993 Mon Sep 17 00:00:00 2001 From: Serge Pavlov <[email protected]> Date: Thu, 18 Sep 2025 00:14:48 +0700 Subject: [PATCH 2/3] Addressreview notes --- clang/lib/Sema/AnalysisBasedWarnings.cpp | 8 ++--- clang/test/SemaCXX/noreturn-vars.cpp | 40 ++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index fe1498003e7da..b16c9989fbbb4 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -480,6 +480,7 @@ struct TransferFunctions : public StmtVisitor<TransferFunctions> { } Visit(Obj); } + VisitCallExpr(CE); } void VisitLambdaExpr(LambdaExpr *LE) { @@ -495,12 +496,11 @@ struct TransferFunctions : public StmtVisitor<TransferFunctions> { Visit(MTE->getSubExpr()); } - void VisitExprWithCleanups(FullExpr *FE) { - Visit(FE->getSubExpr()); - } + void VisitExprWithCleanups(FullExpr *FE) { Visit(FE->getSubExpr()); } void VisitCXXConstructExpr(CXXConstructExpr *CE) { - Visit(CE->getArg(0)); + if (CE->getNumArgs() > 0) + Visit(CE->getArg(0)); } }; } // namespace diff --git a/clang/test/SemaCXX/noreturn-vars.cpp b/clang/test/SemaCXX/noreturn-vars.cpp index 3b2473c1bc670..9b23dc96d9ae0 100644 --- a/clang/test/SemaCXX/noreturn-vars.cpp +++ b/clang/test/SemaCXX/noreturn-vars.cpp @@ -226,15 +226,49 @@ extern void abc_02(func_type *); func_ptr(); } // expected-warning {{function declared 'noreturn' should not return}} -[[noreturn]] void test_lambda() { +[[noreturn]] void test_lambda_capture_ref() { func_type func_ptr = noret; [&func_ptr]() { func_ptr = ordinary; } (); func_ptr(); } // expected-warning {{function declared 'noreturn' should not return}} -[[noreturn]] void test_lambda_var(int x) { +[[noreturn]] void test_lambda_var_capture_ref() { func_type func_ptr = noret; - auto LF = [&](){func_ptr = ordinary;}; + auto LF = [&func_ptr](){func_ptr = ordinary; }; LF(); func_ptr(); } // expected-warning {{function declared 'noreturn' should not return}} + +[[noreturn]] void test_lambda_capture_ref_all() { + func_type func_ptr = noret; + [&]() { func_ptr = ordinary; } (); + func_ptr(); +} // expected-warning {{function declared 'noreturn' should not return}} + +[[noreturn]] void test_lambda_var_capture_ref_all() { + func_type func_ptr = noret; + auto LF = [&](){func_ptr = ordinary; }; + LF(); + func_ptr(); +} // expected-warning {{function declared 'noreturn' should not return}} + +[[noreturn]] void lambda_capture_by_value() { + func_type func_ptr = noret; + auto LF = [func_ptr](){ return func_ptr; }; + LF(); + func_ptr(); +} + +[[noreturn]] void lambda_pass_by_ref() { + func_type func_ptr = noret; + auto LF = [](func_type &fptr){ fptr = ordinary; }; + LF(func_ptr); + func_ptr(); +} // expected-warning {{function declared 'noreturn' should not return}} + +[[noreturn]] void lambda_pass_by_value() { + func_type func_ptr = noret; + auto LF = [](func_type fptr){ fptr = ordinary; }; + LF(func_ptr); + func_ptr(); +} >From 3dc5d78a14e0232d5ccc4e14a9cf707111dabdb7 Mon Sep 17 00:00:00 2001 From: Serge Pavlov <[email protected]> Date: Thu, 30 Oct 2025 01:33:28 +0700 Subject: [PATCH 3/3] Small enhancements --- clang/lib/Sema/AnalysisBasedWarnings.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index b16c9989fbbb4..88fd63156d002 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -475,7 +475,7 @@ struct TransferFunctions : public StmtVisitor<TransferFunctions> { Obj = MTE->getSubExpr(); if (auto *DRE = dyn_cast<DeclRefExpr>(Obj)) { auto *D = dyn_cast<VarDecl>(DRE->getDecl()); - if (D->hasInit()) + if (D && D->hasInit()) Obj = D->getInit(); } Visit(Obj); @@ -487,9 +487,8 @@ struct TransferFunctions : public StmtVisitor<TransferFunctions> { for (const LambdaCapture &Capture : LE->captures()) if (Capture.capturesVariable()) if (const VarDecl *VD = dyn_cast<VarDecl>(Capture.getCapturedVar())) - if (VD == Var) - if (Capture.getCaptureKind() == LCK_ByRef) - AllValuesAreNoReturn = false; + if (VD == Var && Capture.getCaptureKind() == LCK_ByRef) + AllValuesAreNoReturn = false; } void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
