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 <[email protected]> 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; } +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
