https://github.com/ojhunt created https://github.com/llvm/llvm-project/pull/211745
I was looking at https://github.com/llvm/llvm-project/issues/210512 and found that the underlying cause seemed to be a failure to ignore expansion contexts when traversing contexts, and found the same issue hit extern var decls as well. Alas these go through different paths. So caveats: not an area I'm familiar with, so is it right? no idea! it _seems_ reasonable, but this is the result of debugging to find where things went weird in the test case, and then looking at other code added as part of the statement expansion changes. But "looking reasonable" doesn't mean correct. It's generally a correctness progression from the point of code being compiled, but is it the right way? >From 92aeb06977b61c87c9f6f6ddae3030053b47ee70 Mon Sep 17 00:00:00 2001 From: Oliver Hunt <[email protected]> Date: Fri, 24 Jul 2026 01:04:02 -0700 Subject: [PATCH] [clang][sema][wat] peek through expansion statements to try and fix weird decl problems --- clang/lib/AST/Decl.cpp | 5 ++- clang/lib/Sema/SemaDecl.cpp | 3 +- ...xpansion-statements-local-extern-decls.cpp | 45 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/expansion-statements-local-extern-decls.cpp diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 4eaef0d87f3e5..49852c1afa795 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1566,7 +1566,10 @@ LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D, // one such matching entity, the program is ill-formed. Otherwise, // if no matching entity is found, the block scope entity receives // external linkage. - if (D->getDeclContext()->isFunctionOrMethod()) + // **REVIEWER***: peeking through expansion statements lalalala + if (D->getDeclContext() + ->getEnclosingNonExpansionStatementContext() + ->isFunctionOrMethod()) return getLVForLocalDecl(D, computation); // C++ [basic.link]p6: diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 7de5542e72559..93bc2a51ebfaf 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7510,7 +7510,8 @@ static bool hasParsedAttr(Scope *S, const Declarator &PD, } bool Sema::adjustContextForLocalExternDecl(DeclContext *&DC) { - if (!DC->isFunctionOrMethod()) + // **REVIEWER***: Peeking through expansion statements lalalala + if (!DC->getEnclosingNonExpansionStatementContext()->isFunctionOrMethod()) return false; // If this is a local extern function or variable declared within a function diff --git a/clang/test/SemaCXX/expansion-statements-local-extern-decls.cpp b/clang/test/SemaCXX/expansion-statements-local-extern-decls.cpp new file mode 100644 index 0000000000000..8dd703a298bed --- /dev/null +++ b/clang/test/SemaCXX/expansion-statements-local-extern-decls.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -verify + +int wibble(); // #wibble_decl + +void foo1() { + template for (auto x : {1}) { // #foo1_instantiation + void wibble(); + // expected-error@-1 {{functions that differ only in their return type cannot be overloaded}} + // expected-note@#wibble_decl {{previous declaration is here}} + // expected-note@#foo1_instantiation {{in instantiation of expansion statement requested here}} + } +} + +void foo2() { + template for (auto x : {1}) { // #foo2_instantiation + template for (auto x : {1}) { + void wibble(); + // expected-error@-1 {{functions that differ only in their return type cannot be overloaded}} + // expected-note@#wibble_decl {{previous declaration is here}} + // expected-note@#foo2_instantiation {{in instantiation of expansion statement requested here}} + } + } +} + +int woffle; // #woffle_decl + +void foo3() { + template for (auto x : {1}) { // #foo3_instantiation + extern double woffle; + // expected-error@-1 {{redeclaration of 'woffle' with a different type: 'double' vs 'int'}} + // expected-note@#woffle_decl {{previous definition is here}} + // expected-note@#foo3_instantiation {{in instantiation of expansion statement requested here}} + } +} + +void foo4() { + template for (auto x : {1}) { // #foo4_instantiation + template for (auto x : {1}) { + extern double woffle; + // expected-error@-1 {{redeclaration of 'woffle' with a different type: 'double' vs 'int'}} + // expected-note@#woffle_decl {{previous definition is here}} + // expected-note@#foo4_instantiation {{in instantiation of expansion statement requested here}} + } + } +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
