https://github.com/foxtran updated https://github.com/llvm/llvm-project/pull/127546
>From 80f3250eadc887d76abf9c2edbec6285aef6d5d2 Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" <i.s....@ya.ru> Date: Mon, 17 Feb 2025 22:39:31 +0100 Subject: [PATCH 1/8] 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 f10af8f5bd6b2..ff00c76c5e492 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 589869d018657..7b28781ede0ca 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); } @@ -714,15 +697,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 8a87f68eb14e67cf76877ddde0d7a06878ec562d Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" <i.s....@ya.ru> Date: Mon, 17 Feb 2025 22:41:29 +0100 Subject: [PATCH 2/8] 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 7b28781ede0ca..da44ff6f08ff7 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. @@ -692,34 +682,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 adecfd4bcafc6dc73b77072ed9f2bdd120bcfeab Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" <i.s....@ya.ru> Date: Mon, 17 Feb 2025 23:22:51 +0100 Subject: [PATCH 3/8] 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 ff00c76c5e492..5f53adc2f15c8 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 da44ff6f08ff7..ef527374b811f 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. @@ -689,13 +688,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 8743f30f0586fb70516e26bb06722f726673c0e3 Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" <i.s....@ya.ru> Date: Mon, 17 Feb 2025 23:37:14 +0100 Subject: [PATCH 4/8] 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 5f53adc2f15c8..4a7b33ebd01f4 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 207aa88526f50ac68819990e0a29db8d1dc8fb8f Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" <i.s....@ya.ru> Date: Tue, 18 Feb 2025 19:56:24 +0100 Subject: [PATCH 5/8] Merge err_noreturn_has_return_expr --- .../clang/Basic/DiagnosticSemaKinds.td | 12 +++++----- clang/lib/Sema/AnalysisBasedWarnings.cpp | 24 +++++++------------ clang/lib/Sema/SemaStmt.cpp | 4 ++-- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 4a7b33ebd01f4..220fd3107ad2e 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,11 +10585,13 @@ 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_block_has_return_expr : Error< - "block declared 'noreturn' should not return">; +def err_noreturn_has_return_expr : Error< + "%select{function|block|lambda|coroutine}0 " + "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 ef527374b811f..4c7844b39edb1 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)); @@ -634,12 +634,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)) @@ -668,12 +666,6 @@ 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) { - if (IsCoroutine) - S.Diag(Loc, DiagID) << FSI->CoroutinePromise->getType(); - else - S.Diag(Loc, DiagID); - }; // cpu_dispatch functions permit empty function bodies for ICC compatibility. if (D->getAsFunction() && D->getAsFunction()->isCPUDispatchMultiVersion()) @@ -686,13 +678,13 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, case MaybeFallThrough: if (HasNoReturn) - EmitDiag(RBrace, CD.diag_FallThrough_HasNoReturn); + S.Diag(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); + S.Diag(RBrace, CD.diag_FallThrough_HasNoReturn) << CD.funMode; else if (!ReturnsVoid) S.Diag(RBrace, CD.diag_FallThrough_ReturnsNonVoid) << CD.funMode << 0; break; @@ -2735,7 +2727,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 diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index ec38674a2c3e7..a65649b7c2ff6 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 973dde560d5ae499ffacf3cdd1d18d42465057fb Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" <i.s....@ya.ru> Date: Tue, 18 Feb 2025 20:28:56 +0100 Subject: [PATCH 6/8] 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 220fd3107ad2e..01ea849a64d6e 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 4c7844b39edb1..e6fc886f8dc59 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 a65649b7c2ff6..36fb68a73c52d 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 164e26072339f6c7890bd5a6d3d56e90613dd3fc Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" <i.s....@ya.ru> Date: Tue, 18 Feb 2025 20:39:44 +0100 Subject: [PATCH 7/8] 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 e6fc886f8dc59..2e15dca0c6073 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 36fb68a73c52d..ca744328ffbd1 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 df9a7129862abfdd4d5f015876ba930f0eda8c65 Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" <i.s....@ya.ru> Date: Tue, 18 Feb 2025 21:52:50 +0100 Subject: [PATCH 8/8] 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 2e15dca0c6073..092a8088b4c21 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; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits