This is the mail archive of the gcc-bugs@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]

[Bug preprocessor/60570] expression in 'elif' directive mis-diagnosed as error when group will be skipped


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60570

--- Comment #6 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
It would appear so, in which case the following (untested, only quick hack)
should work:

diff --git a/gcc/testsuite/gcc.dg/cpp/pr36320.c
b/gcc/testsuite/gcc.dg/cpp/pr36320.c
index d136a69..ebd5191 100644
--- a/gcc/testsuite/gcc.dg/cpp/pr36320.c
+++ b/gcc/testsuite/gcc.dg/cpp/pr36320.c
@@ -4,5 +4,5 @@

 int z;
 #if 1
-#elif   /* { dg-error "with no expression" } */
+#elif
 #endif
diff --git a/libcpp/directives.c b/libcpp/directives.c
index ab4f15c..37cd109 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -2036,23 +2036,16 @@ do_elif (cpp_reader *pfile)
     }
       ifs->type = T_ELIF;

-      if (! ifs->was_skipping)
+      /* See DR#412: "Only the first group whose control condition
+     evaluates to true (nonzero) is processed; any following groups
+     are skipped and their controlling directives are processed as
+     if they were in a group that is skipped."  */
+      if (ifs->skip_elses)
+    pfile->state.skipping = 1;
+      else
     {
-      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;
-      value = _cpp_parse_expr (pfile, false);
-      if (ifs->skip_elses)
-        pfile->state.skipping = 1;
-      else
-        {
-          pfile->state.skipping = ! value;
-          ifs->skip_elses = value;
-        }
+      pfile->state.skipping = ! _cpp_parse_expr (pfile, false);
+      ifs->skip_elses = ! pfile->state.skipping;
     }

       /* Invalidate any controlling macro.  */

together with a test like the following

#if 1
int i;
#elif 1/0
#endif

#if 1
int j;
#elif
#endif

#if 0
#elif 1/0    /* { dg-error "division by zero" } */
int k;
#endif

#if 0
#elif        /* { dg-error "with no expression" } */
int n;
#endif

#if 1
# if 1
int l;
# elif 1/0
# endif
#endif

#if 1
# if 0
# elif 1/0    /* { dg-error "division by zero" } */
# endif
#endif


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