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]

Patch: FYI: fix PR preprocessor/36320


I'm checking this in.

This patch fixes PR preprocessor/36320.  The bug here is that an
#elif's expression is required to be syntactically correct if the
overall group is not being skipped.  libcpp was not enforcing this
requirement.

Test case included.  Bootstrapped and regtested on the compile farm
(x86-64).

Tom

gcc/testsuite/ChangeLog:
2008-05-30  Tom Tromey  <tromey@redhat.com>

	PR preprocessor/36320:
	* gcc.dg/cpp/pr36320.c: New file.

libcpp/ChangeLog:
2008-05-30  Tom Tromey  <tromey@redhat.com>

	PR preprocessor/36320:
	* internal.h (_cpp_parse_expr): Update.
	* expr.c (_cpp_parse_expr): Add 'is_if' argument.  Update error
	messages.
	* directives.c (do_if): Update.
	(do_elif): Require expression if processing group.

Index: gcc/testsuite/gcc.dg/cpp/pr36320.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/pr36320.c	(revision 0)
+++ gcc/testsuite/gcc.dg/cpp/pr36320.c	(revision 0)
@@ -0,0 +1,8 @@
+/* PR 36320 - #elif still requires valid expression.  */
+
+/* { dg-do preprocess } */
+
+int z;
+#if 1
+#elif   /* { dg-error "with no expression" } */
+#endif
Index: libcpp/directives.c
===================================================================
--- libcpp/directives.c	(revision 136189)
+++ libcpp/directives.c	(working copy)
@@ -1737,7 +1737,7 @@
   int skip = 1;
 
   if (! pfile->state.skipping)
-    skip = _cpp_parse_expr (pfile) == false;
+    skip = _cpp_parse_expr (pfile, true) == false;
 
   push_conditional (pfile, skip, T_IF, pfile->mi_ind_cmacro);
 }
@@ -1796,15 +1796,23 @@
 	}
       ifs->type = T_ELIF;
 
-      /* Only evaluate this if we aren't skipping elses.  During
-	 evaluation, set skipping to false to get lexer warnings.  */
-      if (ifs->skip_elses)
-	pfile->state.skipping = 1;
-      else
+      if (! ifs->was_skipping)
 	{
+	  bool value;
+	  /* The standard mandates that the expression be parsed even
+	     if we are skipping elses at this point -- the lexical
+	     restrictions on #elif only apply to skipped groups, but
+	     this group is not being skipped.  Temporarily set
+	     skipping to false to get lexer warnings.  */
 	  pfile->state.skipping = 0;
-	  pfile->state.skipping = ! _cpp_parse_expr (pfile);
-	  ifs->skip_elses = ! pfile->state.skipping;
+	  value = _cpp_parse_expr (pfile, false);
+	  if (ifs->skip_elses)
+	    pfile->state.skipping = 1;
+	  else
+	    {
+	      pfile->state.skipping = ! value;
+	      ifs->skip_elses = value;
+	    }
 	}
 
       /* Invalidate any controlling macro.  */
Index: libcpp/expr.c
===================================================================
--- libcpp/expr.c	(revision 136189)
+++ libcpp/expr.c	(working copy)
@@ -852,7 +852,7 @@
    stored in the 'value' field of the stack element of the operator
    that precedes it.  */
 bool
-_cpp_parse_expr (cpp_reader *pfile)
+_cpp_parse_expr (cpp_reader *pfile, bool is_if)
 {
   struct op *top = pfile->op_stack;
   unsigned int lex_count;
@@ -927,7 +927,7 @@
 	    SYNTAX_ERROR ("missing expression between '(' and ')'");
 
 	  if (op.op == CPP_EOF && top->op == CPP_EOF)
- 	    SYNTAX_ERROR ("#if with no expression");
+ 	    SYNTAX_ERROR2 ("%s with no expression", is_if ? "#if" : "#elif");
 
  	  if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
  	    SYNTAX_ERROR2 ("operator '%s' has no right operand",
@@ -988,7 +988,8 @@
 
   if (top != pfile->op_stack)
     {
-      cpp_error (pfile, CPP_DL_ICE, "unbalanced stack in #if");
+      cpp_error (pfile, CPP_DL_ICE, "unbalanced stack in %s",
+		 is_if ? "#if" : "#elif");
     syntax_error:
       return false;  /* Return false on syntax error.  */
     }
Index: libcpp/internal.h
===================================================================
--- libcpp/internal.h	(revision 136189)
+++ libcpp/internal.h	(working copy)
@@ -557,7 +557,7 @@
 extern struct stat *_cpp_get_file_stat (_cpp_file *);
 
 /* In expr.c */
-extern bool _cpp_parse_expr (cpp_reader *);
+extern bool _cpp_parse_expr (cpp_reader *, bool);
 extern struct op *_cpp_expand_op_stack (cpp_reader *);
 
 /* In lex.c */


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