]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Lambda context mangling
authorNathan Sidwell <nathan@acm.org>
Mon, 10 Oct 2022 21:55:04 +0000 (17:55 -0400)
committerNathan Sidwell <nathan@acm.org>
Mon, 10 Oct 2022 22:13:47 +0000 (18:13 -0400)
VAR and FIELD decls can become part of a lambda context, when the
lambda is 'attached' to that entity (It's a C++20 ODR thing that was
discovered with modules, but is actually separate.)  We were not
marking those decls as substitution candidates, leading to demangling
failures and variance from other compilers.

This patch bumps the ABI, and adds the contexts them to the
substitution table.  This is the intent of the ABI.

gcc/
* common.opt (-fabi-version=): Document 18.
* doc/invoke.texi (-fabi-version): Document 18.
gcc/c-family/
* c-opts.cc (c_common_post_options): Bump abi to 18.
gcc/cp/
* mangle.cc (write_prefix): Add VAR_DECL & FIELD_DECL to
substitution table under abi=18.  Note possible mismatch.
gcc/testsuite/
* g++.dg/abi/lambda-ctx1-17.C: New.
* g++.dg/abi/lambda-ctx1-18.C: New.
* g++.dg/abi/lambda-ctx1-18vs17.C: New.
* g++.dg/abi/lambda-ctx1.h: New.
* g++.dg/abi/lambda-vis.C: Adjust expected mangles.
* g++.dg/abi/macro0.C: Adjust.

gcc/c-family/c-opts.cc
gcc/common.opt
gcc/cp/mangle.cc
gcc/doc/invoke.texi
gcc/testsuite/g++.dg/abi/lambda-ctx1-17.C [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/lambda-ctx1-18.C [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/lambda-ctx1-18vs17.C [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/lambda-ctx1.h [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/lambda-vis.C
gcc/testsuite/g++.dg/abi/macro0.C

index babaa2fc157af8c724b2c600f5f81313518a9bcc..55cebf68f9c3f12eaa0592868b1ad068fa5980a0 100644 (file)
@@ -975,7 +975,7 @@ c_common_post_options (const char **pfilename)
 
   /* Change flag_abi_version to be the actual current ABI level, for the
      benefit of c_cpp_builtins, and to make comparison simpler.  */
-  const int latest_abi_version = 17;
+  const int latest_abi_version = 18;
   /* Generate compatibility aliases for ABI v13 (8.2) by default.  */
   const int abi_compat_default = 13;
 
index 3a97e6782ce52c703207c44793a4cadb2a241366..bce3e514f65bbf18c0d6394fca85292478c1f284 100644 (file)
@@ -1004,6 +1004,9 @@ Driver Undocumented
 ;     member initializers in C++14 and up.
 ;     Default in G++ 12.
 ;
+; 18: Corrects errors in mangling of lambdas with additional context.
+;     Default in G++ 13.
+;
 ; Additional positive integers will be assigned as new versions of
 ; the ABI become the default version of the ABI.
 fabi-version=
index f051e76466a31f3ad369f1671a62df5ba7b18b3d..1215463089b5479e85abb3a0151e8c81bea9b9ee 100644 (file)
@@ -1252,7 +1252,14 @@ write_prefix (const tree node)
        {
          /* <data-member-prefix> := <member source-name> M */
          write_char ('M');
-         return;
+
+         /* Before ABI 18, we did not count these as substitution
+            candidates.  This leads to incorrect demanglings (and
+            ABI divergence to other compilers).  */
+         if (abi_warn_or_compat_version_crosses (18))
+           G.need_abi_warning = true;
+         if (!abi_version_at_least (18))
+           return;
        }
     }
 
index 278c55d5a19a17e8a6eff4778ab1445d58ef46fa..271c8bb846852bea6e2289ea871a4c2404b8a2f4 100644 (file)
@@ -2973,6 +2973,9 @@ Version 17, which first appeared in G++ 12, fixes layout of classes
 that inherit from aggregate classes with default member initializers
 in C++14 and up.
 
+Version 18, which first appeard in G++ 13, fixes manglings of lambdas
+that have additional context.
+
 See also @option{-Wabi}.
 
 @item -fabi-compat-version=@var{n}
diff --git a/gcc/testsuite/g++.dg/abi/lambda-ctx1-17.C b/gcc/testsuite/g++.dg/abi/lambda-ctx1-17.C
new file mode 100644 (file)
index 0000000..42f277a
--- /dev/null
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++20 } }
+// { dg-options -fabi-version=17 }
+
+#include "lambda-ctx1.h"
+
+// These demangle incorrectly, due to a missed substitution candidate
+// { dg-final { scan-assembler {_ZNK1C1fMUlT_E_clIMS_iEEDaS0_:} } }
+// { dg-final { scan-assembler {_ZNK2L2MUlT_T0_E_clIifEEvS_S0_:} } }
+// { dg-final { scan-assembler {_ZNK1B2L3MUlT_T0_E_clIjdEEvS0_S1_:} } }
+// { dg-final { scan-assembler {_Z3fooIN1qMUlvE_EN1qMUlvE0_EEiOT_OT0_:} } }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-ctx1-18.C b/gcc/testsuite/g++.dg/abi/lambda-ctx1-18.C
new file mode 100644 (file)
index 0000000..c1c9e27
--- /dev/null
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++20 } }
+// { dg-options -fabi-version=18 }
+
+#include "lambda-ctx1.h"
+
+// These correctly include the lambda's extra context as a
+// substitution candidate, and thus demangle as expected
+// { dg-final { scan-assembler {_ZNK1C1fMUlT_E_clIMS_iEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZNK2L2MUlT_T0_E_clIifEEvS0_S1_:} } }
+// { dg-final { scan-assembler {_ZNK1B2L3MUlT_T0_E_clIjdEEvS1_S2_:} } }
+// { dg-final { scan-assembler {_Z3fooIN1qMUlvE_ENS0_UlvE0_EEiOT_OT0_:} } }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-ctx1-18vs17.C b/gcc/testsuite/g++.dg/abi/lambda-ctx1-18vs17.C
new file mode 100644 (file)
index 0000000..f5ec905
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++20 } }
+// { dg-options {-fabi-version=18 -Wabi=17} }
+
+#include "lambda-ctx1.h"
+
+// { dg-regexp {[^\n]*lambda-ctx1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZNK1B2L3MUlT_T0_E_clIjdEEvS0_S1_'\) and '-fabi-version=18' \('_ZNK1B2L3MUlT_T0_E_clIjdEEvS1_S2_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-ctx1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZNK2L2MUlT_T0_E_clIifEEvS_S0_'\) and '-fabi-version=18' \('_ZNK2L2MUlT_T0_E_clIifEEvS0_S1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-ctx1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZNK1C1fMUlT_E_clIMS_iEEDaS0_'\) and '-fabi-version=18' \('_ZNK1C1fMUlT_E_clIMS_iEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-ctx1.h:[:0-9]* warning: the mangled name [^\n]* \('_Z3fooIN1qMUlvE_EN1qMUlvE0_EEiOT_OT0_'\) and '-fabi-version=18' \('_Z3fooIN1qMUlvE_ENS0_UlvE0_EEiOT_OT0_'\) [^\n]*\n} }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-ctx1.h b/gcc/testsuite/g++.dg/abi/lambda-ctx1.h
new file mode 100644 (file)
index 0000000..9afb66a
--- /dev/null
@@ -0,0 +1,20 @@
+inline auto L2 = [] <typename T, typename U> (T, U) -> void {};
+namespace B
+{
+  inline auto L3 = [] <typename T, typename U> (T, U) -> void {};
+}
+
+struct C
+{
+  int f = [] (auto){ return 1;}(&C::f);
+  C ();
+};
+
+C::C ()
+{
+  L2 (1, 1.2f);
+  B::L3 (1u, 1.2);
+}
+
+template <typename A, typename B> int foo (A&&, B&&) {return 0;}
+inline int q = foo ([](){}, [](){});
index c1033f501a3cccf360c5079d832570f1a93c6eaf..81cffcbe5a6d7eaeed329ddca2bf2ffb9a052e58 100644 (file)
@@ -13,9 +13,11 @@ int gvar = gfoo (capture ([]{}));
 
 inline int ivar = ifoo (capture ([]{}));
 
