]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/14607 (Duplicate symbol "vtable for node" in files div.o and env.o)
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>
Tue, 28 Dec 2004 04:51:33 +0000 (04:51 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Tue, 28 Dec 2004 04:51:33 +0000 (04:51 +0000)
PR c++/14607.
Backported from main.
* configure.ac (HAVE_GAS_NSUBSPA_COMDAT): Add check for .NSUBSPA
COMDAT support.
* configure. config.in: Rebuilt.
* config/pa/pa-protos.h (som_text_section_asm_op,
som_readonly_data_section, som_one_only_readonly_data_section,
som_one_only_data_section, forget_section): Declare.
* pa.c (override_options): Set init_machine_status to
pa_init_machine_status.
(pa_init_machine_status): New function.
(pa_output_function_epilogue): Call forget_section if TARGET_SOM and
TARGET_GAS.
(pa_asm_output_mi_thunk): Likewise.
(som_text_section_asm_op): New function.
(pa_select_section): Call som_one_only_readonly_data_section and
som_one_only_data_section when appropriate.
* pa.h (struct machine_function): Define.
(EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS,
SOM_READONLY_DATA_SECTION_FUNCTION,
SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION
SOM_ONE_ONLY_DATA_SECTION_FUNCTION, FORGET_SECTION_FUNCTION): New
macros.
* som.h (ASM_OUTPUT_FUNCTION_PREFIX): Delete.
(TEXT_SECTION_ASM_OP): Call som_text_section_asm_op.
(READONLY_DATA_ASM_OP, EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Delete.
(READONLY_DATA_SECTION): Call som_readonly_data_section when not PIC.
(SUPPORTS_SOM_COMDAT): New define.
(SUPPORTS_ONE_ONLY): True if SUPPORTS_WEAK or SUPPORTS_SOM_COMDAT.
(MAKE_DECL_ONE_ONLY): Rework common support.

From-SVN: r92660

gcc/ChangeLog
gcc/config.in
gcc/config/pa/pa-protos.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/som.h
gcc/configure
gcc/configure.ac

index d4dff7786b4542cbde24d47dea41fd975a0d650e..888a66781c1046668e93fc18303d61066eed6b0d 100644 (file)
@@ -1,3 +1,36 @@
+2004-12-27  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       PR c++/14607.
+       Backported from main.
+       * configure.ac (HAVE_GAS_NSUBSPA_COMDAT): Add check for .NSUBSPA
+       COMDAT support.
+       * configure. config.in: Rebuilt.
+       * config/pa/pa-protos.h (som_text_section_asm_op,
+       som_readonly_data_section, som_one_only_readonly_data_section,
+       som_one_only_data_section, forget_section): Declare.
+       * pa.c (override_options): Set init_machine_status to
+       pa_init_machine_status.
+       (pa_init_machine_status): New function.
+       (pa_output_function_epilogue): Call forget_section if TARGET_SOM and
+       TARGET_GAS.
+       (pa_asm_output_mi_thunk): Likewise.
+       (som_text_section_asm_op): New function.
+       (pa_select_section): Call som_one_only_readonly_data_section and
+       som_one_only_data_section when appropriate.
+       * pa.h (struct machine_function): Define.
+       (EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS,
+       SOM_READONLY_DATA_SECTION_FUNCTION,
+       SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION
+       SOM_ONE_ONLY_DATA_SECTION_FUNCTION, FORGET_SECTION_FUNCTION): New
+       macros.
+       * som.h (ASM_OUTPUT_FUNCTION_PREFIX): Delete.
+       (TEXT_SECTION_ASM_OP): Call som_text_section_asm_op.
+       (READONLY_DATA_ASM_OP, EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Delete.
+       (READONLY_DATA_SECTION): Call som_readonly_data_section when not PIC.
+       (SUPPORTS_SOM_COMDAT): New define.
+       (SUPPORTS_ONE_ONLY): True if SUPPORTS_WEAK or SUPPORTS_SOM_COMDAT.
+       (MAKE_DECL_ONE_ONLY): Rework common support.
+
 2004-12-26  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        PR target/17643
index 4d47fbea162ad64411509bded63c054c56b3c7a4..547dda02945423d857ce410945b9390a2845d09d 100644 (file)
    skip when using the GAS .p2align command. */
 #undef HAVE_GAS_MAX_SKIP_P2ALIGN
 
+/* Define if your assembler supports .nsubspa comdat option. */
+#undef HAVE_GAS_NSUBSPA_COMDAT
+
 /* Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.
    */
 #undef HAVE_GAS_SHF_MERGE
 /* Define to `int' if <sys/types.h> doesn't define. */
 #undef gid_t
 
-/* Define as `__inline' if that's what the C compiler calls it, or to nothing
-   if it is not supported. */
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
 #undef inline
+#endif
 
 /* Define to `int' if <sys/types.h> does not define. */
 #undef pid_t
index 848997e4d3ee925295c498e5bfa71208b6133483..6d6dcc8e50e1ba5a56b08785f631d6220775f031 100644 (file)
@@ -137,6 +137,7 @@ extern struct rtx_def *hppa_builtin_saveregs (void);
 
 extern void override_options (void);
 extern void output_ascii (FILE *, const char *, int);
+extern const char * som_text_section_asm_op (void);
 extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT, int *);
 extern int and_mask_p (unsigned HOST_WIDE_INT);
 extern int cint_ok_for_move (HOST_WIDE_INT);
@@ -153,7 +154,6 @@ extern int cmpib_comparison_operator (rtx, enum machine_mode);
 #endif
 
 
-
 #ifdef TREE_CODE
 extern int reloc_needed (tree);
 #ifdef RTX_CODE
@@ -165,3 +165,9 @@ extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
                                       enum machine_mode,
                                       tree, int);
 #endif /* TREE_CODE */
+
+/* Functions in varasm.c used by pa.c.  */
+extern void som_readonly_data_section (void);
+extern void som_one_only_readonly_data_section (void);
+extern void som_one_only_data_section (void);
+extern void forget_section (void);
index 8864cee7bc38f577c4a51ce0d3668062a9ba5fe0..661eff59cca94e2897c3e0924028b7b79a4f5d0e 100644 (file)
@@ -148,6 +148,7 @@ static void output_deferred_plabels (void);
 #ifdef HPUX_LONG_DOUBLE_LIBRARY
 static void pa_hpux_init_libfuncs (void);
 #endif
+static struct machine_function * pa_init_machine_status (void);
 
 /* Save the operands last given to a compare for use when we
    generate a scc or bcc insn.  */
@@ -370,6 +371,8 @@ override_options (void)
       targetm.asm_out.unaligned_op.si = NULL;
       targetm.asm_out.unaligned_op.di = NULL;
     }
