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]

Re: Solaris pragma macro expansion


On Fri, 19 Nov 2004, Zack Weinberg wrote:

> As a stopgap measure, suggest ignoring the macro-expansion-enabled
> flag on individual pragmas when called from
> cpp_handle_deferred_pragma.  This will produce behavior which is
> no worse than the status quo.

This revised patch to Solaris pragmas removes the change to allow
align pragmas after first declaration (which didn't seem to be
supported by Sun's specification after all) and avoids macro
expansion when expanding deferred pragmas.

Bootstrapped with no regressions on i386-pc-solaris2.10 (on top of the
previous five unreviewed patches).  OK to commit?

gcc:
2004-11-23  Daniel Jacobowitz  <dan@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>

	* config/sol2-c.c (solaris_register_pragmas): Use
	c_register_pragma_with_expansion.
	* config/sol2.h (HANDLE_PRAGMA_PACK_WITH_EXPANSION): Define.
	* c-pragma.c (c_register_pragma): Update call to
	cpp_register_pragma.
	(c_register_pragma_with_expansion): New function.
	(init_pragma): Honor HANDLE_PRAGMA_PACK_WITH_EXPANSION.
	* c-pragma.h (c_register_pragma_with_expansion): New prototype.
	* doc/extend.texi (Solaris Pragmas): Mention macro expansion for
	#pragma align.
	* doc/tm.texi (c_register_pragma_with_expansion,
	HANDLE_PRAGMA_PACK_WITH_EXPANSION): Document.

gcc/testsuite:
2004-11-23  Daniel Jacobowitz  <dan@codesourcery.com>

	* gcc.dg/pragma-align-2.c: Test macro expansion.
	* gcc.dg/pragma-pack-2.c: New test.

libcpp:
2004-11-23  Daniel Jacobowitz  <dan@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>

	* internal.h (struct lexer_state): Add in_deferred_pragma.
	* directives.c (struct pragma_entry): Add allow_expansion.
	(insert_pragma_entry): Take allow_expansion flag.
	(register_pragma): Likewise.
	(cpp_register_pragma): Likewise.
	(_cpp_init_internal_pragmas): Update calls to cpp_register_pragma.
	(do_pragma): Honor allow_expansion.
	(cpp_handle_deferred_pragma): Set in_deferred_pragma.
	* include/cpplib.h (cpp_register_pragma): Update prototype.

diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/config/sol2-c.c gcc-sol210/gcc/config/sol2-c.c
--- gcc-merge-HEAD-csl-sol210-1/gcc/config/sol2-c.c	2004-09-17 14:54:50.000000000 -0700
+++ gcc-sol210/gcc/config/sol2-c.c	2004-09-27 09:24:48.000000000 -0700
@@ -266,7 +269,7 @@ solaris_pragma_fini (cpp_reader *pfile A
 void
 solaris_register_pragmas (void)
 {
-  c_register_pragma (0, "align", solaris_pragma_align);
+  c_register_pragma_with_expansion (0, "align", solaris_pragma_align);
   c_register_pragma (0, "init", solaris_pragma_init);
   c_register_pragma (0, "fini", solaris_pragma_fini);
 }
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/config/sol2.h gcc-sol210/gcc/config/sol2.h
--- gcc-merge-HEAD-csl-sol210-1/gcc/config/sol2.h	2004-07-25 11:10:02.000000000 -0700
+++ gcc-sol210/gcc/config/sol2.h	2004-09-27 08:44:58.000000000 -0700
@@ -234,3 +245,6 @@ __enable_execute_stack (void *addr)					
 extern GTY(()) tree solaris_pending_aligns;
 extern GTY(()) tree solaris_pending_inits;
 extern GTY(()) tree solaris_pending_finis;
+
+/* Allow macro expansion in #pragma pack.  */
+#define HANDLE_PRAGMA_PACK_WITH_EXPANSION
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/c-pragma.c gcc-sol210/gcc/c-pragma.c
--- gcc-merge-HEAD-csl-sol210-1/gcc/c-pragma.c	2004-09-17 14:54:22.000000000 -0700
+++ gcc-sol210/gcc/c-pragma.c	2004-09-27 08:44:55.000000000 -0700
@@ -627,13 +658,20 @@ handle_pragma_visibility (cpp_reader *du
 
 #endif
 
-/* Front-end wrapper for pragma registration to avoid dragging
+/* Front-end wrappers for pragma registration to avoid dragging
    cpplib.h in almost everywhere.  */
 void
 c_register_pragma (const char *space, const char *name,
 		   void (*handler) (struct cpp_reader *))
 {
-  cpp_register_pragma (parse_in, space, name, handler);
+  cpp_register_pragma (parse_in, space, name, handler, 0);
+}
+
+void
+c_register_pragma_with_expansion (const char *space, const char *name,
+				  void (*handler) (struct cpp_reader *))
+{
+  cpp_register_pragma (parse_in, space, name, handler, 1);
 }
 
 /* Set up front-end pragmas.  */
@@ -641,8 +679,12 @@ void
 init_pragma (void)
 {
 #ifdef HANDLE_PRAGMA_PACK
+#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
+  c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
+#else
   c_register_pragma (0, "pack", handle_pragma_pack);
 #endif
+#endif
 #ifdef HANDLE_PRAGMA_WEAK
   c_register_pragma (0, "weak", handle_pragma_weak);
 #endif
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/c-pragma.h gcc-sol210/gcc/c-pragma.h
--- gcc-merge-HEAD-csl-sol210-1/gcc/c-pragma.h	2004-09-20 19:22:36.000000000 -0700
+++ gcc-sol210/gcc/c-pragma.h	2004-09-27 08:44:55.000000000 -0700
@@ -53,11 +53,13 @@ extern struct cpp_reader* parse_in;
 
 extern void init_pragma (void);
 
-/* Front-end wrapper for pragma registration to avoid dragging
+/* Front-end wrappers for pragma registration to avoid dragging
    cpplib.h in almost everywhere.  */
 extern void c_register_pragma (const char *, const char *,
 			       void (*) (struct cpp_reader *));
+extern void c_register_pragma_with_expansion (const char *, const char *,
+					      void (*) (struct cpp_reader *));
 extern void maybe_apply_pragma_weak (tree);
 extern tree maybe_apply_renaming_pragma (tree, tree);
 extern void add_to_renaming_pragma_list (tree, tree);
 
--- GCC.orig/gcc/doc/extend.texi	2004-11-05 01:22:46.000000000 +0000
+++ GCC/gcc/doc/extend.texi	2004-11-19 16:36:59.000000000 +0000
@@ -8603,7 +8603,7 @@
 
 Increase the minimum alignment of each @var{variable} to @var{alignment}.
 This is the same as GCC's @code{aligned} attribute @pxref{Variable
-Attributes}).
+Attributes}).  Macro expansion occurs on the arguments to this pragma.
 
 @item fini (@var{function} [, @var{function}]...)
 @cindex pragma, fini
