dblaikie created this revision.
dblaikie added reviewers: clang-vendors, rsmith, probinson, rjmccall.
Herald added a project: All.
dblaikie requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

https://llvm.org/pr58819 - clang is giving an externally visible lambda in a 
static data member internal linkage and the wrong linkage name.

Looks like we should be classifying this case the same as a non-static data 
member, so far as I can tell from the ABI docs and template examples (seems 
like the non-template inline-defined case should be the same).

This is a change in ABI, but not sure it qualifies as an ABI break as far as 
Apple and Sony are concerned - do you folks want this change? (it should fix 
the example in the bug where a static member in such a lambda ends up 
bifurcated, and I don't /think/ it'll break existing code since the symbol was 
previously internal anyway)

Looks like GCC has got this mangling slightly wrong (so we'd still end up with 
GCC+Clang bifurcation of the local static in the lambda, function address 
inequality, etc) in that they miss the variable name in the mangling in the 
non-template case. GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107741


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D138247

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/CodeGenCXX/mangle-lambdas.cpp


Index: clang/test/CodeGenCXX/mangle-lambdas.cpp
===================================================================
--- clang/test/CodeGenCXX/mangle-lambdas.cpp
+++ clang/test/CodeGenCXX/mangle-lambdas.cpp
@@ -290,6 +290,17 @@
 // CHECK-LABEL: define linkonce_odr noundef i32 
@_ZZZ3ft4IiEvvEN2lc2mfEiEd_NKUlvE_clEv
 
 
+extern int ExternalVariable;
+struct StaticInlineMember {
+  static constexpr auto x = [] { return ExternalVariable; };
+};
+
+// CHECK-LABEL: define void @_Z23test_StaticInlineMemberv
+// CHECK: call {{.*}} @_ZNK18StaticInlineMember1xMUlvE_clEv
+void test_StaticInlineMember() {
+  StaticInlineMember::x();
+}
+
 // Check linkage of the various lambdas.
 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZZ11inline_funciENKUlvE_clEv
 // CHECK: ret i32 1
Index: clang/lib/Sema/SemaLambda.cpp
===================================================================
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -296,10 +296,10 @@
         if (LexicalDC->isRecord())
           Kind = DefaultArgument;
     } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {
-      if (Var->getDeclContext()->isRecord())
-        Kind = StaticDataMember;
-      else if (Var->getMostRecentDecl()->isInline())
+      if (Var->getMostRecentDecl()->isInline())
         Kind = InlineVariable;
+      else if (Var->getDeclContext()->isRecord())
+        Kind = StaticDataMember;
       else if (Var->getDescribedVarTemplate())
         Kind = VariableTemplate;
       else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) {


Index: clang/test/CodeGenCXX/mangle-lambdas.cpp
===================================================================
--- clang/test/CodeGenCXX/mangle-lambdas.cpp
+++ clang/test/CodeGenCXX/mangle-lambdas.cpp
@@ -290,6 +290,17 @@
 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZZZ3ft4IiEvvEN2lc2mfEiEd_NKUlvE_clEv
 
 
+extern int ExternalVariable;
+struct StaticInlineMember {
+  static constexpr auto x = [] { return ExternalVariable; };
+};
+
+// CHECK-LABEL: define void @_Z23test_StaticInlineMemberv
+// CHECK: call {{.*}} @_ZNK18StaticInlineMember1xMUlvE_clEv
+void test_StaticInlineMember() {
+  StaticInlineMember::x();
+}
+
 // Check linkage of the various lambdas.
 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZZ11inline_funciENKUlvE_clEv
 // CHECK: ret i32 1
Index: clang/lib/Sema/SemaLambda.cpp
===================================================================
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -296,10 +296,10 @@
         if (LexicalDC->isRecord())
           Kind = DefaultArgument;
     } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {
-      if (Var->getDeclContext()->isRecord())
-        Kind = StaticDataMember;
-      else if (Var->getMostRecentDecl()->isInline())
+      if (Var->getMostRecentDecl()->isInline())
         Kind = InlineVariable;
+      else if (Var->getDeclContext()->isRecord())
+        Kind = StaticDataMember;
       else if (Var->getDescribedVarTemplate())
         Kind = VariableTemplate;
       else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to