+
+  init_machine_status = pa_init_machine_status;
 }
 
 static void
@@ -381,6 +384,16 @@ pa_init_builtins (void)
 #endif
 }
 
+/* Function to init struct machine_function.
+   This will be called, via a pointer variable,
+   from push_function_context.  */
+
+static struct machine_function *
+pa_init_machine_status (void)
+{
+  return ggc_alloc_cleared (sizeof (machine_function));
+}
+
 /* If FROM is a probable pointer register, mark TO as a probable
    pointer register with the same pointer alignment as FROM.  */
 
@@ -4098,6 +4111,14 @@ pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 
   fputs ("\t.EXIT\n\t.PROCEND\n", file);
 
+  if (TARGET_SOM && TARGET_GAS)
+    {
+      /* We done with this subspace except possibly for some additional
+        debug information.  Forget that we are in this subspace to ensure
+        that the next function is output in its own subspace.  */
+      forget_section ();
+    }
+
   if (INSN_ADDRESSES_SET_P ())
     {
       insn = get_last_nonnote_insn ();
@@ -7897,8 +7918,9 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
       fprintf (file, "\t.align 4\n");
       ASM_OUTPUT_LABEL (file, label);
       fprintf (file, "\t.word P'%s\n", fname);
-      function_section (thunk_fndecl);
     }
+  else if (TARGET_SOM && TARGET_GAS)
+    forget_section ();
 
   current_thunk_number++;
   nbytes = ((nbytes + FUNCTION_BOUNDARY / BITS_PER_UNIT - 1)
@@ -9060,6 +9082,50 @@ cmpib_comparison_operator (rtx op, enum machine_mode mode)
              || GET_CODE (op) == LEU));
 }
 