--- GCC.orig/gcc/doc/tm.texi	2004-11-18 09:38:16.000000000 +0000
+++ GCC/gcc/doc/tm.texi	2004-11-19 16:56:11.000000000 +0000
@@ -9037,7 +9037,8 @@
 @defmac REGISTER_TARGET_PRAGMAS ()
 Define this macro if you want to implement any target-specific pragmas.
 If defined, it is a C expression which makes a series of calls to
-@code{c_register_pragma} for each pragma.  The macro may also do any
+@code{c_register_pragma} or @code{c_register_pragma_with_expansion}
+for each pragma.  The macro may also do any
 setup required for the pragmas.
 
 The primary reason to define this macro is to provide compatibility with
@@ -9053,8 +9054,10 @@
 @end defmac
 
 @deftypefun void c_register_pragma (const char *@var{space}, const char *@var{name}, void (*@var{callback}) (struct cpp_reader *))
+@deftypefunx void c_register_pragma_with_expansion (const char *@var{space}, const char *@var{name}, void (*@var{callback}) (struct cpp_reader *))
 
-Each call to @code{c_register_pragma} establishes one pragma.  The
+Each call to @code{c_register_pragma} or
+@code{c_register_pragma_with_expansion} establishes one pragma.  The
 @var{callback} routine will be called when the preprocessor encounters a
 pragma of the form
 
