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]

[patch] Re: preprocessor/2706: #defines expanded when -fpreprocessed given


Here's a revised patch which incorporates Neil's suggestions.

It breaks c-torture/execute/920730-1t.c.  The traditional preprocessor
doesn't recognize #include_next (in our limits.h), and passes it
through to the compiler, which rejects it.  Options here include: get
rid of our limits.h when the system one is fine (my personal
favorite); teach tradcpp about #include_next (may be a good idea
anyway); teach tradcpp to discard the line when it doesn't recognize a
directive (difficult).

All of them, unfortunately, require a lot of hacking of old grotty
code.

zw

	* cppinit.c (cpp_post_options): Bump state.prevent_expansion
	if -fpreprocessed.
	* cpplib.c (_cpp_handle_directive): In preprocessed text,
	accept only directives where neither the # nor the name has
	been indented, and # <number> markers.  Pass all others
	through to caller.
	* cppmain.c (scan_buffer): Insert a space between a # and
	a directive name.

===================================================================
Index: cppinit.c
--- cppinit.c	2001/04/09 22:07:24	1.147.2.7
+++ cppinit.c	2001/05/04 02:17:09
@@ -1716,6 +1716,11 @@ cpp_post_options (pfile)
   if (CPP_OPTION (pfile, user_label_prefix) == NULL)
     CPP_OPTION (pfile, user_label_prefix) = USER_LABEL_PREFIX;
 
+  /* Permanently disable macro expansion if we are rescanning
+     preprocessed text.  */
+  if (CPP_OPTION (pfile, preprocessed))
+    pfile->state.prevent_expansion = 1;
+
   /* We need to do this after option processing and before
      cpp_start_read, as cppmain.c relies on the options->no_output to
      set its callbacks correctly before calling cpp_start_read.  */
===================================================================
Index: cpplib.c
--- cpplib.c	2001/04/11 19:33:55	1.239.2.6
+++ cpplib.c	2001/05/04 02:17:10
@@ -312,7 +312,32 @@ _cpp_handle_directive (pfile, indented)
 
       /* If we are rescanning preprocessed input, only directives tagged
 	 with IN_I are honored, and the warnings below are suppressed.  */
-      if (! CPP_OPTION (pfile, preprocessed) || dir->flags & IN_I)
+      if (CPP_OPTION (pfile, preprocessed))
+	{
+	  /* Kluge alert.  In order to be sure that code like this
+	     #define HASH #
+	     HASH define foo bar
+	     does not cause '#define foo bar' to get executed when
+	     compiled with -save-temps, we recognize directives in
+	     -fpreprocessed mode only if the # is in column 1 and the
+	     directive name starts in column 2.  This output can only
+	     be generated by the directive callbacks in cppmain.c (see
+	     also the special case in scan_buffer).  */
+	  if (dir->flags & IN_I && !indented && !(dname.flags & PREV_WHITE))
+	    (*dir->handler) (pfile);
+	  /* That check misses '# 123' linemarkers.  Let them through too.  */
+	  else if (dname.type == CPP_NUMBER)
+	    (*dir->handler) (pfile);
+	  else
+	    {
+	      /* We don't want to process this directive.  Put back the
+		 tokens so caller will see them (and issue an error,
+		 probably).  */
+	      _cpp_push_token (pfile, &dname, &pfile->directive_pos);
+	      skip = 0;
+	    }
+	}
+      else
 	{
 	  /* Traditionally, a directive is ignored unless its # is in
 	     column 1.  Therefore in code intended to work with K+R
===================================================================
Index: cppmain.c
--- cppmain.c	2001/03/27 06:39:40	1.61.2.2
+++ cppmain.c	2001/05/04 02:17:10
@@ -238,6 +238,13 @@ scan_buffer (pfile)
 		       == AVOID_LPASTE
 		   && cpp_avoid_paste (pfile, &tokens[1 - index], token))
 	    token->flags |= PREV_WHITE;
+	  /* Special case '# <directive name>': insert a space between
+	     the # and the token.  This will prevent it from being
+	     treated as a directive when this code is re-preprocessed.
+	     XXX Should do this only at the beginning of a line, but how?  */
+	  else if (token->type == CPP_NAME && token->val.node->directive_index
+		   && tokens[1 - index].type == CPP_HASH)
+	    token->flags |= PREV_WHITE;
 
 	  cpp_output_token (token, print.outf);
 	  print.printed = 1;


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