re PR preprocessor/60570 (expression in 'elif' directive mis-diagnosed as error when group will be skipped)

DR#412
	PR preprocessor/60570
	* directives.c (do_elif): Don't evaluate #elif conditionals
	when they don't need to be.

	* gcc.dg/cpp/pr36320.c: Turn dg-error into dg-bogus.
	* gcc.dg/cpp/pr60570.c: New test.

From-SVN: r220035
This commit is contained in:
Marek Polacek 2015-01-23 11:57:43 +00:00 committed by Marek Polacek
parent b0edd457a1
commit 10ef8f287e
5 changed files with 72 additions and 18 deletions

View File

@ -1,3 +1,9 @@
2015-01-23 Marek Polacek <polacek@redhat.com>
PR preprocessor/60570
* gcc.dg/cpp/pr36320.c: Turn dg-error into dg-bogus.
* gcc.dg/cpp/pr60570.c: New test.
2015-01-23 Richard Biener <rguenther@suse.de>
PR testsuite/63439

View File

@ -1,8 +1,8 @@
/* PR 36320 - #elif still requires valid expression. */
/* DR#412: #elif doesn't have to be valid expression (PR60570). */
/* { dg-do preprocess } */
int z;
#if 1
#elif /* { dg-error "with no expression" } */
#elif /* { dg-bogus "with no expression" } */
#endif

View File

@ -0,0 +1,48 @@
/* PR preprocessor/60570 */
/* { dg-do preprocess } */
#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 1
int l;
# elif
# endif
#endif
#if 1
# if 0
# elif 1/0 /* { dg-error "division by zero" } */
# endif
#endif
#if 1
# if 0
# elif /* { dg-error "with no expression" } */
# endif
#endif

View File

@ -1,3 +1,10 @@
2015-01-23 Marek Polacek <polacek@redhat.com>
DR#412
PR preprocessor/60570
* directives.c (do_elif): Don't evaluate #elif conditionals
when they don't need to be.
2015-01-16 Jakub Jelinek <jakub@redhat.com>
* expr.c (cpp_classify_number): Add N_() around ?: string

View File

@ -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. */