@@ -9068,7 +9071,10 @@
 on to cpplib's functions if necessary.  You can lex tokens after the
 @var{name} by calling @code{c_lex}.  Tokens that are not read by the
 callback will be silently ignored.  The end of the line is indicated by
-a token of type @code{CPP_EOF}
+a token of type @code{CPP_EOF}.  Macro expansion occurs on the
+arguments of pragmas registered with
+@code{c_register_pragma_with_expansion} but not on the arguments of
+pragmas registered with @code{c_register_pragma}.
 
 For an example use of this routine, see @file{c4x.h} and the callback
 routines defined in @file{c4x-c.c}.
@@ -9132,6 +9138,12 @@
 value.
 @end defmac
 
+@defmac HANDLE_PRAGMA_PACK_WITH_EXPANSION
+Define this macro (to a value of 1), as well as
+@code{HANDLE_SYSV_PRAGMA}, if macros should be expanded in the
+arguments of @samp{#pragma pack}.
+@end defmac
+
 @defmac TARGET_DEFAULT_PACK_STRUCT
 If your target requires a structure packing default other than 0 (meaning
 the machine default), define this macro the the necessary value (in bytes).
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/testsuite/gcc.dg/pragma-align-2.c gcc-sol210/gcc/testsuite/gcc.dg/pragma-align-2.c
--- gcc-merge-HEAD-csl-sol210-1/gcc/testsuite/gcc.dg/pragma-align-2.c	2004-07-25 11:08:52.000000000 -0700
+++ gcc-sol210/gcc/testsuite/gcc.dg/pragma-align-2.c	2004-09-27 08:45:13.000000000 -0700
@@ -11,6 +11,12 @@ void abort (void);
 #pragma align 64(x64)
 #pragma align 128(x128)
 
+#define MACRO 128
+#define MACRO2(A) A
+
+#pragma align MACRO(y128)
+#pragma align MACRO2(MACRO) (z128)
+
 #pragma align 8(not_defined)
 
 #pragma align 9(odd_align)	/* { dg-error "invalid alignment" } */
@@ -19,9 +25,9 @@ void abort (void);
 #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;
+int x, x1, x2, x4, x8, y8, z8, x16, x32, x64, x128, y128, z128;
 
 #pragma align 16(x)		/* { dg-error "must appear before" } */
 
 int
 main ()
@@ -50,5 +59,11 @@ main ()
   if (__alignof__ (x128) < 128)
     abort ();
 
+  if (__alignof__ (y128) < 128)
+    abort ();
+
+  if (__alignof__ (z128) < 128)
+    abort (); 
+
   return 0;
 }
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/gcc/testsuite/gcc.dg/pragma-pack-2.c gcc-sol210/gcc/testsuite/gcc.dg/pragma-pack-2.c
--- gcc-merge-HEAD-csl-sol210-1/gcc/testsuite/gcc.dg/pragma-pack-2.c	1969-12-31 16:00:00.000000000 -0800
+++ gcc-sol210/gcc/testsuite/gcc.dg/pragma-pack-2.c	2004-09-27 08:45:13.000000000 -0700
@@ -0,0 +1,48 @@
+/* On Solaris, #pragma pack should accept macro expansion.  */
+
+/* { dg-do run { target *-*-solaris2.* } } */
+
+extern void abort (void);
+
+struct {
+        char one;
+        long two;
+} defaultalign;
+
+#define ALIGNHIGH 16
+
+#pragma pack(ALIGNHIGH)
+struct {
+        char one;
+        long two;
+} sixteen;
+
+#define ALIGN1(X) 1
+#pragma pack(ALIGN1(4))
+struct {
+        char one;
+        long two;
+} two;
+
+#define ALIGN2(X) X
+#pragma pack(ALIGN2(2))
+struct {
+        char one;
+        long two;
+} three;
+
+#define EMPTY
+#pragma pack(EMPTY)
+struct {
+        char one;
+        long two;
+} resetalign;
+
+main()
+{
+        if(sizeof(sixteen) < sizeof(defaultalign)) abort();
+        if(sizeof(two) >= sizeof(defaultalign)) abort();
+        if(sizeof(three) <= sizeof(two)) abort();
+        if(sizeof(resetalign) != sizeof(defaultalign)) abort();
+	return 0;
+}
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/libcpp/directives.c gcc-sol210/libcpp/directives.c
--- gcc-merge-HEAD-csl-sol210-1/libcpp/directives.c	2004-09-17 17:53:50.000000000 -0700
+++ gcc-sol210/libcpp/directives.c	2004-09-27 08:45:16.000000000 -0700
@@ -45,6 +45,7 @@ struct pragma_entry
   struct pragma_entry *next;
   const cpp_hashnode *pragma;	/* Name and length.  */
   bool is_nspace;
