[clang] [clang] Check captured variables for noreturn attribute (PR #155213)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 24 23:29:56 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Serge Pavlov (spavloff)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/155213.diff
2 Files Affected:
- (modified) clang/lib/Sema/AnalysisBasedWarnings.cpp (+35)
- (modified) clang/test/SemaCXX/noreturn-vars.cpp (+13)
``````````diff
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}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/155213
More information about the cfe-commits
mailing list