-// { dg-final { scan-assembler {_?_Z7captureINL4svarMUlvE_EE7WrapperIT_EOS2_:} } }
-// { dg-final { scan-assembler {_?_Z7captureIN4gvarMUlvE_EE7WrapperIT_EOS2_:} } }
-// { dg-final { scan-assembler {_?_Z7captureIN4ivarMUlvE_EE7WrapperIT_EOS2_:} } }
+// These manglings change between ABIs 17 and 18 (the final
+// substitution number).
+// { dg-final { scan-assembler {_?_Z7captureINL4svarMUlvE_EE7WrapperIT_EOS3_:} } }
+// { dg-final { scan-assembler {_?_Z7captureIN4gvarMUlvE_EE7WrapperIT_EOS3_:} } }
+// { dg-final { scan-assembler {_?_Z7captureIN4ivarMUlvE_EE7WrapperIT_EOS3_:} } }
 
 // Calls to the foos are emitted.
 // { dg-final { scan-assembler {call[ \t]*_?_Z4sfooI7WrapperINL4svarMUlvE_EEEiT_} { target { i?86-*-* x86_64-*-* } } } }
index 2d07fcdc631cd6b124c14385a39162faf7e4cd64..4a0e9d06ca0f846c3386c145dcadf0b04fee30f8 100644 (file)
@@ -1,6 +1,6 @@
 // This testcase will need to be kept in sync with c_common_post_options.
 // { dg-options "-fabi-version=0" }
 
-#if __GXX_ABI_VERSION != 1017
+#if __GXX_ABI_VERSION != 1018
 #error "Incorrect value of __GXX_ABI_VERSION"
 #endif