This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[csl-sol210-branch] Add some Solaris #pragmas


This patch enables, for i386-pc-solaris2.10, a couple of #pragma directives:
  #pragma init
  #pragma fini
  #pragma align

These appear to be needed for compatibility with the Solaris 10 system
headers.  Committed to csl-sol210-branch; I'll submit it for mainline at a
later date, after additional testing.

Does any Sparc Solaris target need these?  If so I could put them in
config/...

-- 
Daniel Jacobowitz

2004-07-13  Daniel Jacobowitz  <dan@debian.org>

	* config.gcc (i[34567]86-*-solaris2.1[0-9]): Set tm_p_file,
	tmake_file, c_target_objs, and cxx_target_objs.
	* config/i386/i386.c (TARGET_INSERT_ATTRIBUTES): Define to
	SUBTARGET_INSERT_ATTRIBUTES.
	(ix86_attribute_table): Include "init" and "fini" if
	TARGET_INIT_FINI_ATTRIBUTES.
	* config/i386/sol2-10.h (SUBTARGET_INSERT_ATTRIBUTES)
	(REGISTER_TARGET_PRAGMAS, ASM_DECLARE_FUNCTION_SIZE)
	(TARGET_INIT_FINI_ATTRIBUTES): Define.
	* config/i386/sol2-10-protos.h: New file.
	* config/i386/sol2-c.c: New file.
	* config/i386/t-sol2-10: New file.
	* doc/extend.texi (Solaris Pragmas): New section.

2004-07-13  Daniel Jacobowitz  <dan@debian.org>

	* gcc.dg/pragma-align-2.c: New testcase.
	* gcc.dg/pragma-init-fini.c: New testcase.
	* gcc.dg/pragma-align.c: Run test.  Include i?86-solaris2.1[0-9]*.

Index: gcc/config.gcc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config.gcc,v
retrieving revision 1.465.2.1
diff -u -p -r1.465.2.1 config.gcc
--- gcc/config.gcc	12 Jul 2004 14:59:19 -0000	1.465.2.1
+++ gcc/config.gcc	13 Jul 2004 19:38:50 -0000
@@ -986,7 +986,11 @@ i[34567]86-*-solaris2*)
 	case ${target} in
 	*-*-solaris2.1[0-9])
 		tm_file="${tm_file} i386/x86-64.h i386/sol2-10.h"
+		tm_p_file="${tm_p_file} i386/sol2-10-protos.h"
 		tm_defines="${tm_defines} TARGET_BI_ARCH=1"
+		tmake_file="${tmake_file} i386/t-sol2-10"
+		c_target_objs="sol2-c.o"
+		cxx_target_objs="sol2-c.o"
 		;;
 	esac
 	extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
Index: gcc/config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.685.2.1
diff -u -p -r1.685.2.1 i386.c
--- gcc/config/i386/i386.c	12 Jul 2004 14:42:52 -0000	1.685.2.1
+++ gcc/config/i386/i386.c	13 Jul 2004 19:38:52 -0000
@@ -1075,6 +1075,11 @@ static void init_ext_80387_constants (vo
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
 
+#ifdef SUBTARGET_INSERT_ATTRIBUTES
+#undef TARGET_INSERT_ATTRIBUTES
+#define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
+#endif
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 
@@ -1598,6 +1603,10 @@ const struct attribute_spec ix86_attribu
 #endif
   { "ms_struct", 0, 0, false, false,  false, ix86_handle_struct_attribute },
   { "gcc_struct", 0, 0, false, false,  false, ix86_handle_struct_attribute },
+#ifdef TARGET_INIT_FINI_ATTRIBUTES
+  { "init",      0, 0, true,  false,  false, NULL },
+  { "fini",      0, 0, true,  false,  false, NULL },
+#endif
   { NULL,        0, 0, false, false, false, NULL }
 };
 
