[clang] [Clang][Sema] Add -Wredundant-defer to diagnose redundant `_Defer`s (PR #225748)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 28 19:55:13 PDT 2026
https://github.com/Expertcoderz updated https://github.com/llvm/llvm-project/pull/225748
>From 730360dc5a0f855d996f12b7f8ab2f8bdf5ebff1 Mon Sep 17 00:00:00 2001
From: Expertcoderz <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <aeternalmail at gmail.com>
---
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 <expertcoderzx at gmail.com>
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 <aeternalmail at gmail.com>
---
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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 <expertcoderzx at gmail.com>
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;
}
More information about the cfe-commits
mailing list