+/* Return a string to output before text in the current function.
+
+   This function is only used with SOM.  Because we don't support
+   named subspaces, we can only create a new subspace or switch back
+   to the default text subspace.  */
+const char *
+som_text_section_asm_op (void)
+{
+  if (!TARGET_SOM)
+    return "";
+
+  if (TARGET_GAS)
+    {
+      if (cfun && !cfun->machine->in_nsubspa)
+       {
+         /* We only want to emit a .nsubspa directive once at the
+            start of the function.  */
+         cfun->machine->in_nsubspa = 1;
+
+         /* Create a new subspace for the text.  This provides
+            better stub placement and one-only functions.  */
+         if (cfun->decl
+             && DECL_ONE_ONLY (cfun->decl)
+             && !DECL_WEAK (cfun->decl))
+           return
+ "\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=24,COMDAT";
+
+         return "\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$";
+       }
+      else
+       {
+         /* There isn't a current function or the body of the current
+            function has been completed.  So, we are changing to the
+            text section to output debugging information.  Do this in
+            the default text section.  We need to forget that we are
+            in the text section so that the function text_section in
+            varasm.c will call us the next time around.  */
+         forget_section ();
+       }
+    }
+
+  return "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$";
+}
+
 /* On hpux10, the linker will give an error if we have a reference
    in the read-only data section to a symbol defined in a shared
    library.  Therefore, expressions that might require a reloc can
@@ -9076,11 +9142,23 @@ pa_select_section (tree exp, int reloc,
       && (DECL_INITIAL (exp) == error_mark_node
           || TREE_CONSTANT (DECL_INITIAL (exp)))
       && !reloc)
-    readonly_data_section ();
+    {
+      if (TARGET_SOM
+         && DECL_ONE_ONLY (exp)
+         && !DECL_WEAK (exp))
+       som_one_only_readonly_data_section ();
+      else
+       readonly_data_section ();
+    }
   else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c'
           && !(TREE_CODE (exp) == STRING_CST && flag_writable_strings)
           && !reloc)
     readonly_data_section ();
+  else if (TARGET_SOM
+          && TREE_CODE (exp) == VAR_DECL
+          && DECL_ONE_ONLY (exp)
+          && !DECL_WEAK (exp))
+    som_one_only_data_section ();
   else
     data_section ();
 }
index 15aeccda388cba4558a9ccc60081b807590665cc..1dc2806d2ee6cf72b55109814f10e5d9950ab773 100644 (file)
@@ -424,6 +424,12 @@ do {                                                               \
 #define CAN_DEBUG_WITHOUT_FP
 \f
 /* target machine storage layout */
+typedef struct machine_function GTY(())
+{
+  /* Flag indicating that a .NSUBSPA directive has been output for
+     this function.  */
+  int in_nsubspa;
+} machine_function;
 
 /* Define this macro if it is advisable to hold scalars in registers
    in a wider mode than that declared by the program.  In such cases, 
@@ -1682,12 +1688,78 @@ do {                                                                    \
     goto LABEL
 \f
 #define TARGET_ASM_SELECT_SECTION  pa_select_section
-   
+
 /* Return a nonzero value if DECL has a section attribute.  */
 #define IN_NAMED_SECTION_P(DECL) \
   ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
    && DECL_SECTION_NAME (DECL) != NULL_TREE)
 
