This has been broken since GCC started to put the comdat functions' 
gcc_except_table into their
own section; r0-118218-g3e6011cfebedfb. What would happen is after a non-comdat 
function is processed,
the cached value would always be used even for comdat function. Instead we 
should create a new
section for comdat functions.

OK for GCC 16? Bootstrapped and tested on x86_64-linux-gnu.

        PR middle-end/119507

gcc/ChangeLog:

        * except.cc (switch_to_exception_section): Don't use the cached section 
if
        the current function is in comdat.

gcc/testsuite/ChangeLog:

        * g++.dg/eh/pr119507.C: New test.

Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
---
 gcc/except.cc                      |  9 ++++++++-
 gcc/testsuite/g++.dg/eh/pr119507.C | 17 +++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/eh/pr119507.C

diff --git a/gcc/except.cc b/gcc/except.cc
index d5eb9274a62..8bd16c1dd69 100644
--- a/gcc/except.cc
+++ b/gcc/except.cc
@@ -2935,7 +2935,14 @@ switch_to_exception_section (const char * ARG_UNUSED 
(fnname))
 {
   section *s;
 
-  if (exception_section)
+  if (exception_section
+  /* Don't use the cached section for comdat if it will be different. */
+#ifdef HAVE_LD_EH_GC_SECTIONS
+      && !(targetm_common.have_named_sections
+          && DECL_COMDAT_GROUP (current_function_decl)
+          && HAVE_COMDAT_GROUP)
+#endif
+     )
     s = exception_section;
   else
     {
diff --git a/gcc/testsuite/g++.dg/eh/pr119507.C 
b/gcc/testsuite/g++.dg/eh/pr119507.C
new file mode 100644
index 00000000000..50afa75a43f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/pr119507.C
@@ -0,0 +1,17 @@
+// { dg-do compile { target comdat_group } }
+// Force off function sections
+// Force on exceptions
+// { dg-options "-fno-function-sections -fexceptions" }
+// PR middle-end/119507
+
+
+inline int comdat() { try { throw 1; } catch (int) { return 1; } return 0; }
+int another_func_with_exception() { try { throw 1; } catch (int) { return 1; } 
return 0; }
+inline int comdat1() { try { throw 1; } catch (int) { return 1; } return 0; }
+int foo() { return comdat() + comdat1(); }
+
+// Make sure the gcc puts the exception table for both comdat and comdat1 in 
their own section
+// { dg-final { scan-assembler-times ".section\[\t 
\]\[^\n\]*.gcc_except_table._Z6comdatv" 1 } }
+// { dg-final { scan-assembler-times ".section\[\t 
\]\[^\n\]*.gcc_except_table._Z7comdat1v" 1 } }
+// There should be 3 exception tables, 
+// { dg-final { scan-assembler-times ".section\[\t 
\]\[^\n\]*.gcc_except_table" 3 } }
-- 
2.43.0

Reply via email to