Index: gcc/config/i386/sol2-10-protos.h
===================================================================
RCS file: gcc/config/i386/sol2-10-protos.h
diff -N gcc/config/i386/sol2-10-protos.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/i386/sol2-10-protos.h	13 Jul 2004 19:38:52 -0000
@@ -0,0 +1,25 @@
+/* Prototypes.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+extern void solaris_insert_attributes (tree, tree *);
+extern void solaris_pragma_align (struct cpp_reader *);
+extern void solaris_pragma_init (struct cpp_reader *);
+extern void solaris_pragma_fini (struct cpp_reader *);
+extern void solaris_output_init_fini (FILE *, tree);
Index: gcc/config/i386/sol2-10.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/Attic/sol2-10.h,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 sol2-10.h
--- gcc/config/i386/sol2-10.h	12 Jul 2004 14:59:20 -0000	1.1.2.1
+++ gcc/config/i386/sol2-10.h	13 Jul 2004 19:38:52 -0000
@@ -35,3 +35,25 @@ Boston, MA 02111-1307, USA.  */
 #define WCHAR_TYPE (TARGET_64BIT ? "int" : "long int")
 #undef WCHAR_TYPE_SIZE
 #define WCHAR_TYPE_SIZE 32
+
+#define SUBTARGET_INSERT_ATTRIBUTES solaris_insert_attributes
+
+#define REGISTER_TARGET_PRAGMAS()				\
+  do {								\
+    c_register_pragma (0, "align", solaris_pragma_align);	\
+    c_register_pragma (0, "init", solaris_pragma_init);		\
+    c_register_pragma (0, "fini", solaris_pragma_fini);		\
+  } while (0)
+
+/* This is how to declare the size of a function.  */
+#undef ASM_DECLARE_FUNCTION_SIZE
+#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)		\
+  do								\
+    {								\
+      if (!flag_inhibit_size_directive)				\
+        ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME);			\
+      solaris_output_init_fini (FILE, DECL);			\
+    }								\
+  while (0)
+
+#define TARGET_INIT_FINI_ATTRIBUTES
Index: gcc/config/i386/sol2-c.c
===================================================================
RCS file: gcc/config/i386/sol2-c.c
diff -N gcc/config/i386/sol2-c.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/i386/sol2-c.c	13 Jul 2004 19:38:52 -0000
@@ -0,0 +1,299 @@
+/* Solaris support needed only by C/C++ frontends.
+   Copyright (C) 2004  Free Software Foundation, Inc.
+   Contributed by CodeSourcery, LLC.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "cpplib.h"
+#include "tree.h"
+#include "c-pragma.h"
+#include "c-tree.h"
+#include "c-incpath.h"
+#include "toplev.h"
+#include "tm_p.h"
+
+static GTY(()) tree pending_aligns, pending_inits, pending_finis;
+
+/* Handle #pragma align ALIGNMENT (VAR [, VAR]...)  */
+
+void
+solaris_pragma_align (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+  tree t, x;
+  enum cpp_ttype ttype;
+  HOST_WIDE_INT low;
+
+  if (c_lex (&x) != CPP_NUMBER
+      || c_lex (&t) != CPP_OPEN_PAREN)
+    {
+      warning ("malformed %<#pragma align%>, ignoring");
+      return;
+    }
+
+  low = TREE_INT_CST_LOW (x);
+  if (TREE_INT_CST_HIGH (x) != 0
+      || (low != 1 && low != 2 && low != 4 && low != 8 && low != 16
+	  && low != 32 && low != 64 && low != 128))
+    {
+      warning ("invalid alignment for %<#pragma align%>, ignoring");
+      return;
+    }
+
+  ttype = c_lex (&t);
+  if (ttype != CPP_NAME)
+    {
+      warning ("malformed %<#pragma align%>, ignoring");
+      return;
+    }
+
+  while (1)
+    {
+      tree decl = identifier_global_value (t);
+      if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+	warning ("%<#pragma align%> must appear before the declaration of "
+		 "%D, ignoring", decl);
+      else
+	pending_aligns = tree_cons (t, build_tree_list (NULL, x),
+				    pending_aligns);
+
+      ttype = c_lex (&t);
+      if (ttype == CPP_COMMA)
+	{
+	  ttype = c_lex (&t);
+	  if (ttype != CPP_NAME)
+	    {
+	      warning ("malformed %<#pragma align%>");
+	      return;
+	    }
+	}
+      else if (ttype == CPP_CLOSE_PAREN)
+	{
+	  if (c_lex (&t) != CPP_EOF)
+	    warning ("junk at end of %<#pragma align%>");
+	  return;
+	}
+      else
+	{
+	  warning ("malformed %<#pragma align%>");
+	  return;
+	}
+    }
+}
+
+/* Handle #pragma init (function [, function]...)  */
+
+void
+solaris_pragma_init (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+  tree t;
+  enum cpp_ttype ttype;
+
+  if (c_lex (&t) != CPP_OPEN_PAREN)
+    {
+      warning ("malformed %<#pragma init%>, ignoring");
+      return;
+    }
+
+  ttype = c_lex (&t);
+  if (ttype != CPP_NAME)
+    {
+      warning ("malformed %<#pragma init%>, ignoring");
+      return;
+    }
+
+  while (1)
+    {
+      tree decl = identifier_global_value (t);
+      if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+	{
+	  tree init_list = build_tree_list (get_identifier ("init"),
+					    NULL);
+	  tree attrs = tree_cons (get_identifier ("used"), NULL, init_list);
+	  decl_attributes (&decl, attrs, 0);
+	}
+      else
+	pending_inits = tree_cons (t, NULL, pending_inits);
+
+      ttype = c_lex (&t);
+      if (ttype == CPP_COMMA)
+	{
+	  ttype = c_lex (&t);
+	  if (ttype != CPP_NAME)
+	    {
+	      warning ("malformed %<#pragma init%>");
+	      return;
+	    }
+	}
+      else if (ttype == CPP_CLOSE_PAREN)
+	{
+	  if (c_lex (&t) != CPP_EOF)
+	    warning ("junk at end of %<#pragma init%>");
+	  return;
+	}
+      else
+	{
+	  warning ("malformed %<#pragma init%>");
+	  return;
+	}
+    }
+}
+
+/* Handle #pragma fini (function [, function]...)  */
+
+void
+solaris_pragma_fini (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+  tree t;
+  enum cpp_ttype ttype;
+
+  if (c_lex (&t) != CPP_OPEN_PAREN)
+    {
+      warning ("malformed %<#pragma fini%>, ignoring");
+      return;
+    }
+
+  ttype = c_lex (&t);
+  if (ttype != CPP_NAME)
+    {
+      warning ("malformed %<#pragma fini%>, ignoring");
+      return;
+    }
+
+  while (1)
+    {
+      tree decl = identifier_global_value (t);
+      if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+	{
+	  tree fini_list = build_tree_list (get_identifier ("fini"),
+					    NULL);
+	  tree attrs = tree_cons (get_identifier ("used"), NULL, fini_list);
+	  decl_attributes (&decl, attrs, 0);
+	}
+      else
+	pending_finis = tree_cons (t, NULL, pending_finis);
+
+      ttype = c_lex (&t);
+      if (ttype == CPP_COMMA)
+	{
+	  ttype = c_lex (&t);
+	  if (ttype != CPP_NAME)
+	    {
+	      warning ("malformed %<#pragma fini%>");
+	      return;
+	    }
+	}
+      else if (ttype == CPP_CLOSE_PAREN)
+	{
+	  if (c_lex (&t) != CPP_EOF)
+	    warning ("junk at end of %<#pragma fini%>");
+	  return;
+	}
+      else
+	{
+	  warning ("malformed %<#pragma fini%>");
+	  return;
+	}
+    }
+}
+
+/* Attach any pending attributes for DECL to the list in *ATTRIBUTES.  */
+
+void
+solaris_insert_attributes (tree decl, tree *attributes)
+{
+  tree *x, next;
+
+  if (pending_aligns != NULL && TREE_CODE (decl) == VAR_DECL)
+    for (x = &pending_aligns; *x; x = &TREE_CHAIN (pending_aligns))
+      {
+	tree name = TREE_PURPOSE (*x);
+	tree value = TREE_VALUE (*x);
+	if (DECL_NAME (decl) == name)
+	  {
+	    if (lookup_attribute ("aligned", DECL_ATTRIBUTES (decl))
+		|| lookup_attribute ("aligned", *attributes))
+	      warning ("%Jignoring %<#pragma align%> for explicitly "
+		       "aligned %<%D%>", decl, decl);
+	    else
+	      *attributes = tree_cons (get_identifier ("aligned"), value,
+				       *attributes);
+	    next = TREE_CHAIN (*x);
+	    ggc_free (*x);
+	    *x = next;
+	    break;
+	  }
+      }
+
+  if (pending_inits != NULL && TREE_CODE (decl) == FUNCTION_DECL)
+    for (x = &pending_inits; *x; x = &TREE_CHAIN (pending_inits))
+      {
+	tree name = TREE_PURPOSE (*x);
+	if (DECL_NAME (decl) == name)
+	  {
+	    *attributes = tree_cons (get_identifier ("init"), NULL,
+				     *attributes);
+	    *attributes = tree_cons (get_identifier ("used"), NULL,
+				     *attributes);
+	    next = TREE_CHAIN (*x);
+	    ggc_free (*x);
+	    *x = next;
+	    break;
+	  }
+      }
+
+  if (pending_finis != NULL && TREE_CODE (decl) == FUNCTION_DECL)
+    for (x = &pending_finis; *x; x = &TREE_CHAIN (pending_finis))
+      {
+	tree name = TREE_PURPOSE (*x);
+	if (DECL_NAME (decl) == name)
+	  {
+	    *attributes = tree_cons (get_identifier ("fini"), NULL,
+				     *attributes);
+	    *attributes = tree_cons (get_identifier ("used"), NULL,
+				     *attributes);
+	    next = TREE_CHAIN (*x);
+	    ggc_free (*x);
+	    *x = next;
+	    break;
+	  }
+      }
+}
+
+/* Output initializer or finalizer entries for DECL to FILE.  */
+
+void
+solaris_output_init_fini (FILE *file, tree decl)
+{
+  if (lookup_attribute ("init", DECL_ATTRIBUTES (decl)))
+    {
+      fprintf (file, "\t.section\t.init\n");
+      fprintf (file, "\tcall\t%s\n", IDENTIFIER_POINTER (DECL_NAME (decl)));
+      fprintf (file, "\t.popsection\n");
+    }
+
+  if (lookup_attribute ("fini", DECL_ATTRIBUTES (decl)))
+    {
+      fprintf (file, "\t.section\t.fini\n");
+      fprintf (file, "\tcall\t%s\n", IDENTIFIER_POINTER (DECL_NAME (decl)));
+      fprintf (file, "\t.popsection\n");
+    }
+}
Index: gcc/config/i386/t-sol2-10
===================================================================
RCS file: gcc/config/i386/t-sol2-10
diff -N gcc/config/i386/t-sol2-10
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/i386/t-sol2-10	13 Jul 2004 19:38:52 -0000
@@ -0,0 +1,6 @@
+# Solaris-specific pragmas
+sol2-c.o: $(srcdir)/config/i386/sol2-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+  $(TM_H) $(CPPLIB_H) tree.h c-pragma.h $(C_TREE_H) toplev.h $(TM_P_H) \
+  c-incpath.h
+	$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+	  $(srcdir)/config/i386/sol2-c.c
Index: gcc/doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.200
diff -u -p -r1.200 extend.texi
--- gcc/doc/extend.texi	7 Jul 2004 17:38:40 -0000	1.200
+++ gcc/doc/extend.texi	13 Jul 2004 19:38:54 -0000
@@ -7209,6 +7209,7 @@ for further explanation.
 * ARM Pragmas::
 * RS/6000 and PowerPC Pragmas::
 * Darwin Pragmas::