+  bool allow_expansion;
   bool is_internal;
   union {
     pragma_cb handler;
@@ -108,9 +109,9 @@ static struct pragma_entry *insert_pragm
                                                  struct pragma_entry **,
                                                  const cpp_hashnode *,
                                                  pragma_cb,
-						 bool);
+						 bool, bool);
 static void register_pragma (cpp_reader *, const char *, const char *,
-			     pragma_cb, bool);
+			     pragma_cb, bool, bool);
 static int count_registered_pragmas (struct pragma_entry *);
 static char ** save_registered_pragmas (struct pragma_entry *, char **);
 static char ** restore_registered_pragmas (cpp_reader *, struct pragma_entry *,
@@ -964,7 +965,7 @@ lookup_pragma_entry (struct pragma_entry
 static struct pragma_entry *
 insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain,
 		     const cpp_hashnode *pragma, pragma_cb handler,
-		     bool internal)
+		     bool allow_expansion, bool internal)
 {
   struct pragma_entry *new;
 
@@ -982,6 +983,7 @@ insert_pragma_entry (cpp_reader *pfile, 
       new->u.space = NULL;
     }
 
+  new->allow_expansion = allow_expansion;
   new->is_internal = internal;
   new->next = *chain;
   *chain = new;
@@ -990,12 +992,13 @@ insert_pragma_entry (cpp_reader *pfile, 
 
 /* Register a pragma NAME in namespace SPACE.  If SPACE is null, it
    goes in the global namespace.  HANDLER is the handler it will call,
-   which must be non-NULL.  INTERNAL is true if this is a pragma
-   registered by cpplib itself, false if it is registered via
+   which must be non-NULL.  If ALLOW_EXPANSION is set, allow macro
+   expansion while parsing pragma NAME.  INTERNAL is true if this is a
+   pragma registered by cpplib itself, false if it is registered via
    cpp_register_pragma */
 static void
 register_pragma (cpp_reader *pfile, const char *space, const char *name,
-		 pragma_cb handler, bool internal)
+		 pragma_cb handler, bool allow_expansion, bool internal)
 {
   struct pragma_entry **chain = &pfile->pragmas;
   struct pragma_entry *entry;
@@ -1009,7 +1012,8 @@ register_pragma (cpp_reader *pfile, cons
       node = cpp_lookup (pfile, U space, strlen (space));
       entry = lookup_pragma_entry (*chain, node);
       if (!entry)
-	entry = insert_pragma_entry (pfile, chain, node, NULL, internal);
+	entry = insert_pragma_entry (pfile, chain, node, NULL, 
+				     allow_expansion, internal);
       else if (!entry->is_nspace)
 	goto clash;
       chain = &entry->u.space;
@@ -1032,17 +1036,20 @@ register_pragma (cpp_reader *pfile, cons
 	cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name);
     }
   else
-    insert_pragma_entry (pfile, chain, node, handler, internal);
+    insert_pragma_entry (pfile, chain, node, handler, allow_expansion, 
+			 internal);
 }
 
 /* Register a pragma NAME in namespace SPACE.  If SPACE is null, it
    goes in the global namespace.  HANDLER is the handler it will call,
-   which must be non-NULL.  This function is exported from libcpp. */
+   which must be non-NULL.  If ALLOW_EXPANSION is set, allow macro
+   expansion while parsing pragma NAME.  This function is exported
+   from libcpp. */
 void
 cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name,
-		     pragma_cb handler)
+		     pragma_cb handler, bool allow_expansion)
 {
-  register_pragma (pfile, space, name, handler, false);
+  register_pragma (pfile, space, name, handler, allow_expansion, false);
 }
 
 /* Register the pragmas the preprocessor itself handles.  */
