[clang] [clang][Parse] Fix __extension__ not silencing diagnostics (PR #221623)
Richard Patel via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 6 19:41:12 PDT 2026
https://github.com/riptl created https://github.com/llvm/llvm-project/pull/221623
In ParseCondition(), the ExtensionRAIIObject went out of scope too early (before parsing the condition wrapped by __extension__), so -pedantic incorrectly raised diagnostics.
>From b08c44b6c522cf5cda09d771cf7eb78fcc194443 Mon Sep 17 00:00:00 2001
From: Richard Patel <ripatel at wii.dev>
Date: Mon, 7 Sep 2026 02:30:12 +0000
Subject: [PATCH] [clang][Parse] Fix __extension__ not silencing diagnostics
In ParseCondition(), the ExtensionRAIIObject went out of scope too
early (before parsing the condition wrapped by __extension__), so
-pedantic incorrectly raised diagnostics.
---
clang/lib/Parse/ParseExprCXX.cpp | 16 ++++++++--------
clang/test/Parser/extension-condition.c | 15 +++++++++++++++
2 files changed, 23 insertions(+), 8 deletions(-)
create mode 100644 clang/test/Parser/extension-condition.c
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index ae741af7249cf..beb5dbd4fc0b3 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1882,15 +1882,15 @@ Sema::ConditionResult Parser::ParseCondition(StmtResult *InitStmt,
return Sema::ConditionError();
}
+ // The first clause of a condition may be a declaration used as an
+ // init-statement (C2y), and that declaration may be prefixed by one or more
+ // __extension__ markers. Consume them up front -- mirroring block-statement
+ // parsing -- so the disambiguation below sees the real start of the
+ // declaration. The markers also silence extension diagnostics for the rest
+ // of the condition, including the diagnostic for the init-statement
+ // extension itself.
+ std::optional<ExtensionRAIIObject> ExtensionGuard;
if (Tok.is(tok::kw___extension__)) {
- // The first clause of a condition may be a declaration used as an
- // init-statement (C2y), and that declaration may be prefixed by one or more
- // __extension__ markers. Consume them up front -- mirroring block-statement
- // parsing -- so the disambiguation below sees the real start of the
- // declaration. The markers also silence extension diagnostics for the rest
- // of the condition, including the diagnostic for the init-statement
- // extension itself.
- std::optional<ExtensionRAIIObject> ExtensionGuard;
ExtensionGuard.emplace(Diags);
while (TryConsumeToken(tok::kw___extension__))
;
diff --git a/clang/test/Parser/extension-condition.c b/clang/test/Parser/extension-condition.c
new file mode 100644
index 0000000000000..c9a329a2e92a6
--- /dev/null
+++ b/clang/test/Parser/extension-condition.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify -std=c17
+// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify -std=c2y
+// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify -x c++ -std=c++17
+
+// expected-no-diagnostics
+
+int f(int);
+
+void cond(int a) {
+ if (__extension__ ({ int r = f(a); r; })) {}
+ while (__extension__ ({ int r = f(a); r; })) { break; }
+ switch (__extension__ ({ int r = f(a); r; })) { default: break; }
+ do {} while (__extension__ ({ int r = f(a); r; }));
+ for (; __extension__ ({ int r = f(a); r; });) { break; }
+}
More information about the cfe-commits
mailing list