[clang] [clang][Sema] Combine fallout warnings to just one warning (PR #127546)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 19 09:15:07 PST 2025
https://github.com/foxtran updated https://github.com/llvm/llvm-project/pull/127546
>From d09db5fc8ca7f58813f917c3726d09f0e4cfdd81 Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Mon, 17 Feb 2025 22:39:31 +0100
Subject: [PATCH 01/12] Merge {Maybe,Always}FallThrough_ReturnsNonVoid into
FallThrough_ReturnsNonVoid
---
.../clang/Basic/DiagnosticSemaKinds.td | 20 ++------
clang/lib/Sema/AnalysisBasedWarnings.cpp | 51 +++++++------------
2 files changed, 21 insertions(+), 50 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ee1ad214d81df..e13626b38c50e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -713,12 +713,8 @@ def err_thread_non_global : Error<
def err_thread_unsupported : Error<
"thread-local storage is not supported for the current target">;
-// FIXME: Combine fallout warnings to just one warning.
-def warn_maybe_falloff_nonvoid_function : Warning<
- "non-void function does not return a value in all control paths">,
- InGroup<ReturnType>;
def warn_falloff_nonvoid_function : Warning<
- "non-void function does not return a value">,
+ "non-void function does not return a value%select{| in all control paths}0">,
InGroup<ReturnType>;
def warn_const_attr_with_pure_attr : Warning<
"'const' attribute imposes more restrictions; 'pure' attribute ignored">,
@@ -727,15 +723,10 @@ def warn_pure_function_returns_void : Warning<
"'%select{pure|const}0' attribute on function returning 'void'; attribute ignored">,
InGroup<IgnoredAttributes>;
-def err_maybe_falloff_nonvoid_block : Error<
- "non-void block does not return a value in all control paths">;
def err_falloff_nonvoid_block : Error<
- "non-void block does not return a value">;
-def warn_maybe_falloff_nonvoid_coroutine : Warning<
- "non-void coroutine does not return a value in all control paths">,
- InGroup<ReturnType>;
+ "non-void block does not return a value%select{| in all control paths}0">;
def warn_falloff_nonvoid_coroutine : Warning<
- "non-void coroutine does not return a value">,
+ "non-void coroutine does not return a value%select{| in all control paths}0">,
InGroup<ReturnType>;
def warn_suggest_noreturn_function : Warning<
"%select{function|method}0 %1 could be declared with attribute 'noreturn'">,
@@ -8408,11 +8399,8 @@ let CategoryName = "Lambda Issue" in {
"incomplete result type %0 in lambda expression">;
def err_noreturn_lambda_has_return_expr : Error<
"lambda declared 'noreturn' should not return">;
- def warn_maybe_falloff_nonvoid_lambda : Warning<
- "non-void lambda does not return a value in all control paths">,
- InGroup<ReturnType>;
def warn_falloff_nonvoid_lambda : Warning<
- "non-void lambda does not return a value">,
+ "non-void lambda does not return a value%select{| in all control paths}0">,
InGroup<ReturnType>;
def err_access_lambda_capture : Error<
// The ERRORs represent other special members that aren't constructors, in
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index ce7d9be8d2faa..74a96bb7c443a 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -544,10 +544,8 @@ static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
namespace {
struct CheckFallThroughDiagnostics {
- unsigned diag_MaybeFallThrough_HasNoReturn;
- unsigned diag_MaybeFallThrough_ReturnsNonVoid;
- unsigned diag_AlwaysFallThrough_HasNoReturn;
- unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
+ unsigned diag_FallThrough_HasNoReturn;
+ unsigned diag_FallThrough_ReturnsNonVoid;
unsigned diag_NeverFallThroughOrReturn;
enum { Function, Block, Lambda, Coroutine } funMode;
SourceLocation FuncLoc;
@@ -555,13 +553,9 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
- D.diag_MaybeFallThrough_HasNoReturn =
+ D.diag_FallThrough_HasNoReturn =
diag::warn_falloff_noreturn_function;
- D.diag_MaybeFallThrough_ReturnsNonVoid =
- diag::warn_maybe_falloff_nonvoid_function;
- D.diag_AlwaysFallThrough_HasNoReturn =
- diag::warn_falloff_noreturn_function;
- D.diag_AlwaysFallThrough_ReturnsNonVoid =
+ D.diag_FallThrough_ReturnsNonVoid =
diag::warn_falloff_nonvoid_function;
// Don't suggest that virtual functions be marked "noreturn", since they
@@ -588,11 +582,8 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForCoroutine(const Decl *Func) {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
- D.diag_MaybeFallThrough_HasNoReturn = 0;
- D.diag_MaybeFallThrough_ReturnsNonVoid =
- diag::warn_maybe_falloff_nonvoid_coroutine;
- D.diag_AlwaysFallThrough_HasNoReturn = 0;
- D.diag_AlwaysFallThrough_ReturnsNonVoid =
+ D.diag_FallThrough_HasNoReturn = 0;
+ D.diag_FallThrough_ReturnsNonVoid =
diag::warn_falloff_nonvoid_coroutine;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Coroutine;
@@ -601,13 +592,9 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForBlock() {
CheckFallThroughDiagnostics D;
- D.diag_MaybeFallThrough_HasNoReturn =
- diag::err_noreturn_block_has_return_expr;
- D.diag_MaybeFallThrough_ReturnsNonVoid =
- diag::err_maybe_falloff_nonvoid_block;
- D.diag_AlwaysFallThrough_HasNoReturn =
+ D.diag_FallThrough_HasNoReturn =
diag::err_noreturn_block_has_return_expr;
- D.diag_AlwaysFallThrough_ReturnsNonVoid =
+ D.diag_FallThrough_ReturnsNonVoid =
diag::err_falloff_nonvoid_block;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Block;
@@ -616,13 +603,9 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForLambda() {
CheckFallThroughDiagnostics D;
- D.diag_MaybeFallThrough_HasNoReturn =
- diag::err_noreturn_lambda_has_return_expr;
- D.diag_MaybeFallThrough_ReturnsNonVoid =
- diag::warn_maybe_falloff_nonvoid_lambda;
- D.diag_AlwaysFallThrough_HasNoReturn =
+ D.diag_FallThrough_HasNoReturn =
diag::err_noreturn_lambda_has_return_expr;
- D.diag_AlwaysFallThrough_ReturnsNonVoid =
+ D.diag_FallThrough_ReturnsNonVoid =
diag::warn_falloff_nonvoid_lambda;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Lambda;
@@ -633,7 +616,7 @@ struct CheckFallThroughDiagnostics {
bool HasNoReturn) const {
if (funMode == Function) {
return (ReturnsVoid ||
- D.isIgnored(diag::warn_maybe_falloff_nonvoid_function,
+ D.isIgnored(diag::warn_falloff_nonvoid_function,
FuncLoc)) &&
(!HasNoReturn ||
D.isIgnored(diag::warn_noreturn_function_has_return_expr,
@@ -643,8 +626,8 @@ struct CheckFallThroughDiagnostics {
}
if (funMode == Coroutine) {
return (ReturnsVoid ||
- D.isIgnored(diag::warn_maybe_falloff_nonvoid_function, FuncLoc) ||
- D.isIgnored(diag::warn_maybe_falloff_nonvoid_coroutine,
+ D.isIgnored(diag::warn_falloff_nonvoid_function, FuncLoc) ||
+ D.isIgnored(diag::warn_falloff_nonvoid_coroutine,
FuncLoc)) &&
(!HasNoReturn);
}
@@ -716,15 +699,15 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
case MaybeFallThrough:
if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_MaybeFallThrough_HasNoReturn);
+ EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
else if (!ReturnsVoid)
- EmitDiag(RBrace, CD.diag_MaybeFallThrough_ReturnsNonVoid);
+ S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << 1;
break;
case AlwaysFallThrough:
if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_AlwaysFallThrough_HasNoReturn);
+ EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
else if (!ReturnsVoid)
- EmitDiag(RBrace, CD.diag_AlwaysFallThrough_ReturnsNonVoid);
+ S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << 0;
break;
case NeverFallThroughOrReturn:
if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
>From 8d7fd28186e5277468055126c3d9bbd37638375e Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Mon, 17 Feb 2025 22:41:29 +0100
Subject: [PATCH 02/12] Format source code
---
clang/lib/Sema/AnalysisBasedWarnings.cpp | 82 +++++++++++-------------
1 file changed, 36 insertions(+), 46 deletions(-)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 74a96bb7c443a..1929178be2ddb 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -553,10 +553,8 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
- D.diag_FallThrough_HasNoReturn =
- diag::warn_falloff_noreturn_function;
- D.diag_FallThrough_ReturnsNonVoid =
- diag::warn_falloff_nonvoid_function;
+ D.diag_FallThrough_HasNoReturn = diag::warn_falloff_noreturn_function;
+ D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid_function;
// Don't suggest that virtual functions be marked "noreturn", since they
// might be overridden by non-noreturn functions.
@@ -570,8 +568,7 @@ struct CheckFallThroughDiagnostics {
isTemplateInstantiation = Function->isTemplateInstantiation();
if (!isVirtualMethod && !isTemplateInstantiation)
- D.diag_NeverFallThroughOrReturn =
- diag::warn_suggest_noreturn_function;
+ D.diag_NeverFallThroughOrReturn = diag::warn_suggest_noreturn_function;
else
D.diag_NeverFallThroughOrReturn = 0;
@@ -583,8 +580,7 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
D.diag_FallThrough_HasNoReturn = 0;
- D.diag_FallThrough_ReturnsNonVoid =
- diag::warn_falloff_nonvoid_coroutine;
+ D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid_coroutine;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Coroutine;
return D;
@@ -592,10 +588,8 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForBlock() {
CheckFallThroughDiagnostics D;
- D.diag_FallThrough_HasNoReturn =
- diag::err_noreturn_block_has_return_expr;
- D.diag_FallThrough_ReturnsNonVoid =
- diag::err_falloff_nonvoid_block;
+ D.diag_FallThrough_HasNoReturn = diag::err_noreturn_block_has_return_expr;
+ D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid_block;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Block;
return D;
@@ -603,10 +597,8 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForLambda() {
CheckFallThroughDiagnostics D;
- D.diag_FallThrough_HasNoReturn =
- diag::err_noreturn_lambda_has_return_expr;
- D.diag_FallThrough_ReturnsNonVoid =
- diag::warn_falloff_nonvoid_lambda;
+ D.diag_FallThrough_HasNoReturn = diag::err_noreturn_lambda_has_return_expr;
+ D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid_lambda;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Lambda;
return D;
@@ -616,8 +608,7 @@ struct CheckFallThroughDiagnostics {
bool HasNoReturn) const {
if (funMode == Function) {
return (ReturnsVoid ||
- D.isIgnored(diag::warn_falloff_nonvoid_function,
- FuncLoc)) &&
+ D.isIgnored(diag::warn_falloff_nonvoid_function, FuncLoc)) &&
(!HasNoReturn ||
D.isIgnored(diag::warn_noreturn_function_has_return_expr,
FuncLoc)) &&
@@ -627,8 +618,7 @@ struct CheckFallThroughDiagnostics {
if (funMode == Coroutine) {
return (ReturnsVoid ||
D.isIgnored(diag::warn_falloff_nonvoid_function, FuncLoc) ||
- D.isIgnored(diag::warn_falloff_nonvoid_coroutine,
- FuncLoc)) &&
+ D.isIgnored(diag::warn_falloff_nonvoid_coroutine, FuncLoc)) &&
(!HasNoReturn);
}
// For blocks / lambdas.
@@ -694,34 +684,34 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
// Either in a function body compound statement, or a function-try-block.
switch (CheckFallThrough(AC)) {
- case UnknownFallThrough:
- break;
+ case UnknownFallThrough:
+ break;
- case MaybeFallThrough:
- if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
- else if (!ReturnsVoid)
- S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << 1;
- break;
- case AlwaysFallThrough:
- if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
- else if (!ReturnsVoid)
- S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << 0;
- break;
- case NeverFallThroughOrReturn:
- if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 0 << FD;
- } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 1 << MD;
- } else {
- S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn);
- }
+ case MaybeFallThrough:
+ if (HasNoReturn)
+ EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
+ else if (!ReturnsVoid)
+ S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << 1;
+ break;
+ case AlwaysFallThrough:
+ if (HasNoReturn)
+ EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
+ else if (!ReturnsVoid)
+ S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << 0;
+ break;
+ case NeverFallThroughOrReturn:
+ if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 0 << FD;
+ } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+ S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 1 << MD;
+ } else {
+ S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn);
}
- break;
- case NeverFallThrough:
- break;
+ }
+ break;
+ case NeverFallThrough:
+ break;
}
}
>From 724e41ce48e74e65ce28b99127853bbaf0222dae Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Mon, 17 Feb 2025 23:22:51 +0100
Subject: [PATCH 03/12] Merge warn_falloff_nonvoid_* into warn_falloff_nonvoid
---
.../clang/Basic/DiagnosticSemaKinds.td | 17 +++++++----------
clang/lib/Sema/AnalysisBasedWarnings.cpp | 19 +++++++++----------
2 files changed, 16 insertions(+), 20 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e13626b38c50e..bcc1c595807f9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -713,8 +713,13 @@ def err_thread_non_global : Error<
def err_thread_unsupported : Error<
"thread-local storage is not supported for the current target">;
-def warn_falloff_nonvoid_function : Warning<
- "non-void function does not return a value%select{| in all control paths}0">,
+def warn_falloff_nonvoid : Warning<
+ "non-void %select{function|block|lambda|coroutine}0 "
+ "does not return a value%select{| in all control paths}1">,
+ InGroup<ReturnType>;
+def err_falloff_nonvoid : Warning<
+ "non-void %select{function|block|lambda|coroutine}0 "
+ "does not return a value%select{| in all control paths}1">,
InGroup<ReturnType>;
def warn_const_attr_with_pure_attr : Warning<
"'const' attribute imposes more restrictions; 'pure' attribute ignored">,
@@ -723,11 +728,6 @@ def warn_pure_function_returns_void : Warning<
"'%select{pure|const}0' attribute on function returning 'void'; attribute ignored">,
InGroup<IgnoredAttributes>;
-def err_falloff_nonvoid_block : Error<
- "non-void block does not return a value%select{| in all control paths}0">;
-def warn_falloff_nonvoid_coroutine : Warning<
- "non-void coroutine does not return a value%select{| in all control paths}0">,
- InGroup<ReturnType>;
def warn_suggest_noreturn_function : Warning<
"%select{function|method}0 %1 could be declared with attribute 'noreturn'">,
InGroup<MissingNoreturn>, DefaultIgnore;
@@ -8399,9 +8399,6 @@ let CategoryName = "Lambda Issue" in {
"incomplete result type %0 in lambda expression">;
def err_noreturn_lambda_has_return_expr : Error<
"lambda declared 'noreturn' should not return">;
- def warn_falloff_nonvoid_lambda : Warning<
- "non-void lambda does not return a value%select{| in all control paths}0">,
- InGroup<ReturnType>;
def err_access_lambda_capture : Error<
// The ERRORs represent other special members that aren't constructors, in
// hopes that someone will bother noticing and reporting if they appear
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 1929178be2ddb..82c60a30c39c1 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -547,14 +547,14 @@ struct CheckFallThroughDiagnostics {
unsigned diag_FallThrough_HasNoReturn;
unsigned diag_FallThrough_ReturnsNonVoid;
unsigned diag_NeverFallThroughOrReturn;
- enum { Function, Block, Lambda, Coroutine } funMode;
+ enum { Function = 0, Block, Lambda, Coroutine } funMode;
SourceLocation FuncLoc;
static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
D.diag_FallThrough_HasNoReturn = diag::warn_falloff_noreturn_function;
- D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid_function;
+ D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
// Don't suggest that virtual functions be marked "noreturn", since they
// might be overridden by non-noreturn functions.
@@ -580,7 +580,7 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
D.diag_FallThrough_HasNoReturn = 0;
- D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid_coroutine;
+ D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Coroutine;
return D;
@@ -589,7 +589,7 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForBlock() {
CheckFallThroughDiagnostics D;
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_block_has_return_expr;
- D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid_block;
+ D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Block;
return D;
@@ -598,7 +598,7 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForLambda() {
CheckFallThroughDiagnostics D;
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_lambda_has_return_expr;
- D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid_lambda;
+ D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Lambda;
return D;
@@ -608,7 +608,7 @@ struct CheckFallThroughDiagnostics {
bool HasNoReturn) const {
if (funMode == Function) {
return (ReturnsVoid ||
- D.isIgnored(diag::warn_falloff_nonvoid_function, FuncLoc)) &&
+ D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn ||
D.isIgnored(diag::warn_noreturn_function_has_return_expr,
FuncLoc)) &&
@@ -617,8 +617,7 @@ struct CheckFallThroughDiagnostics {
}
if (funMode == Coroutine) {
return (ReturnsVoid ||
- D.isIgnored(diag::warn_falloff_nonvoid_function, FuncLoc) ||
- D.isIgnored(diag::warn_falloff_nonvoid_coroutine, FuncLoc)) &&
+ D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn);
}
// For blocks / lambdas.
@@ -691,13 +690,13 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
if (HasNoReturn)
EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
else if (!ReturnsVoid)
- S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << 1;
+ S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.funMode << 1;
break;
case AlwaysFallThrough:
if (HasNoReturn)
EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
else if (!ReturnsVoid)
- S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << 0;
+ S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.funMode << 0;
break;
case NeverFallThroughOrReturn:
if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
>From a0fdfa08df94be97eda12b29cf5dc659dff98758 Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Mon, 17 Feb 2025 23:37:14 +0100
Subject: [PATCH 04/12] err_falloff_nonvoid should be Error
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index bcc1c595807f9..9d27ca2af44b8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -717,10 +717,9 @@ def warn_falloff_nonvoid : Warning<
"non-void %select{function|block|lambda|coroutine}0 "
"does not return a value%select{| in all control paths}1">,
InGroup<ReturnType>;
-def err_falloff_nonvoid : Warning<
+def err_falloff_nonvoid : Error<
"non-void %select{function|block|lambda|coroutine}0 "
- "does not return a value%select{| in all control paths}1">,
- InGroup<ReturnType>;
+ "does not return a value%select{| in all control paths}1">;
def warn_const_attr_with_pure_attr : Warning<
"'const' attribute imposes more restrictions; 'pure' attribute ignored">,
InGroup<IgnoredAttributes>;
>From 4d3a785b36913772f8922bf0fe36af21f5e65c8f Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Tue, 18 Feb 2025 19:56:24 +0100
Subject: [PATCH 05/12] Merge err_noreturn_has_return_expr
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 12 ++++++------
clang/lib/Sema/AnalysisBasedWarnings.cpp | 16 ++++++++--------
clang/lib/Sema/SemaStmt.cpp | 4 ++--
3 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9d27ca2af44b8..e00c4183e36ca 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8396,8 +8396,6 @@ let CategoryName = "Lambda Issue" in {
"lambda expression in default argument cannot capture any entity">;
def err_lambda_incomplete_result : Error<
"incomplete result type %0 in lambda expression">;
- def err_noreturn_lambda_has_return_expr : Error<
- "lambda declared 'noreturn' should not return">;
def err_access_lambda_capture : Error<
// The ERRORs represent other special members that aren't constructors, in
// hopes that someone will bother noticing and reporting if they appear
@@ -10587,14 +10585,16 @@ def err_ctor_dtor_returns_void : Error<
def warn_noreturn_function_has_return_expr : Warning<
"function %0 declared 'noreturn' should not return">,
InGroup<InvalidNoreturn>;
-def warn_falloff_noreturn_function : Warning<
- "function declared 'noreturn' should not return">,
+def warn_noreturn_has_return_expr : Warning<
+ "%select{function|block|lambda|coroutine}0 "
+ "declared 'noreturn' should not return">,
InGroup<InvalidNoreturn>;
+def err_noreturn_has_return_expr : Error<
+ "%select{function|block|lambda|coroutine}0 "
+ "declared 'noreturn' should not return">;
def warn_noreturn_coroutine : Warning<
"coroutine %0 cannot be declared 'noreturn' as it always returns a coroutine handle">,
InGroup<InvalidNoreturn>;
-def err_noreturn_block_has_return_expr : Error<
- "block declared 'noreturn' should not return">;
def err_carries_dependency_missing_on_first_decl : Error<
"%select{function|parameter}0 declared '[[carries_dependency]]' "
"after its first declaration">;
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 82c60a30c39c1..c392712bd8dec 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -553,7 +553,7 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
- D.diag_FallThrough_HasNoReturn = diag::warn_falloff_noreturn_function;
+ D.diag_FallThrough_HasNoReturn = diag::warn_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
// Don't suggest that virtual functions be marked "noreturn", since they
@@ -588,7 +588,7 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForBlock() {
CheckFallThroughDiagnostics D;
- D.diag_FallThrough_HasNoReturn = diag::err_noreturn_block_has_return_expr;
+ D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Block;
@@ -597,7 +597,7 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForLambda() {
CheckFallThroughDiagnostics D;
- D.diag_FallThrough_HasNoReturn = diag::err_noreturn_lambda_has_return_expr;
+ D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
D.diag_NeverFallThroughOrReturn = 0;
D.funMode = Lambda;
@@ -610,7 +610,7 @@ struct CheckFallThroughDiagnostics {
return (ReturnsVoid ||
D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn ||
- D.isIgnored(diag::warn_noreturn_function_has_return_expr,
+ D.isIgnored(diag::warn_noreturn_has_return_expr,
FuncLoc)) &&
(!ReturnsVoid ||
D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
@@ -668,12 +668,12 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
return;
SourceLocation LBrace = Body->getBeginLoc(), RBrace = Body->getEndLoc();
- auto EmitDiag = [&](SourceLocation Loc, unsigned DiagID) {
+ auto EmitDiag = [&](SourceLocation Loc, unsigned DiagID, unsigned FunMode) {
if (IsCoroutine) {
if (DiagID != 0)
S.Diag(Loc, DiagID) << FSI->CoroutinePromise->getType();
} else {
- S.Diag(Loc, DiagID);
+ S.Diag(Loc, DiagID) << FunMode;
}
};
@@ -688,13 +688,13 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
case MaybeFallThrough:
if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
+ EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn, CD.funMode);
else if (!ReturnsVoid)
S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.funMode << 1;
break;
case AlwaysFallThrough:
if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn);
+ EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn, CD.funMode);
else if (!ReturnsVoid)
S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.funMode << 0;
break;
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 0394edb7889ba..fdf7e390570d9 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3590,7 +3590,7 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
if (CurBlock->FunctionType->castAs<FunctionType>()->getNoReturnAttr()) {
- Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr);
+ Diag(ReturnLoc, diag::err_noreturn_has_return_expr) << 1;
return StmtError();
}
} else if (auto *CurRegion = dyn_cast<CapturedRegionScopeInfo>(CurCap)) {
@@ -3601,7 +3601,7 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
if (CurLambda->CallOperator->getType()
->castAs<FunctionType>()
->getNoReturnAttr()) {
- Diag(ReturnLoc, diag::err_noreturn_lambda_has_return_expr);
+ Diag(ReturnLoc, diag::err_noreturn_has_return_expr) << 2;
return StmtError();
}
}
>From 9187f9ea3b022ba23b981004e235045cf635e3c7 Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Tue, 18 Feb 2025 20:28:56 +0100
Subject: [PATCH 06/12] Use enum_select for generating diag::FunModes structure
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++--
clang/lib/Sema/AnalysisBasedWarnings.cpp | 14 +++++++-------
clang/lib/Sema/SemaStmt.cpp | 4 ++--
3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e00c4183e36ca..74f26164ccfc8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -714,8 +714,9 @@ def err_thread_unsupported : Error<
"thread-local storage is not supported for the current target">;
def warn_falloff_nonvoid : Warning<
- "non-void %select{function|block|lambda|coroutine}0 "
- "does not return a value%select{| in all control paths}1">,
+ "non-void "
+ "%enum_select<FunModes>{%Function{function}|%Block{block}|%Lambda{lambda}|%Coroutine{coroutine}}0"
+ " does not return a value%select{| in all control paths}1">,
InGroup<ReturnType>;
def err_falloff_nonvoid : Error<
"non-void %select{function|block|lambda|coroutine}0 "
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index c392712bd8dec..13bf433be6068 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -547,7 +547,7 @@ struct CheckFallThroughDiagnostics {
unsigned diag_FallThrough_HasNoReturn;
unsigned diag_FallThrough_ReturnsNonVoid;
unsigned diag_NeverFallThroughOrReturn;
- enum { Function = 0, Block, Lambda, Coroutine } funMode;
+ unsigned funMode; // TODO: use diag::FunModes
SourceLocation FuncLoc;
static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
@@ -572,7 +572,7 @@ struct CheckFallThroughDiagnostics {
else
D.diag_NeverFallThroughOrReturn = 0;
- D.funMode = Function;
+ D.funMode = diag::FunModes::Function;
return D;
}
@@ -582,7 +582,7 @@ struct CheckFallThroughDiagnostics {
D.diag_FallThrough_HasNoReturn = 0;
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
D.diag_NeverFallThroughOrReturn = 0;
- D.funMode = Coroutine;
+ D.funMode = diag::FunModes::Coroutine;
return D;
}
@@ -591,7 +591,7 @@ struct CheckFallThroughDiagnostics {
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid;
D.diag_NeverFallThroughOrReturn = 0;
- D.funMode = Block;
+ D.funMode = diag::FunModes::Block;
return D;
}
@@ -600,13 +600,13 @@ struct CheckFallThroughDiagnostics {
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
D.diag_NeverFallThroughOrReturn = 0;
- D.funMode = Lambda;
+ D.funMode = diag::FunModes::Lambda;
return D;
}
bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,
bool HasNoReturn) const {
- if (funMode == Function) {
+ if (funMode == diag::FunModes::Function) {
return (ReturnsVoid ||
D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn ||
@@ -615,7 +615,7 @@ struct CheckFallThroughDiagnostics {
(!ReturnsVoid ||
D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
}
- if (funMode == Coroutine) {
+ if (funMode == diag::FunModes::Coroutine) {
return (ReturnsVoid ||
D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn);
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index fdf7e390570d9..93b2e10ba0a78 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3590,7 +3590,7 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
if (CurBlock->FunctionType->castAs<FunctionType>()->getNoReturnAttr()) {
- Diag(ReturnLoc, diag::err_noreturn_has_return_expr) << 1;
+ Diag(ReturnLoc, diag::err_noreturn_has_return_expr) << diag::FunModes::Block;
return StmtError();
}
} else if (auto *CurRegion = dyn_cast<CapturedRegionScopeInfo>(CurCap)) {
@@ -3601,7 +3601,7 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
if (CurLambda->CallOperator->getType()
->castAs<FunctionType>()
->getNoReturnAttr()) {
- Diag(ReturnLoc, diag::err_noreturn_has_return_expr) << 2;
+ Diag(ReturnLoc, diag::err_noreturn_has_return_expr) << diag::FunModes::Lambda;
return StmtError();
}
}
>From 5d20d275f7033c3aaface6325ef2ebb8faf493ff Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Tue, 18 Feb 2025 20:39:44 +0100
Subject: [PATCH 07/12] Apply clang-format
---
clang/lib/Sema/AnalysisBasedWarnings.cpp | 3 +--
clang/lib/Sema/SemaStmt.cpp | 6 ++++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 13bf433be6068..7ead5e5c1011a 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -610,8 +610,7 @@ struct CheckFallThroughDiagnostics {
return (ReturnsVoid ||
D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn ||
- D.isIgnored(diag::warn_noreturn_has_return_expr,
- FuncLoc)) &&
+ D.isIgnored(diag::warn_noreturn_has_return_expr, FuncLoc)) &&
(!ReturnsVoid ||
D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
}
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 93b2e10ba0a78..cbef77640019c 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3590,7 +3590,8 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
if (CurBlock->FunctionType->castAs<FunctionType>()->getNoReturnAttr()) {
- Diag(ReturnLoc, diag::err_noreturn_has_return_expr) << diag::FunModes::Block;
+ Diag(ReturnLoc, diag::err_noreturn_has_return_expr)
+ << diag::FunModes::Block;
return StmtError();
}
} else if (auto *CurRegion = dyn_cast<CapturedRegionScopeInfo>(CurCap)) {
@@ -3601,7 +3602,8 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
if (CurLambda->CallOperator->getType()
->castAs<FunctionType>()
->getNoReturnAttr()) {
- Diag(ReturnLoc, diag::err_noreturn_has_return_expr) << diag::FunModes::Lambda;
+ Diag(ReturnLoc, diag::err_noreturn_has_return_expr)
+ << diag::FunModes::Lambda;
return StmtError();
}
}
>From 146642ed8a63e624dce4833bb91ef1ccf525ccd4 Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Tue, 18 Feb 2025 21:52:50 +0100
Subject: [PATCH 08/12] Use default values in CheckFallThroughDiagnostics
structure
---
clang/lib/Sema/AnalysisBasedWarnings.cpp | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 7ead5e5c1011a..9e884d56ded1d 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -544,9 +544,9 @@ static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
namespace {
struct CheckFallThroughDiagnostics {
- unsigned diag_FallThrough_HasNoReturn;
- unsigned diag_FallThrough_ReturnsNonVoid;
- unsigned diag_NeverFallThroughOrReturn;
+ unsigned diag_FallThrough_HasNoReturn = 0;
+ unsigned diag_FallThrough_ReturnsNonVoid = 0;
+ unsigned diag_NeverFallThroughOrReturn = 0;
unsigned funMode; // TODO: use diag::FunModes
SourceLocation FuncLoc;
@@ -569,8 +569,6 @@ struct CheckFallThroughDiagnostics {
if (!isVirtualMethod && !isTemplateInstantiation)
D.diag_NeverFallThroughOrReturn = diag::warn_suggest_noreturn_function;
- else
- D.diag_NeverFallThroughOrReturn = 0;
D.funMode = diag::FunModes::Function;
return D;
@@ -579,9 +577,7 @@ struct CheckFallThroughDiagnostics {
static CheckFallThroughDiagnostics MakeForCoroutine(const Decl *Func) {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
- D.diag_FallThrough_HasNoReturn = 0;
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
- D.diag_NeverFallThroughOrReturn = 0;
D.funMode = diag::FunModes::Coroutine;
return D;
}
@@ -590,7 +586,6 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid;
- D.diag_NeverFallThroughOrReturn = 0;
D.funMode = diag::FunModes::Block;
return D;
}
@@ -599,7 +594,6 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
- D.diag_NeverFallThroughOrReturn = 0;
D.funMode = diag::FunModes::Lambda;
return D;
}
>From ccfa4c6778c846a22cccf2c90bf965d696b8d4fe Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Tue, 18 Feb 2025 22:04:25 +0100
Subject: [PATCH 09/12] funMode -> FunMode
---
clang/lib/Sema/AnalysisBasedWarnings.cpp | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 9e884d56ded1d..8c097858286ea 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -547,7 +547,7 @@ struct CheckFallThroughDiagnostics {
unsigned diag_FallThrough_HasNoReturn = 0;
unsigned diag_FallThrough_ReturnsNonVoid = 0;
unsigned diag_NeverFallThroughOrReturn = 0;
- unsigned funMode; // TODO: use diag::FunModes
+ unsigned FunMode; // TODO: use diag::FunModes
SourceLocation FuncLoc;
static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
@@ -570,7 +570,7 @@ struct CheckFallThroughDiagnostics {
if (!isVirtualMethod && !isTemplateInstantiation)
D.diag_NeverFallThroughOrReturn = diag::warn_suggest_noreturn_function;
- D.funMode = diag::FunModes::Function;
+ D.FunMode = diag::FunModes::Function;
return D;
}
@@ -578,7 +578,7 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
- D.funMode = diag::FunModes::Coroutine;
+ D.FunMode = diag::FunModes::Coroutine;
return D;
}
@@ -586,7 +586,7 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid;
- D.funMode = diag::FunModes::Block;
+ D.FunMode = diag::FunModes::Block;
return D;
}
@@ -594,13 +594,13 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
- D.funMode = diag::FunModes::Lambda;
+ D.FunMode = diag::FunModes::Lambda;
return D;
}
bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,
bool HasNoReturn) const {
- if (funMode == diag::FunModes::Function) {
+ if (FunMode == diag::FunModes::Function) {
return (ReturnsVoid ||
D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn ||
@@ -608,7 +608,7 @@ struct CheckFallThroughDiagnostics {
(!ReturnsVoid ||
D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
}
- if (funMode == diag::FunModes::Coroutine) {
+ if (FunMode == diag::FunModes::Coroutine) {
return (ReturnsVoid ||
D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn);
@@ -681,15 +681,15 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
case MaybeFallThrough:
if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn, CD.funMode);
+ EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn, CD.FunMode);
else if (!ReturnsVoid)
- S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.funMode << 1;
+ S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.FunMode << 1;
break;
case AlwaysFallThrough:
if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn, CD.funMode);
+ EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn, CD.FunMode);
else if (!ReturnsVoid)
- S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.funMode << 0;
+ S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.FunMode << 0;
break;
case NeverFallThroughOrReturn:
if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
>From 5ba28fcfa2237d12137e98a0a8d84882b737b885 Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Tue, 18 Feb 2025 23:01:16 +0100
Subject: [PATCH 10/12] Remove EmitDiag and merge branches in switch-case
---
clang/lib/Sema/AnalysisBasedWarnings.cpp | 34 +++++++++---------------
1 file changed, 12 insertions(+), 22 deletions(-)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 8c097858286ea..6f816af9d222d 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -627,12 +627,10 @@ struct CheckFallThroughDiagnostics {
static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
QualType BlockType,
const CheckFallThroughDiagnostics &CD,
- AnalysisDeclContext &AC,
- sema::FunctionScopeInfo *FSI) {
+ AnalysisDeclContext &AC) {
bool ReturnsVoid = false;
bool HasNoReturn = false;
- bool IsCoroutine = FSI->isCoroutine();
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
if (const auto *CBody = dyn_cast<CoroutineBodyStmt>(Body))
@@ -661,35 +659,27 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
return;
SourceLocation LBrace = Body->getBeginLoc(), RBrace = Body->getEndLoc();
- auto EmitDiag = [&](SourceLocation Loc, unsigned DiagID, unsigned FunMode) {
- if (IsCoroutine) {
- if (DiagID != 0)
- S.Diag(Loc, DiagID) << FSI->CoroutinePromise->getType();
- } else {
- S.Diag(Loc, DiagID) << FunMode;
- }
- };
// cpu_dispatch functions permit empty function bodies for ICC compatibility.
if (D->getAsFunction() && D->getAsFunction()->isCPUDispatchMultiVersion())
return;
// Either in a function body compound statement, or a function-try-block.
- switch (CheckFallThrough(AC)) {
+ int FallThroughType = CheckFallThrough(AC);
+ switch (FallThroughType) {
case UnknownFallThrough:
break;
case MaybeFallThrough:
- if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn, CD.FunMode);
- else if (!ReturnsVoid)
- S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.FunMode << 1;
- break;
case AlwaysFallThrough:
- if (HasNoReturn)
- EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn, CD.FunMode);
- else if (!ReturnsVoid)
- S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.FunMode << 0;
+ if (HasNoReturn && CD.diag_FallThrough_HasNoReturn != 0) {
+ S.Diag(RBrace, CD.diag_FallThrough_HasNoReturn) << CD.FunMode;
+ } else if (!ReturnsVoid && CD.diag_FallThrough_ReturnsNonVoid != 0) {
+ unsigned NotInAllControlPath =
+ FallThroughType == MaybeFallThrough ? 1 : 0;
+ S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid)
+ << CD.FunMode << NotInAllControlPath;
+ }
break;
case NeverFallThroughOrReturn:
if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
@@ -2730,7 +2720,7 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
: (fscope->isCoroutine()
? CheckFallThroughDiagnostics::MakeForCoroutine(D)
: CheckFallThroughDiagnostics::MakeForFunction(D)));
- CheckFallThroughForBody(S, D, Body, BlockType, CD, AC, fscope);
+ CheckFallThroughForBody(S, D, Body, BlockType, CD, AC);
}
// Warning: check for unreachable code
>From b92b4bb532093fa436c3484bfc1cf8c84cf3afc8 Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Tue, 18 Feb 2025 23:40:25 +0100
Subject: [PATCH 11/12] Apply suggestions
---
clang/lib/Sema/AnalysisBasedWarnings.cpp | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 6f816af9d222d..af7e2377e3d5f 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -665,20 +665,19 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
return;
// Either in a function body compound statement, or a function-try-block.
- int FallThroughType = CheckFallThrough(AC);
- switch (FallThroughType) {
+ switch (int FallThroughType = CheckFallThrough(AC)) {
case UnknownFallThrough:
break;
case MaybeFallThrough:
case AlwaysFallThrough:
- if (HasNoReturn && CD.diag_FallThrough_HasNoReturn != 0) {
- S.Diag(RBrace, CD.diag_FallThrough_HasNoReturn) << CD.FunMode;
- } else if (!ReturnsVoid && CD.diag_FallThrough_ReturnsNonVoid != 0) {
- unsigned NotInAllControlPath =
- FallThroughType == MaybeFallThrough ? 1 : 0;
+ if (HasNoReturn) {
+ if (CD.diag_FallThrough_HasNoReturn)
+ S.Diag(RBrace, CD.diag_FallThrough_HasNoReturn) << CD.FunMode;
+ } else if (!ReturnsVoid && CD.diag_FallThrough_ReturnsNonVoid) {
+ bool NotInAllControlPaths = FallThroughType == MaybeFallThrough;
S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid)
- << CD.FunMode << NotInAllControlPath;
+ << CD.FunMode << NotInAllControlPaths;
}
break;
case NeverFallThroughOrReturn:
>From 466da73bbab891f324de6846a2161b655ad08d18 Mon Sep 17 00:00:00 2001
From: "Igor S. Gerasimov" <i.s.ger at ya.ru>
Date: Wed, 19 Feb 2025 18:14:19 +0100
Subject: [PATCH 12/12] Use FunctionKind instead FunModes
---
.../include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
clang/lib/Sema/AnalysisBasedWarnings.cpp | 18 +++++++++---------
clang/lib/Sema/SemaStmt.cpp | 4 ++--
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 74f26164ccfc8..07071a04edd90 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -715,7 +715,7 @@ def err_thread_unsupported : Error<
def warn_falloff_nonvoid : Warning<
"non-void "
- "%enum_select<FunModes>{%Function{function}|%Block{block}|%Lambda{lambda}|%Coroutine{coroutine}}0"
+ "%enum_select<FunctionKind>{%Function{function}|%Block{block}|%Lambda{lambda}|%Coroutine{coroutine}}0"
" does not return a value%select{| in all control paths}1">,
InGroup<ReturnType>;
def err_falloff_nonvoid : Error<
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index af7e2377e3d5f..4acb4c054a0ad 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -547,7 +547,7 @@ struct CheckFallThroughDiagnostics {
unsigned diag_FallThrough_HasNoReturn = 0;
unsigned diag_FallThrough_ReturnsNonVoid = 0;
unsigned diag_NeverFallThroughOrReturn = 0;
- unsigned FunMode; // TODO: use diag::FunModes
+ unsigned FunKind; // TODO: use diag::FunctionKind
SourceLocation FuncLoc;
static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
@@ -570,7 +570,7 @@ struct CheckFallThroughDiagnostics {
if (!isVirtualMethod && !isTemplateInstantiation)
D.diag_NeverFallThroughOrReturn = diag::warn_suggest_noreturn_function;
- D.FunMode = diag::FunModes::Function;
+ D.FunKind = diag::FunctionKind::Function;
return D;
}
@@ -578,7 +578,7 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
- D.FunMode = diag::FunModes::Coroutine;
+ D.FunKind = diag::FunctionKind::Coroutine;
return D;
}
@@ -586,7 +586,7 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::err_falloff_nonvoid;
- D.FunMode = diag::FunModes::Block;
+ D.FunKind = diag::FunctionKind::Block;
return D;
}
@@ -594,13 +594,13 @@ struct CheckFallThroughDiagnostics {
CheckFallThroughDiagnostics D;
D.diag_FallThrough_HasNoReturn = diag::err_noreturn_has_return_expr;
D.diag_FallThrough_ReturnsNonVoid = diag::warn_falloff_nonvoid;
- D.FunMode = diag::FunModes::Lambda;
+ D.FunKind = diag::FunctionKind::Lambda;
return D;
}
bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,
bool HasNoReturn) const {
- if (FunMode == diag::FunModes::Function) {
+ if (FunKind == diag::FunctionKind::Function) {
return (ReturnsVoid ||
D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn ||
@@ -608,7 +608,7 @@ struct CheckFallThroughDiagnostics {
(!ReturnsVoid ||
D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
}
- if (FunMode == diag::FunModes::Coroutine) {
+ if (FunKind == diag::FunctionKind::Coroutine) {
return (ReturnsVoid ||
D.isIgnored(diag::warn_falloff_nonvoid, FuncLoc)) &&
(!HasNoReturn);
@@ -673,11 +673,11 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
case AlwaysFallThrough:
if (HasNoReturn) {
if (CD.diag_FallThrough_HasNoReturn)
- S.Diag(RBrace, CD.diag_FallThrough_HasNoReturn) << CD.FunMode;
+ S.Diag(RBrace, CD.diag_FallThrough_HasNoReturn) << CD.FunKind;
} else if (!ReturnsVoid && CD.diag_FallThrough_ReturnsNonVoid) {
bool NotInAllControlPaths = FallThroughType == MaybeFallThrough;
S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid)
- << CD.FunMode << NotInAllControlPaths;
+ << CD.FunKind << NotInAllControlPaths;
}
break;
case NeverFallThroughOrReturn:
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index cbef77640019c..bf06802688f7f 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3591,7 +3591,7 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
if (CurBlock->FunctionType->castAs<FunctionType>()->getNoReturnAttr()) {
Diag(ReturnLoc, diag::err_noreturn_has_return_expr)
- << diag::FunModes::Block;
+ << diag::FunctionKind::Block;
return StmtError();
}
} else if (auto *CurRegion = dyn_cast<CapturedRegionScopeInfo>(CurCap)) {
@@ -3603,7 +3603,7 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
->castAs<FunctionType>()
->getNoReturnAttr()) {
Diag(ReturnLoc, diag::err_noreturn_has_return_expr)
- << diag::FunModes::Lambda;
+ << diag::FunctionKind::Lambda;
return StmtError();
}
}
More information about the cfe-commits
mailing list