This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug preprocessor/60570] expression in 'elif' directive mis-diagnosed as error when group will be skipped
- From: "mpolacek at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 22 Jan 2015 09:37:15 +0000
- Subject: [Bug preprocessor/60570] expression in 'elif' directive mis-diagnosed as error when group will be skipped
- Auto-submitted: auto-generated
- References: <bug-60570-4 at http dot gcc dot gnu dot org/bugzilla/>
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