+/* The following extra sections and extra section functions are only used
+   for SOM, but they must be provided unconditionally because pa.c's calls
+   to the functions might not get optimized out when other object formats
+   are in use.  */
+
+#define EXTRA_SECTIONS                                                 \
+  in_som_readonly_data,                                                        \
+  in_som_one_only_readonly_data,                                       \
+  in_som_one_only_data
+
+#define EXTRA_SECTION_FUNCTIONS                                                \
+  SOM_READONLY_DATA_SECTION_FUNCTION                                   \
+  SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION                          \
+  SOM_ONE_ONLY_DATA_SECTION_FUNCTION                                   \
+  FORGET_SECTION_FUNCTION
+
+/* SOM puts readonly data in the default $LIT$ subspace when PIC code
+   is not being generated.  */
+#define SOM_READONLY_DATA_SECTION_FUNCTION                             \
+void                                                                   \
+som_readonly_data_section (void)                                       \
+{                                                                      \
+  if (!TARGET_SOM)                                                     \
+    return;                                                            \
+  if (in_section != in_som_readonly_data)                              \
+    {                                                                  \
+      in_section = in_som_readonly_data;                               \
+      fputs ("\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n", asm_out_file);      \
+    }                                                                  \
+}
+
+/* When secondary definitions are not supported, SOM makes readonly data one
+   only by creating a new $LIT$ subspace in $TEXT$ with the comdat flag.  */
+#define SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION                    \
+void                                                                   \
+som_one_only_readonly_data_section (void)                              \
+{                                                                      \
+  if (!TARGET_SOM)                                                     \
+    return;                                                            \
+  in_section = in_som_one_only_readonly_data;                          \
+  fputs ("\t.SPACE $TEXT$\n"                                           \
+        "\t.NSUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=16,COMDAT\n",\
+        asm_out_file);                                                 \
+}
+
+/* When secondary definitions are not supported, SOM makes data one only by
+   creating a new $DATA$ subspace in $PRIVATE$ with the comdat flag.  */
+#define SOM_ONE_ONLY_DATA_SECTION_FUNCTION                             \
+void                                                                   \
+som_one_only_data_section (void)                                       \
+{                                                                      \
+  if (!TARGET_SOM)                                                     \
+    return;                                                            \
+  in_section = in_som_one_only_data;                                   \
+  fputs ("\t.SPACE $PRIVATE$\n"                                                \
+        "\t.NSUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31,SORT=24,COMDAT\n", \
+        asm_out_file);                                                 \
+}
+
+#define FORGET_SECTION_FUNCTION                                                \
+void                                                                   \
+forget_section (void)                                                  \
+{                                                                      \
+  in_section = no_section;                                             \
+}
+
 /* Define this macro if references to a symbol must be treated
    differently depending on something about the variable or
    function named by the symbol (such as what section it is in).
index ae52cd0a30e26d5c95c41e3e1794720fc25dd487..1680ecbcba3f33aa790f8d9b364e22e66a555993 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for SOM assembler support.
-   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -129,19 +129,6 @@ do {                                                               \
 #endif
 
 \f
-/* NAME refers to the function's name.  If we are placing each function into
-   its own section, we need to switch to the section for this function.  Note
-   that the section name will have a "." prefix.  */
-#define ASM_OUTPUT_FUNCTION_PREFIX(FILE, NAME) \
-  {                                                                    \
-    const char *name = (*targetm.strip_name_encoding) (NAME);          \
-    if (TARGET_GAS && in_section == in_text)                           \
-      fputs ("\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
-    else if (TARGET_GAS)                                               \
-      fprintf (FILE,                                                   \
-              "\t.SUBSPA .%s\n", name);                                \
-  }
-    
 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
     do { tree fntype = TREE_TYPE (TREE_TYPE (DECL));                   \
         tree tree_type = TREE_TYPE (DECL);                             \
@@ -219,29 +206,14 @@ do {                                                              \
 
 #define TARGET_ASM_FILE_START pa_som_file_start
 
-/* Output before code.  */
-
-/* Supposedly the assembler rejects the command if there is no tab!  */
-#define TEXT_SECTION_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$\n"
-
-/* Output before read-only data.  */
-
-/* Supposedly the assembler rejects the command if there is no tab!  */
-#define READONLY_DATA_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n"
+/* String to output before text.  */
+#define TEXT_SECTION_ASM_OP som_text_section_asm_op ()
 
-#define EXTRA_SECTIONS in_readonly_data
+/* String to output before writable data.  */
+#define DATA_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $DATA$\n"
 
-#define EXTRA_SECTION_FUNCTIONS                                                \
-extern void readonly_data (void);                                      \
-void                                                                   \
-readonly_data (void)                                                   \
-{                                                                      \
-  if (in_section != in_readonly_data)                                  \
-    {                                                                  \
-      in_section = in_readonly_data;                                   \
-      fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP);            \
-    }                                                                  \
-}
+/* String to output before uninitialized data.  */
+#define BSS_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $BSS$\n"
 
 /* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups
    which reference data within the $TEXT$ space (for example constant
@@ -255,17 +227,8 @@ readonly_data (void)                                                       \
    $TEXT$ space during PIC generation.  Instead place all constant
    data into the $PRIVATE$ subspace (this reduces sharing, but it
    works correctly).  */
-
-#define READONLY_DATA_SECTION (flag_pic ? data_section : readonly_data)
-
-/* Output before writable data.  */
-
-/* Supposedly the assembler rejects the command if there is no tab!  */
-#define DATA_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $DATA$\n"
-
-/* Output before uninitialized data.  */
-
-#define BSS_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $BSS$\n"
+#define READONLY_DATA_SECTION \
+  (flag_pic ? data_section : som_readonly_data_section)
 
 /* We must not have a reference to an external symbol defined in a
    shared library in a readonly section, else the SOM linker will
@@ -361,11 +324,30 @@ do {                                              \
 #define SUPPORTS_WEAK 0
 #endif
 
-/* We can support one only if we support weak.  */
-#define SUPPORTS_ONE_ONLY SUPPORTS_WEAK
+/* CVS GAS as of 4/28/04 supports a comdat parameter for the .nsubspa
+   directive.  This provides one-only linkage semantics even though we
+   don't have weak support.  */
+#ifdef HAVE_GAS_NSUBSPA_COMDAT
+#define SUPPORTS_SOM_COMDAT (TARGET_GAS)
+#else
+#define SUPPORTS_SOM_COMDAT 0
+#endif
 
-/* Use weak (secondary definitions) to make one only declarations.  */
-#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
+/* We can support one only if we support weak or comdat.  */
+#define SUPPORTS_ONE_ONLY (SUPPORTS_WEAK || SUPPORTS_SOM_COMDAT)
+
+/* We use DECL_COMMON for uninitialized one-only variables as we don't
+   have linkonce .bss.  We use SOM secondary definitions or comdat for
+   initialized variables and functions.  */
+#define MAKE_DECL_ONE_ONLY(DECL) \
+  do {                                                                 \
+    if (TREE_CODE (DECL) == VAR_DECL                                   \
+        && (DECL_INITIAL (DECL) == 0                                   \
+            || DECL_INITIAL (DECL) == error_mark_node))                        \
+      DECL_COMMON (DECL) = 1;                                          \
+    else if (SUPPORTS_WEAK)                                            \
+      DECL_WEAK (DECL) = 1;                                            \
+  } while (0)
 
 /* This is how we tell the assembler that a symbol is weak.  The SOM
    weak implementation uses the secondary definition (sdef) flag.
index 0232ac07566062fc9718a879ddb5d2052be3e11a..1d3cc0e513346a14821ed16ac595b9f352cfe67e 100755 (executable)
@@ -10397,6 +10397,44 @@ _ACEOF
 
 fi
 
+echo "$as_me:$LINENO: checking assembler for .nsubspa comdat" >&5
+echo $ECHO_N "checking assembler for .nsubspa comdat... $ECHO_C" >&6
+if test "${gcc_cv_as_nsubspa_comdat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  gcc_cv_as_nsubspa_comdat=no
+    if test $in_tree_gas = yes; then
+    if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91`
+  then gcc_cv_as_nsubspa_comdat=yes
+fi
+  elif test x$gcc_cv_as != x; then
+    echo '     .SPACE $TEXT$
+       .NSUBSPA $CODE$,COMDAT' > conftest.s
+    if { ac_try='$gcc_cv_as  -o conftest.o conftest.s >&5'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }
+    then
+       gcc_cv_as_nsubspa_comdat=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_nsubspa_comdat" >&5
+echo "${ECHO_T}$gcc_cv_as_nsubspa_comdat" >&6
+if test $gcc_cv_as_nsubspa_comdat = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GAS_NSUBSPA_COMDAT 1
+_ACEOF
+
+fi
+
 # .hidden needs to be supported in both the assembler and the linker,
 # because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
 # This is irritatingly difficult to feature test for; we have to check the
index ec6942b43ec40864316d3cb7555fe124ce3ee1b8..89edf64bc01f57f8174b0f35644299a6c1970eae 100644 (file)
@@ -1855,6 +1855,12 @@ gcc_GAS_CHECK_FEATURE([.weak], gcc_cv_as_weak,
  [     .weak foobar],,
 [AC_DEFINE(HAVE_GAS_WEAK, 1, [Define if your assembler supports .weak.])])
 
+gcc_GAS_CHECK_FEATURE([.nsubspa comdat], gcc_cv_as_nsubspa_comdat,
+ [2,15,91],,
+ [     .SPACE $TEXT$
+       .NSUBSPA $CODE$,COMDAT],,
+[AC_DEFINE(HAVE_GAS_NSUBSPA_COMDAT, 1, [Define if your assembler supports .nsubspa comdat option.])])
+
 # .hidden needs to be supported in both the assembler and the linker,
 # because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
 # This is irritatingly difficult to feature test for; we have to check the