https://github.com/Expertcoderz updated https://github.com/llvm/llvm-project/pull/225748
>From 730360dc5a0f855d996f12b7f8ab2f8bdf5ebff1 Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 08:22:44 +0000 Subject: [PATCH 01/15] [Clang][Sema] Add -Wredundant-defer to diagnose redundant `_Defer`s This PR adds a new `-Wredundant-defer` diagnostic to have Clang emit warnings for superfluous uses of `_Defer`, where the substatement is always executed at the point of defer. With `-Wredundant-defer`, `_Defer` statements that occur in these positions will trigger the warning: - as the last statement of a compound statement or function - as the body of an `if`/`else` statement - as the body of a `for`/`while` loop - immediately preceding a `break` or `continue` statement - as the substatement of another `_Defer` This helps to detect mistakes and some potential misuses of `_Defer`. --- clang/docs/ReleaseNotes.md | 5 + clang/include/clang/Basic/DiagnosticGroups.td | 2 + .../clang/Basic/DiagnosticSemaKinds.td | 4 + clang/lib/Sema/SemaStmt.cpp | 41 ++++- clang/test/Parser/defer-ts.c | 4 +- clang/test/Sema/warn-redundant-defer.c | 151 ++++++++++++++++++ 6 files changed, 203 insertions(+), 4 deletions(-) create mode 100644 clang/test/Sema/warn-redundant-defer.c diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index e5da258b9950a3..a0126b0785d59d 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -518,6 +518,11 @@ features cannot lower the translation-unit ABI level; - Improve Clang diagnoses when unary `__imag` operator with non-complex type operand is used as lvalue. (GH222383) +- Added `-Wredundant-defer` to diagnose redundant uses of the `_Defer` + keyword, such as when deferring the last statement of a block; when + used as the body of a conditional; or when it immediately precedes + a `break`/`continue` statement. + ### Improvements to Clang's time-trace ### Improvements to Coverage Mapping diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 1da7698944b24b..4b35e4247e2c4c 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -345,6 +345,8 @@ def EmptyBody : DiagGroup<"empty-body">; def Exceptions : DiagGroup<"exceptions">; def DeclarationAfterStatement : DiagGroup<"declaration-after-statement">; +def RedundantDefer : DiagGroup<"redundant-defer">; + def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">; def ExtraTokens : DiagGroup<"extra-tokens">; def CXX98CompatExtraSemi : DiagGroup<"c++98-compat-extra-semi">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 36a18473f4d4cc..17a15406d003aa 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11342,6 +11342,10 @@ def warn_empty_defer_body : Warning< def note_empty_body_on_separate_line : Note< "put the semicolon on a separate line to silence this warning">; +def warn_redundant_defer: Warning< + "redundant use of defer; the deferred statement is executed immediately">, + InGroup<RedundantDefer>, DefaultIgnore; + def err_va_start_captured_stmt : Error< "'va_start' cannot be used in a captured statement">; def err_va_start_outside_function : Error< diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 74fe253efa1374..8454f4f2bd8421 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -470,6 +470,23 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]); } + // Find defer statements that immediately precede a break/continue statement. + std::optional<SourceLocation> DeferLoc = std::nullopt; + for (unsigned i = 0; i != NumElts; ++i) { + if (DeferLoc && isa<BreakStmt, ContinueStmt>(Elts[i])) + Diag(DeferLoc.value(), diag::warn_redundant_defer) + << Elts[i]->getSourceRange(); + DeferLoc = isa<DeferStmt>(Elts[i]) + ? std::optional<SourceLocation>(Elts[i]->getBeginLoc()) + : std::nullopt; + } + + // Check for defer as last statement. + Stmt *Back = NumElts > 0 ? Elts[NumElts - 1] : nullptr; + if (Back && isa<DeferStmt>(Back)) + Diag(Back->getBeginLoc(), diag::warn_redundant_defer) + << Back->getSourceRange(); + // Calculate difference between FP options in this compound statement and in // the enclosing one. If this is a function body, take the difference against // default options. In this case the difference will indicate options that are @@ -997,6 +1014,14 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc, if (!ConstevalOrNegatedConsteval && !elseStmt) DiagnoseEmptyStmtBody(RParenLoc, thenStmt, diag::warn_empty_if_body); + if (isa<DeferStmt>(thenStmt)) + Diag(thenStmt->getBeginLoc(), diag::warn_redundant_defer) + << thenStmt->getSourceRange(); + + if (elseStmt && isa<DeferStmt>(elseStmt)) + Diag(elseStmt->getBeginLoc(), diag::warn_redundant_defer) + << elseStmt->getSourceRange(); + if (ConstevalOrNegatedConsteval || StatementKind == IfStatementKind::Constexpr) { auto DiagnoseLikelihood = [&](const Stmt *S) { @@ -1837,6 +1862,9 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); + else if (isa<DeferStmt>(Body)) + Diag(Body->getBeginLoc(), diag::warn_redundant_defer) + << Body->getSourceRange(); return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body, WhileLoc, LParenLoc, RParenLoc); @@ -2328,6 +2356,9 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Expr *Third = third.release().getAs<Expr>(); if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); + else if (isa<DeferStmt>(Body)) + Diag(Body->getBeginLoc(), diag::warn_redundant_defer) + << Body->getSourceRange(); return new (Context) ForStmt(Context, First, Second.get().second, Second.get().first, Third, @@ -4033,11 +4064,17 @@ void Sema::ActOnDeferStmtError([[maybe_unused]] Scope *CurScope) { CurrentDefer.pop_back(); } -StmtResult Sema::ActOnEndOfDeferStmt(Stmt *Body, - [[maybe_unused]] Scope *CurScope) { +StmtResult Sema::ActOnEndOfDeferStmt(Stmt *Body, Scope *CurScope) { assert(!CurrentDefer.empty() && CurrentDefer.back().first == CurScope); + SourceLocation DeferLoc = CurrentDefer.pop_back_val().second; DiagnoseEmptyStmtBody(DeferLoc, Body, diag::warn_empty_defer_body); + + // Check for superfluous nested defer. + if (isa<DeferStmt>(Body)) + Diag(Body->getBeginLoc(), diag::warn_redundant_defer) + << Body->getSourceRange(); + setFunctionHasBranchProtectedScope(); return DeferStmt::Create(Context, DeferLoc, Body); } diff --git a/clang/test/Parser/defer-ts.c b/clang/test/Parser/defer-ts.c index 118fe9ee3cc8f5..1fe7eb2ec57163 100644 --- a/clang/test/Parser/defer-ts.c +++ b/clang/test/Parser/defer-ts.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c11 -fsyntax-only -fdefer-ts -verify %s -// RUN: %clang_cc1 -std=c23 -fsyntax-only -fdefer-ts -verify %s +// RUN: %clang_cc1 -std=c11 -fsyntax-only -fdefer-ts -Wno-redundant-defer -verify %s +// RUN: %clang_cc1 -std=c23 -fsyntax-only -fdefer-ts -Wno-redundant-defer -verify %s #define defer _Defer diff --git a/clang/test/Sema/warn-redundant-defer.c b/clang/test/Sema/warn-redundant-defer.c new file mode 100644 index 00000000000000..2d9b92bbe9b63b --- /dev/null +++ b/clang/test/Sema/warn-redundant-defer.c @@ -0,0 +1,151 @@ +// RUN: %clang_cc1 -std=c23 -fdefer-ts -fsyntax-only -verify %s -Wredundant-defer + +#define defer _Defer + +void f1() { + defer {} // expected-warning {{redundant use of defer}} +} + +void f2() { + defer {} // OK + + defer defer {} // expected-warning {{redundant use of defer}} + + defer defer defer {} // expected-warning 2 {{redundant use of defer}} + + { + defer {} // OK + f1(); + } + + { defer {} } // expected-warning {{redundant use of defer}} + + { defer defer {} } // expected-warning 2 {{redundant use of defer}} + + { + defer { // OK + defer {} // OK + f1(); + } + f1(); + } + + { + defer { // expected-warning {{redundant use of defer}} + defer defer {} // expected-warning 2 {{redundant use of defer}} + } + } + + if (true) { + defer {} // OK + f1(); + } + + if (true) + defer {} // expected-warning {{redundant use of defer}} + + if (true) { + defer {} // expected-warning {{redundant use of defer}} + } + + for (;;) { + defer {} // OK + f1(); + } + + for (;;) + defer {} // expected-warning {{redundant use of defer}} + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + } + + for (;;) { + defer {} // OK + f1(); + break; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + break; + } + + for (;;) { + defer {} // OK + f1(); + continue; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + continue; + } + + while (true) { + defer {} // OK + f1(); + } + + while (true) + defer {} // expected-warning {{redundant use of defer}} + + while (true) { + defer {} // expected-warning {{redundant use of defer}} + } + + while (true) { + defer {} // OK + f1(); + break; + } + + while (true) { + defer {} // expected-warning {{redundant use of defer}} + break; + } + + while (true) { + defer {} // OK + f1(); + continue; + } + + while (true) { + defer {} // expected-warning {{redundant use of defer}} + continue; + } + + do { + defer {} // OK + f1(); + } while (true); + + do { + defer {} // expected-warning {{redundant use of defer}} + } while (true); + + do { + defer {} // OK + f1(); + break; + } while (true); + + do { + defer {} // expected-warning {{redundant use of defer}} + break; + } while (true); + + do { + defer {} // OK + f1(); + continue; + } while (true); + + do { + defer {} // expected-warning {{redundant use of defer}} + continue; + } while (true); + + defer {} // expected-warning {{redundant use of defer}} +} >From 43552bba54d55954537750ee28d0c88aaf7c5d8a Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 12:49:22 +0000 Subject: [PATCH 02/15] Remove accidental change to clang/test/Parser/defer-ts.c --- clang/test/Parser/defer-ts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Parser/defer-ts.c b/clang/test/Parser/defer-ts.c index 1fe7eb2ec57163..118fe9ee3cc8f5 100644 --- a/clang/test/Parser/defer-ts.c +++ b/clang/test/Parser/defer-ts.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c11 -fsyntax-only -fdefer-ts -Wno-redundant-defer -verify %s -// RUN: %clang_cc1 -std=c23 -fsyntax-only -fdefer-ts -Wno-redundant-defer -verify %s +// RUN: %clang_cc1 -std=c11 -fsyntax-only -fdefer-ts -verify %s +// RUN: %clang_cc1 -std=c23 -fsyntax-only -fdefer-ts -verify %s #define defer _Defer >From 995108a364b039bef658384a02cfe380e0bdf4a2 Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 14:52:28 +0000 Subject: [PATCH 03/15] Remove DefaultIgnore on -Wredundant-defer --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/test/Sema/defer-ts-seh.c | 2 +- clang/test/Sema/defer-ts-sjlj.c | 2 +- clang/test/Sema/defer-ts.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 17a15406d003aa..ee93b6c4c33c17 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11344,7 +11344,7 @@ def note_empty_body_on_separate_line : Note< def warn_redundant_defer: Warning< "redundant use of defer; the deferred statement is executed immediately">, - InGroup<RedundantDefer>, DefaultIgnore; + InGroup<RedundantDefer>; def err_va_start_captured_stmt : Error< "'va_start' cannot be used in a captured statement">; diff --git a/clang/test/Sema/defer-ts-seh.c b/clang/test/Sema/defer-ts-seh.c index 4b773ed3f09a0c..de515f38aae876 100644 --- a/clang/test/Sema/defer-ts-seh.c +++ b/clang/test/Sema/defer-ts-seh.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c23 -fdefer-ts -fms-compatibility -triple x86_64-windows-msvc -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c23 -fdefer-ts -Wno-redundant-defer -fms-compatibility -triple x86_64-windows-msvc -fsyntax-only -verify %s void f() { __try { diff --git a/clang/test/Sema/defer-ts-sjlj.c b/clang/test/Sema/defer-ts-sjlj.c index 49230fa721e0f7..dc23f1f6969d41 100644 --- a/clang/test/Sema/defer-ts-sjlj.c +++ b/clang/test/Sema/defer-ts-sjlj.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-windows-msvc -std=gnu23 -fdefer-ts -fsyntax-only -fblocks -verify %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -std=gnu23 -fdefer-ts -Wno-redundant-defer -fsyntax-only -fblocks -verify %s typedef void** jmp_buf; typedef void** sigjmp_buf; diff --git a/clang/test/Sema/defer-ts.c b/clang/test/Sema/defer-ts.c index 95c68fa213eaae..d1fba4128b088c 100644 --- a/clang/test/Sema/defer-ts.c +++ b/clang/test/Sema/defer-ts.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c23 -fdefer-ts -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c23 -fdefer-ts -Wno-redundant-defer -fsyntax-only -verify %s #define defer _Defer >From b8bd97ebc20fe865d3a91bc12185843964b56640 Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 15:01:29 +0000 Subject: [PATCH 04/15] Simplify check for _Defer before break/continue statements --- clang/lib/Sema/SemaStmt.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 8454f4f2bd8421..00eccea0f5a0e2 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -471,14 +471,10 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, } // Find defer statements that immediately precede a break/continue statement. - std::optional<SourceLocation> DeferLoc = std::nullopt; - for (unsigned i = 0; i != NumElts; ++i) { - if (DeferLoc && isa<BreakStmt, ContinueStmt>(Elts[i])) - Diag(DeferLoc.value(), diag::warn_redundant_defer) + for (unsigned i = 0; i != NumElts - 1; ++i) { + if (isa<DeferStmt>(Elts[i]) && isa<BreakStmt, ContinueStmt>(Elts[i+1])) + Diag(Elts[i]->getBeginLoc(), diag::warn_redundant_defer) << Elts[i]->getSourceRange(); - DeferLoc = isa<DeferStmt>(Elts[i]) - ? std::optional<SourceLocation>(Elts[i]->getBeginLoc()) - : std::nullopt; } // Check for defer as last statement. >From bca3b93e62a75a5969b576ce8c7b8fa5bd2c8dff Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 15:14:50 +0000 Subject: [PATCH 05/15] Add redundant _Defer check for void return statements --- clang/lib/Sema/SemaStmt.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 00eccea0f5a0e2..204d8a3270b58a 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -470,11 +470,19 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]); } - // Find defer statements that immediately precede a break/continue statement. - for (unsigned i = 0; i != NumElts - 1; ++i) { - if (isa<DeferStmt>(Elts[i]) && isa<BreakStmt, ContinueStmt>(Elts[i+1])) - Diag(Elts[i]->getBeginLoc(), diag::warn_redundant_defer) - << Elts[i]->getSourceRange(); + // Find defer statements that immediately precede a `break`/`continue` + // or a plain `return` statement. + if (NumElts > 1) { + for (unsigned i = 0; i != NumElts - 1; ++i) { + if (!isa<DeferStmt>(Elts[i])) + continue; + + if (isa<BreakStmt, ContinueStmt>(Elts[i + 1]) || + (isa<ReturnStmt>(Elts[i + 1]) && + !cast<ReturnStmt>(Elts[i + 1])->getRetValue())) + Diag(Elts[i]->getBeginLoc(), diag::warn_redundant_defer) + << Elts[i]->getSourceRange(); + } } // Check for defer as last statement. >From 2058a8ed833e5dfc61a34dbe231b5d9dd12c16dd Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 15:44:58 +0000 Subject: [PATCH 06/15] Add -Wredundant-defer tests for break/continue with labels/attributes --- clang/test/Sema/warn-redundant-defer.c | 64 ++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/clang/test/Sema/warn-redundant-defer.c b/clang/test/Sema/warn-redundant-defer.c index 2d9b92bbe9b63b..6e158d2c425667 100644 --- a/clang/test/Sema/warn-redundant-defer.c +++ b/clang/test/Sema/warn-redundant-defer.c @@ -71,6 +71,38 @@ void f2() { break; } + for (;;) { + defer {} // OK + f1(); + l1: break; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + l2: break; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + l3: l4: break; + } + + for (;;) { + defer {} // OK + f1(); + [[clang::likely]] break; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + [[clang::likely]] break; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + [[clang::likely]] [[clang::suppress]] break; + } + for (;;) { defer {} // OK f1(); @@ -82,6 +114,38 @@ void f2() { continue; } + for (;;) { + defer {} // OK + f1(); + l5: continue; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + l6: continue; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + l7: l8: continue; + } + + for (;;) { + defer {} // OK + f1(); + [[clang::likely]] continue; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + [[clang::likely]] continue; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + [[clang::likely]] [[clang::suppress]] continue; + } + while (true) { defer {} // OK f1(); >From 17819b914de3d1a8ffa7a923d5ef27989e305ada Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 15:48:49 +0000 Subject: [PATCH 07/15] Add -Wredundant-defer tests for _Defer before return --- clang/test/Sema/warn-redundant-defer.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/clang/test/Sema/warn-redundant-defer.c b/clang/test/Sema/warn-redundant-defer.c index 6e158d2c425667..61a5a75f2ee5bc 100644 --- a/clang/test/Sema/warn-redundant-defer.c +++ b/clang/test/Sema/warn-redundant-defer.c @@ -213,3 +213,19 @@ void f2() { defer {} // expected-warning {{redundant use of defer}} } + +int f3() { + defer {} // OK + return 0; +} + +void f4() { + defer {} // OK + f1(); + return; +} + +void f5() { + defer {} // expected-warning {{redundant use of defer}} + return; +} >From 699f9d5af02a4db715bb5f2316f4f0497bf6004d Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 16:18:29 +0000 Subject: [PATCH 08/15] Inline the DiagGroup of warn_redundant_defer --- clang/include/clang/Basic/DiagnosticGroups.td | 2 -- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 4b35e4247e2c4c..1da7698944b24b 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -345,8 +345,6 @@ def EmptyBody : DiagGroup<"empty-body">; def Exceptions : DiagGroup<"exceptions">; def DeclarationAfterStatement : DiagGroup<"declaration-after-statement">; -def RedundantDefer : DiagGroup<"redundant-defer">; - def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">; def ExtraTokens : DiagGroup<"extra-tokens">; def CXX98CompatExtraSemi : DiagGroup<"c++98-compat-extra-semi">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ee93b6c4c33c17..72197af301c54a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11344,7 +11344,7 @@ def note_empty_body_on_separate_line : Note< def warn_redundant_defer: Warning< "redundant use of defer; the deferred statement is executed immediately">, - InGroup<RedundantDefer>; + InGroup<DiagGroup<"redundant-defer">>; def err_va_start_captured_stmt : Error< "'va_start' cannot be used in a captured statement">; >From 98013854a670123adaf4bb85ffa80c10f584bd0c Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 16:27:53 +0000 Subject: [PATCH 09/15] Update ReleaseNotes.md entry on -Wredundant-defer features Co-authored-by: Ambrose Leeb <[email protected]> --- clang/docs/ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index a0126b0785d59d..3e9a67201c60ef 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -521,7 +521,7 @@ features cannot lower the translation-unit ABI level; - Added `-Wredundant-defer` to diagnose redundant uses of the `_Defer` keyword, such as when deferring the last statement of a block; when used as the body of a conditional; or when it immediately precedes - a `break`/`continue` statement. + a `break`/`continue` statement or a `return` with no argument. ### Improvements to Clang's time-trace >From 9f5ff658fca2f0d4c7795de9a2f99acdb92a1116 Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Wed, 23 Sep 2026 16:33:35 +0000 Subject: [PATCH 10/15] Change wording in -Wredundant-defer from "defer" to "_Defer" Co-authored-by: Ambrose Leeb <[email protected]> --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 72197af301c54a..cbf7d95c1cc7ff 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11343,7 +11343,7 @@ def note_empty_body_on_separate_line : Note< "put the semicolon on a separate line to silence this warning">; def warn_redundant_defer: Warning< - "redundant use of defer; the deferred statement is executed immediately">, + "redundant use of '_Defer'; the deferred statement is executed immediately">, InGroup<DiagGroup<"redundant-defer">>; def err_va_start_captured_stmt : Error< >From 7e12e83b3a3a97978c14f53696944e930bce66d4 Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Fri, 25 Sep 2026 13:23:55 +0000 Subject: [PATCH 11/15] Ignore unexpected -Wredundant-defer warnings in defer-ts Parser test --- clang/test/Parser/defer-ts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Parser/defer-ts.c b/clang/test/Parser/defer-ts.c index 118fe9ee3cc8f5..1fe7eb2ec57163 100644 --- a/clang/test/Parser/defer-ts.c +++ b/clang/test/Parser/defer-ts.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c11 -fsyntax-only -fdefer-ts -verify %s -// RUN: %clang_cc1 -std=c23 -fsyntax-only -fdefer-ts -verify %s +// RUN: %clang_cc1 -std=c11 -fsyntax-only -fdefer-ts -Wno-redundant-defer -verify %s +// RUN: %clang_cc1 -std=c23 -fsyntax-only -fdefer-ts -Wno-redundant-defer -verify %s #define defer _Defer >From 325c0193b6df1a72805c681662065c8e8e8bed11 Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Fri, 25 Sep 2026 13:45:41 +0000 Subject: [PATCH 12/15] Add stronger testcases with labels/attributes for redundant-defer --- clang/test/Sema/warn-redundant-defer.c | 80 ++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/clang/test/Sema/warn-redundant-defer.c b/clang/test/Sema/warn-redundant-defer.c index 61a5a75f2ee5bc..f2b9f4272fd48f 100644 --- a/clang/test/Sema/warn-redundant-defer.c +++ b/clang/test/Sema/warn-redundant-defer.c @@ -13,6 +13,32 @@ void f2() { defer defer defer {} // expected-warning 2 {{redundant use of defer}} + l1: defer defer {} // expected-warning {{redundant use of defer}} + + l2: defer defer defer {} // expected-warning 2 {{redundant use of defer}} + + defer [[clang::likely]] defer {} // expected-warning {{redundant use of defer}} + + defer + [[clang::likely]] [[clang::suppress]] + defer {}; // expected-warning {{redundant use of defer}} + + [[clang::likely]] defer defer {} // expected-warning {{redundant use of defer}} + + l3: + [[clang::likely]] defer + defer {} // expected-warning {{redundant use of defer}} + + defer __attribute__((suppress)) + defer {} // expected-warning {{redundant use of defer}} + + __attribute__((suppress)) defer + defer {} // expected-warning {{redundant use of defer}} + + l4: + __attribute__((unknown)) defer // expected-warning {{unknown attribute}} + defer {} // expected-warning {{redundant use of defer}} + { defer {} // OK f1(); @@ -36,6 +62,13 @@ void f2() { } } + { + [[clang::likely]] defer { // expected-warning {{redundant use of defer}} + [[clang::likely]] + defer defer {} // expected-warning 2 {{redundant use of defer}} + } + } + if (true) { defer {} // OK f1(); @@ -74,17 +107,17 @@ void f2() { for (;;) { defer {} // OK f1(); - l1: break; + l5: break; } for (;;) { defer {} // expected-warning {{redundant use of defer}} - l2: break; + l6: break; } for (;;) { defer {} // expected-warning {{redundant use of defer}} - l3: l4: break; + l7: l8: break; } for (;;) { @@ -103,6 +136,16 @@ void f2() { [[clang::likely]] [[clang::suppress]] break; } + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + __attribute__((suppress)) continue; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + l9: [[clang::likely]] break; + } + for (;;) { defer {} // OK f1(); @@ -117,17 +160,17 @@ void f2() { for (;;) { defer {} // OK f1(); - l5: continue; + l10: continue; } for (;;) { defer {} // expected-warning {{redundant use of defer}} - l6: continue; + l11: continue; } for (;;) { defer {} // expected-warning {{redundant use of defer}} - l7: l8: continue; + l12: l13: continue; } for (;;) { @@ -146,6 +189,16 @@ void f2() { [[clang::likely]] [[clang::suppress]] continue; } + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + __attribute__((suppress)) continue; + } + + for (;;) { + defer {} // expected-warning {{redundant use of defer}} + l14: [[clang::likely]] continue; + } + while (true) { defer {} // OK f1(); @@ -229,3 +282,18 @@ void f5() { defer {} // expected-warning {{redundant use of defer}} return; } + +void f6() { + defer {} // expected-warning {{redundant use of defer}} + l15: return; +} + +void f7() { + defer {} // expected-warning {{redundant use of defer}} + [[clang::likely]] return; +} + +void f8() { + defer {} // expected-warning {{redundant use of defer}} + l16: l17: [[clang::likely]] [[clang::suppress]] return; +} >From d0a7f75e71afd8462ef7a25535650a469ade53cf Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Fri, 25 Sep 2026 13:47:16 +0000 Subject: [PATCH 13/15] Handle AttributedStmt and LabelStmt for redundant-defer checks --- clang/lib/Sema/SemaStmt.cpp | 63 ++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 204d8a3270b58a..08bdb2d3908f41 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -430,6 +430,27 @@ void Sema::ActOnFinishOfCompoundStmt() { PopCompoundScope(); } +// Returns the given statement as if its labels and attributes were +// stripped, if any. +static Stmt *GetInnermostStatement(Stmt *Outer) { + if (isa<LabelStmt>(Outer)) + Outer = cast<LabelStmt>(Outer)->getInnermostLabeledStmt(); + + if (isa<AttributedStmt>(Outer)) + Outer = cast<AttributedStmt>(Outer)->getSubStmt(); + + return Outer; +} + +// Diagnose if the given statement is a redundant _Defer statement. +static void CheckRedundantDeferStmt(Sema &S, Stmt *Body) { + Stmt *Inner = GetInnermostStatement(Body); + + if (isa<DeferStmt>(Inner)) + S.Diag(Inner->getBeginLoc(), diag::warn_redundant_defer) + << Inner->getSourceRange(); +} + sema::CompoundScopeInfo &Sema::getCurCompoundScope() const { return getCurFunction()->CompoundScopes.back(); } @@ -474,22 +495,16 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, // or a plain `return` statement. if (NumElts > 1) { for (unsigned i = 0; i != NumElts - 1; ++i) { - if (!isa<DeferStmt>(Elts[i])) - continue; - - if (isa<BreakStmt, ContinueStmt>(Elts[i + 1]) || - (isa<ReturnStmt>(Elts[i + 1]) && - !cast<ReturnStmt>(Elts[i + 1])->getRetValue())) - Diag(Elts[i]->getBeginLoc(), diag::warn_redundant_defer) - << Elts[i]->getSourceRange(); + Stmt *Inner = GetInnermostStatement(Elts[i + 1]); + if (isa<BreakStmt, ContinueStmt>(Inner) || + (isa<ReturnStmt>(Inner) && !cast<ReturnStmt>(Inner)->getRetValue())) + CheckRedundantDeferStmt(*this, Elts[i]); } } // Check for defer as last statement. - Stmt *Back = NumElts > 0 ? Elts[NumElts - 1] : nullptr; - if (Back && isa<DeferStmt>(Back)) - Diag(Back->getBeginLoc(), diag::warn_redundant_defer) - << Back->getSourceRange(); + if (NumElts > 0) + CheckRedundantDeferStmt(*this, Elts[NumElts - 1]); // Calculate difference between FP options in this compound statement and in // the enclosing one. If this is a function body, take the difference against @@ -1018,13 +1033,9 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc, if (!ConstevalOrNegatedConsteval && !elseStmt) DiagnoseEmptyStmtBody(RParenLoc, thenStmt, diag::warn_empty_if_body); - if (isa<DeferStmt>(thenStmt)) - Diag(thenStmt->getBeginLoc(), diag::warn_redundant_defer) - << thenStmt->getSourceRange(); - - if (elseStmt && isa<DeferStmt>(elseStmt)) - Diag(elseStmt->getBeginLoc(), diag::warn_redundant_defer) - << elseStmt->getSourceRange(); + CheckRedundantDeferStmt(*this, thenStmt); + if (elseStmt) + CheckRedundantDeferStmt(*this, elseStmt); if (ConstevalOrNegatedConsteval || StatementKind == IfStatementKind::Constexpr) { @@ -1866,9 +1877,8 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); - else if (isa<DeferStmt>(Body)) - Diag(Body->getBeginLoc(), diag::warn_redundant_defer) - << Body->getSourceRange(); + else + CheckRedundantDeferStmt(*this, Body); return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body, WhileLoc, LParenLoc, RParenLoc); @@ -2360,9 +2370,8 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Expr *Third = third.release().getAs<Expr>(); if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); - else if (isa<DeferStmt>(Body)) - Diag(Body->getBeginLoc(), diag::warn_redundant_defer) - << Body->getSourceRange(); + else + CheckRedundantDeferStmt(*this, Body); return new (Context) ForStmt(Context, First, Second.get().second, Second.get().first, Third, @@ -4075,9 +4084,7 @@ StmtResult Sema::ActOnEndOfDeferStmt(Stmt *Body, Scope *CurScope) { DiagnoseEmptyStmtBody(DeferLoc, Body, diag::warn_empty_defer_body); // Check for superfluous nested defer. - if (isa<DeferStmt>(Body)) - Diag(Body->getBeginLoc(), diag::warn_redundant_defer) - << Body->getSourceRange(); + CheckRedundantDeferStmt(*this, Body); setFunctionHasBranchProtectedScope(); return DeferStmt::Create(Context, DeferLoc, Body); >From 67452b6910bbabe743dd309254382ced082ddb4d Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Fri, 25 Sep 2026 16:07:35 +0000 Subject: [PATCH 14/15] Add nested label + nested defer test case --- clang/test/Sema/warn-redundant-defer.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/clang/test/Sema/warn-redundant-defer.c b/clang/test/Sema/warn-redundant-defer.c index f2b9f4272fd48f..c4f234b8512dc3 100644 --- a/clang/test/Sema/warn-redundant-defer.c +++ b/clang/test/Sema/warn-redundant-defer.c @@ -17,6 +17,8 @@ void f2() { l2: defer defer defer {} // expected-warning 2 {{redundant use of defer}} + l3: l4: defer defer {} // expected-warning {{redundant use of defer}} + defer [[clang::likely]] defer {} // expected-warning {{redundant use of defer}} defer @@ -25,7 +27,7 @@ void f2() { [[clang::likely]] defer defer {} // expected-warning {{redundant use of defer}} - l3: + l5: [[clang::likely]] defer defer {} // expected-warning {{redundant use of defer}} @@ -35,7 +37,7 @@ void f2() { __attribute__((suppress)) defer defer {} // expected-warning {{redundant use of defer}} - l4: + l6: __attribute__((unknown)) defer // expected-warning {{unknown attribute}} defer {} // expected-warning {{redundant use of defer}} @@ -107,17 +109,17 @@ void f2() { for (;;) { defer {} // OK f1(); - l5: break; + l7: break; } for (;;) { defer {} // expected-warning {{redundant use of defer}} - l6: break; + l8: break; } for (;;) { defer {} // expected-warning {{redundant use of defer}} - l7: l8: break; + l9: l10: break; } for (;;) { @@ -143,7 +145,7 @@ void f2() { for (;;) { defer {} // expected-warning {{redundant use of defer}} - l9: [[clang::likely]] break; + l11: [[clang::likely]] break; } for (;;) { @@ -160,17 +162,17 @@ void f2() { for (;;) { defer {} // OK f1(); - l10: continue; + l12: continue; } for (;;) { defer {} // expected-warning {{redundant use of defer}} - l11: continue; + l13: continue; } for (;;) { defer {} // expected-warning {{redundant use of defer}} - l12: l13: continue; + l14: l15: continue; } for (;;) { @@ -196,7 +198,7 @@ void f2() { for (;;) { defer {} // expected-warning {{redundant use of defer}} - l14: [[clang::likely]] continue; + l16: [[clang::likely]] continue; } while (true) { @@ -285,7 +287,7 @@ void f5() { void f6() { defer {} // expected-warning {{redundant use of defer}} - l15: return; + l17: return; } void f7() { @@ -295,5 +297,5 @@ void f7() { void f8() { defer {} // expected-warning {{redundant use of defer}} - l16: l17: [[clang::likely]] [[clang::suppress]] return; + l18: l19: [[clang::likely]] [[clang::suppress]] return; } >From 9bd6e9b7ab892a377e05abbdc231cdf78a91978d Mon Sep 17 00:00:00 2001 From: Expertcoderz <[email protected]> Date: Tue, 29 Sep 2026 02:53:19 +0000 Subject: [PATCH 15/15] Support "defer" macro spelling as alternative to "_Defer" --- .../clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Sema/SemaStmt.cpp | 12 +- clang/test/Sema/warn-redundant-defer.c | 118 +++++++++--------- 3 files changed, 71 insertions(+), 61 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 68ac46a7b495ea..3ab9207798b0a2 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11358,7 +11358,7 @@ def note_empty_body_on_separate_line : Note< "put the semicolon on a separate line to silence this warning">; def warn_redundant_defer: Warning< - "redundant use of '_Defer'; the deferred statement is executed immediately">, + "redundant use of '%0'; the deferred statement is executed immediately">, InGroup<DiagGroup<"redundant-defer">>; def err_va_start_captured_stmt : Error< diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 08bdb2d3908f41..86469c4bad95bc 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -446,9 +446,15 @@ static Stmt *GetInnermostStatement(Stmt *Outer) { static void CheckRedundantDeferStmt(Sema &S, Stmt *Body) { Stmt *Inner = GetInnermostStatement(Body); - if (isa<DeferStmt>(Inner)) - S.Diag(Inner->getBeginLoc(), diag::warn_redundant_defer) - << Inner->getSourceRange(); + if (isa<DeferStmt>(Inner)) { + SourceLocation InnerLoc = Inner->getBeginLoc(); + StringRef DeferSpelling = + S.PP.getLastMacroWithSpelling(InnerLoc, {tok::kw__Defer}); + + S.Diag(InnerLoc, diag::warn_redundant_defer) + << Inner->getSourceRange() + << (DeferSpelling.empty() ? "_Defer" : DeferSpelling); + } } sema::CompoundScopeInfo &Sema::getCurCompoundScope() const { diff --git a/clang/test/Sema/warn-redundant-defer.c b/clang/test/Sema/warn-redundant-defer.c index c4f234b8512dc3..8c91355dcb1119 100644 --- a/clang/test/Sema/warn-redundant-defer.c +++ b/clang/test/Sema/warn-redundant-defer.c @@ -1,54 +1,58 @@ // RUN: %clang_cc1 -std=c23 -fdefer-ts -fsyntax-only -verify %s -Wredundant-defer -#define defer _Defer - void f1() { - defer {} // expected-warning {{redundant use of defer}} + _Defer {} // expected-warning {{redundant use of '_Defer'}} } +#define defer _Defer + void f2() { + defer {} // expected-warning {{redundant use of 'defer'}} +} + +void f3() { defer {} // OK - defer defer {} // expected-warning {{redundant use of defer}} + defer defer {} // expected-warning {{redundant use of 'defer'}} - defer defer defer {} // expected-warning 2 {{redundant use of defer}} + defer defer defer {} // expected-warning 2 {{redundant use of 'defer'}} - l1: defer defer {} // expected-warning {{redundant use of defer}} + l1: defer defer {} // expected-warning {{redundant use of 'defer'}} - l2: defer defer defer {} // expected-warning 2 {{redundant use of defer}} + l2: defer defer defer {} // expected-warning 2 {{redundant use of 'defer'}} - l3: l4: defer defer {} // expected-warning {{redundant use of defer}} + l3: l4: defer defer {} // expected-warning {{redundant use of 'defer'}} - defer [[clang::likely]] defer {} // expected-warning {{redundant use of defer}} + defer [[clang::likely]] defer {} // expected-warning {{redundant use of 'defer'}} defer [[clang::likely]] [[clang::suppress]] - defer {}; // expected-warning {{redundant use of defer}} + defer {}; // expected-warning {{redundant use of 'defer'}} - [[clang::likely]] defer defer {} // expected-warning {{redundant use of defer}} + [[clang::likely]] defer defer {} // expected-warning {{redundant use of 'defer'}} l5: [[clang::likely]] defer - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} defer __attribute__((suppress)) - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} __attribute__((suppress)) defer - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} l6: __attribute__((unknown)) defer // expected-warning {{unknown attribute}} - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} { defer {} // OK f1(); } - { defer {} } // expected-warning {{redundant use of defer}} + { defer {} } // expected-warning {{redundant use of 'defer'}} - { defer defer {} } // expected-warning 2 {{redundant use of defer}} + { defer defer {} } // expected-warning 2 {{redundant use of 'defer'}} { defer { // OK @@ -59,15 +63,15 @@ void f2() { } { - defer { // expected-warning {{redundant use of defer}} - defer defer {} // expected-warning 2 {{redundant use of defer}} + defer { // expected-warning {{redundant use of 'defer'}} + defer defer {} // expected-warning 2 {{redundant use of 'defer'}} } } { - [[clang::likely]] defer { // expected-warning {{redundant use of defer}} + [[clang::likely]] defer { // expected-warning {{redundant use of 'defer'}} [[clang::likely]] - defer defer {} // expected-warning 2 {{redundant use of defer}} + defer defer {} // expected-warning 2 {{redundant use of 'defer'}} } } @@ -77,10 +81,10 @@ void f2() { } if (true) - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} if (true) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} } for (;;) { @@ -89,10 +93,10 @@ void f2() { } for (;;) - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} } for (;;) { @@ -102,7 +106,7 @@ void f2() { } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} break; } @@ -113,12 +117,12 @@ void f2() { } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} l8: break; } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} l9: l10: break; } @@ -129,22 +133,22 @@ void f2() { } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} [[clang::likely]] break; } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} [[clang::likely]] [[clang::suppress]] break; } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} __attribute__((suppress)) continue; } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} l11: [[clang::likely]] break; } @@ -155,7 +159,7 @@ void f2() { } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} continue; } @@ -166,12 +170,12 @@ void f2() { } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} l13: continue; } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} l14: l15: continue; } @@ -182,22 +186,22 @@ void f2() { } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} [[clang::likely]] continue; } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} [[clang::likely]] [[clang::suppress]] continue; } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} __attribute__((suppress)) continue; } for (;;) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} l16: [[clang::likely]] continue; } @@ -207,10 +211,10 @@ void f2() { } while (true) - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} while (true) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} } while (true) { @@ -220,7 +224,7 @@ void f2() { } while (true) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} break; } @@ -231,7 +235,7 @@ void f2() { } while (true) { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} continue; } @@ -241,7 +245,7 @@ void f2() { } while (true); do { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} } while (true); do { @@ -251,7 +255,7 @@ void f2() { } while (true); do { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} break; } while (true); @@ -262,40 +266,40 @@ void f2() { } while (true); do { - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} continue; } while (true); - defer {} // expected-warning {{redundant use of defer}} + defer {} // expected-warning {{redundant use of 'defer'}} } -int f3() { +int f4() { defer {} // OK return 0; } -void f4() { +void f5() { defer {} // OK f1(); return; } -void f5() { - defer {} // expected-warning {{redundant use of defer}} +void f6() { + defer {} // expected-warning {{redundant use of 'defer'}} return; } -void f6() { - defer {} // expected-warning {{redundant use of defer}} +void f7() { + defer {} // expected-warning {{redundant use of 'defer'}} l17: return; } -void f7() { - defer {} // expected-warning {{redundant use of defer}} +void f8() { + defer {} // expected-warning {{redundant use of 'defer'}} [[clang::likely]] return; } -void f8() { - defer {} // expected-warning {{redundant use of defer}} +void f9() { + defer {} // expected-warning {{redundant use of 'defer'}} l18: l19: [[clang::likely]] [[clang::suppress]] return; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
