re PR preprocessor/60570 (expression in 'elif' directive mis-diagnosed as error when...
authorMarek Polacek <polacek@redhat.com>
Fri, 23 Jan 2015 11:57:43 +0000 (11:57 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 23 Jan 2015 11:57:43 +0000 (11:57 +0000)
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

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/pr36320.c
gcc/testsuite/gcc.dg/cpp/pr60570.c [new file with mode: 0644]
libcpp/ChangeLog
libcpp/directives.c

index 86753d6fc1dd373a64174c8fc50110e4e99dd67e..cf9b478268bd28e5c56002fdfdf17976bf631c34 100644 (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
index d136a69b6b2db2d2630553f0108bdeef0a6a2486..cc2baa73e1fb2f44045bc534b678db9b8522d91c 100644 (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
diff --git a/gcc/testsuite/gcc.dg/cpp/pr60570.c b/gcc/testsuite/gcc.dg/cpp/pr60570.c
new file mode 100644 (file)
index 0000000..4755206
--- /dev/null
@@ -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
index 232516194728e878ad01fa070ac52f92e2655444..41aa56fa9c3b506657ffbd17275b74754814dae5 100644 (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
index ab4f15c5bd79774f090163ecfc715e1dca63ebb0..37cd109ed8a249ce17e2a440303d6c8f3c88d487 100644 (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.  */