+* Solaris Pragmas::
 * Symbol-Renaming Pragmas::
 @end menu
 
@@ -7293,6 +7294,38 @@ that of the @code{unused} attribute, exc
 anywhere within the variables' scopes.
 @end table
 
+@node Solaris Pragmas
+@subsection Solaris Pragmas
+
+The Solaris target supports @code{#pragma redefine_extname}
+(@pxref{Symbol-Renaming Pragmas}).  The x86/AMD64 Solaris 10 target also
+supports additional @code{#pragma} directives for compatibility with system
+headers.
+
+@table @code
+@item align @var{alignment} (@var{variable} [, @var{variable}]...)
+@cindex pragma, align
+
+Increase the minimum alignment of each @var{variable} to @var{alignment}.
+This is the same as GCC's @code{aligned} attribute @pxref{Variable
+Attributes}).
+
+@item fini (@var{function} [, @var{function}]...)
+@cindex pragma, fini
+
+This pragma causes each listed @var{function} to be called after
+main, or during shared module unloading, by adding a call to the
+@code{.fini} section.
+
+@item init (@var{function} [, @var{function}]...)
+@cindex pragma, init
+
+This pragma causes each listed @var{function} to be called during
+initialization (before @code{main}) or during shared module loading, by
+adding a call to the @code{.init} section.
+
+@end table
+
 @node Symbol-Renaming Pragmas
 @subsection Symbol-Renaming Pragmas
 