@@ -1050,12 +1057,14 @@ void
 _cpp_init_internal_pragmas (cpp_reader *pfile)
 {
   /* Pragmas in the global namespace.  */
-  register_pragma (pfile, 0, "once", do_pragma_once, true);
+  register_pragma (pfile, 0, "once", do_pragma_once, false, true);
 
   /* New GCC-specific pragmas should be put in the GCC namespace.  */
-  register_pragma (pfile, "GCC", "poison", do_pragma_poison, true);
-  register_pragma (pfile, "GCC", "system_header", do_pragma_system_header, true);
-  register_pragma (pfile, "GCC", "dependency", do_pragma_dependency, true);
+  register_pragma (pfile, "GCC", "poison", do_pragma_poison, false, true);
+  register_pragma (pfile, "GCC", "system_header", do_pragma_system_header, 
+		   false, true);
+  register_pragma (pfile, "GCC", "dependency", do_pragma_dependency, 
+		   false, true);
 }
 
 /* Return the number of registered pragmas in PE.  */
@@ -1176,7 +1185,11 @@ do_pragma (cpp_reader *pfile)
 	     numbers in place.  */
 	  if (pfile->cb.line_change)
 	    (*pfile->cb.line_change) (pfile, pragma_token, false);
+	  if (p->allow_expansion && !pfile->state.in_deferred_pragma)
+	    pfile->state.prevent_expansion--;
 	  (*p->u.handler) (pfile);
+	  if (p->allow_expansion && !pfile->state.in_deferred_pragma)
+	    pfile->state.prevent_expansion++;
 	}
       else
 	{
@@ -1430,6 +1443,7 @@ cpp_handle_deferred_pragma (cpp_reader *
   pfile->context->macro = 0;
   pfile->context->prev = 0;
   pfile->cb.line_change = NULL;
+  pfile->state.in_deferred_pragma = true;
   CPP_OPTION (pfile, defer_pragmas) = false;
 
   run_directive (pfile, T_PRAGMA, (const char *)s->text, s->len);
@@ -1439,6 +1453,7 @@ cpp_handle_deferred_pragma (cpp_reader *
   pfile->cur_token = saved_cur_token;
   pfile->cur_run = saved_cur_run;
   pfile->cb.line_change = saved_line_change;
+  pfile->state.in_deferred_pragma = false;
   CPP_OPTION (pfile, defer_pragmas) = saved_defer_pragmas;
 }
 
--- GCC.orig/libcpp/internal.h	2004-11-05 00:33:56.000000000 +0000
+++ GCC/libcpp/internal.h	2004-11-23 16:26:30.000000000 +0000
@@ -205,6 +205,9 @@ struct lexer_state
   /* Nonzero to prevent macro expansion.  */
   unsigned char prevent_expansion;
 
+  /* Nonzero when handling a deferred pragma.  */
+  unsigned char in_deferred_pragma;
+
   /* Nonzero when parsing arguments to a function-like macro.  */
   unsigned char parsing_args;
 
diff -rupN -x CVS gcc-merge-HEAD-csl-sol210-1/libcpp/include/cpplib.h gcc-sol210/libcpp/include/cpplib.h
--- gcc-merge-HEAD-csl-sol210-1/libcpp/include/cpplib.h	2004-09-09 12:16:56.000000000 -0700
+++ gcc-sol210/libcpp/include/cpplib.h	2004-09-27 08:45:17.000000000 -0700
@@ -638,7 +638,7 @@ extern unsigned char *cpp_token_as_text 
 extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *,
 				       unsigned char *);
 extern void cpp_register_pragma (cpp_reader *, const char *, const char *,
-				 void (*) (cpp_reader *));
+				 void (*) (cpp_reader *), bool);
 extern void cpp_handle_deferred_pragma (cpp_reader *, const cpp_string *);
 extern int cpp_avoid_paste (cpp_reader *, const cpp_token *,
 			    const cpp_token *);

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)


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