llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Oliver Hunt (ojhunt)

<details>
<summary>Changes</summary>

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?

---
Full diff: https://github.com/llvm/llvm-project/pull/211745.diff


3 Files Affected:

- (modified) clang/lib/AST/Decl.cpp (+4-1) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+2-1) 
- (added) clang/test/SemaCXX/expansion-statements-local-extern-decls.cpp (+45) 


``````````diff
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}}
+    }
+  }
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/211745
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to