Index: gcc/testsuite/gcc.dg/pragma-align-2.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/pragma-align-2.c
diff -N gcc/testsuite/gcc.dg/pragma-align-2.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/pragma-align-2.c	13 Jul 2004 19:38:54 -0000
@@ -0,0 +1,54 @@
+/* { dg-do run { target i?86-*-solaris2.1[0-9]* } } */
+
+void abort (void);
+
+#pragma align 1(x1)
+#pragma align 2(x2)
+#pragma align 4(x4)
+#pragma align 8(x8,y8,z8)
+#pragma align 16(x16)
+#pragma align 32(x32)
+#pragma align 64(x64)
+#pragma align 128(x128)
+
+#pragma align 8(not_defined)
+
+#pragma align 9(odd_align)	/* { dg-error "invalid alignment" } */
+#pragma align 256(high_align)	/* { dg-error "invalid alignment" } */
+#pragma align -1(neg_align)	/* { dg-error "malformed" } */
+#pragma align bad_align		/* { dg-error "malformed" } */
+#pragma align 1(bad_align	/* { dg-error "malformed" } */
+
+int x, x1, x2, x4, x8, y8, z8, x16, x32, x64, x128;
+
+#pragma align 16(x)		/* { dg-error "must appear before" } */
+
+int
+main ()
+{
+  if (__alignof__ (x4) < 4)
+    abort ();
+
+  if (__alignof__ (x8) < 8)
+    abort ();
+
+  if (__alignof__ (y8) < 8)
+    abort ();
+
+  if (__alignof__ (z8) < 8)
+    abort ();
+
+  if (__alignof__ (x16) < 16)
+    abort ();
+
+  if (__alignof__ (x32) < 32)
+    abort ();
+
+  if (__alignof__ (x64) < 64)
+    abort ();
+
+  if (__alignof__ (x128) < 128)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/pragma-align.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/pragma-align.c,v
retrieving revision 1.2
diff -u -p -r1.2 pragma-align.c
--- gcc/testsuite/gcc.dg/pragma-align.c	11 Sep 2000 22:47:05 -0000	1.2
+++ gcc/testsuite/gcc.dg/pragma-align.c	13 Jul 2004 19:38:54 -0000
@@ -1,6 +1,6 @@
 /* Prove that HANDLE_SYSTEMV_PRAGMA alignment handling works somewhat. */
 
-/* { dg-do compile { target i?86-*-linux* i?86-*-*bsd* i?86-*-sco3.2v5* } } */
+/* { dg-do run { target i?86-*-linux* i?86-*-*bsd* i?86-*-sco3.2v5* i?86-*-solaris2.1[0-9]* } } */
 
 struct {
         char one;
@@ -39,4 +39,3 @@ main()
         if(sizeof(resetalign) != sizeof(defaultalign)) abort();
 	return 0;
 }
-
Index: gcc/testsuite/gcc.dg/pragma-init-fini.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/pragma-init-fini.c
diff -N gcc/testsuite/gcc.dg/pragma-init-fini.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/pragma-init-fini.c	13 Jul 2004 19:38:54 -0000
@@ -0,0 +1,50 @@
+/* Tests for #pragma init and #pragma fini.  */
+
+/* { dg-do run { target i?86-*-solaris2.1[0-9]* } } */
+
+extern void abort ();
+
+#pragma init		/* { dg-error "malformed" } */
+#pragma init ()		/* { dg-error "malformed" } */
+#pragma init init_func	/* { dg-error "malformed" } */
+
+#pragma fini		/* { dg-error "malformed" } */
+#pragma fini ()		/* { dg-error "malformed" } */
+#pragma fini fini_func	/* { dg-error "malformed" } */
+
+#pragma init (init_func, init_static_func)
+
+int glob_1, glob_2;
+
+void init_func (void)
+{
+  glob_1 = 1;
+}
+
+static void init_static_func (void)
+{
+  glob_2 = 2;
+}
+
+#pragma fini (fini_func, fini_static_func)
+
+void fini_func (void)
+{
+
+}
+
+static void fini_static_func (void)
+{
+
+}
+
+int main()
+{
+  if (glob_1 != 1)
+    abort ();
+
+  if (glob_2 != 2)
+    abort ();
+
+  return 0;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]