This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C PATCH] Better diagnostics for C++ comments in C90 (PR c/61854)
- From: Marek Polacek <polacek at redhat dot com>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 17 Sep 2014 21:14:35 +0200
- Subject: Re: [C PATCH] Better diagnostics for C++ comments in C90 (PR c/61854)
- Authentication-results: sourceware.org; auth=none
- References: <20140915171617 dot GG23226 at redhat dot com> <Pine dot LNX dot 4 dot 64 dot 1409151742130 dot 16736 at digraph dot polyomino dot org dot uk> <20140915210035 dot GH23226 at redhat dot com> <Pine dot LNX dot 4 dot 64 dot 1409162227460 dot 4182 at digraph dot polyomino dot org dot uk>
On Tue, Sep 16, 2014 at 10:32:51PM +0000, Joseph S. Myers wrote:
> This is getting closer, but it looks like you still treat it as a line
> comment when being skipped for C90, when actually it's not safe to treat
> it like that; you have to produce a '/' preprocessing token and continue
> tokenizing the rest of the line. Consider the following code:
>
> int i = 0
> #if 0
> // /*
> #else
> // */
> +1
> #endif
> ;
>
> For C90 i gets value 0. With // comments it gets value 1.
Aha. I made a thinko, hopefully fixed now. I added two new tests
(it's definitely good to have more testing in this area!) based on
your code, thanks for that.
> > + /* In C89/C94, C++ style comments are forbidden. */
> > + else if ((CPP_OPTION (pfile, lang) == CLK_STDC89
> > + || CPP_OPTION (pfile, lang) == CLK_STDC94))
> > + {
> > + /* But don't be confused about // immediately followed by *. */
> > + if (buffer->cur[1] == '*'
> > + || pfile->state.in_directive)
>
> And this comment needs updating to reflect that it's not just //* where //
> can appear in valid C90 code in a way incompatible with treating it as a
> comment.
Sure, updated.
Bootstrap in progress, regtested on x86_64-linux, ok for trunk?
2014-09-17 Marek Polacek <polacek@redhat.com>
PR c/61854
libcpp/
* init.c (struct lang_flags): Remove cplusplus_comments.
(cpp_set_lang): Likewise.
(post_options): Likewise.
* lex.c (_cpp_lex_direct): Disallow C++ style comments in C90/C94.
testsuite/
* gcc.dg/cpp/pr61854-1.c: New test.
* gcc.dg/cpp/pr61854-2.c: New test.
* gcc.dg/cpp/pr61854-3.c: New test.
* gcc.dg/cpp/pr61854-3.h: New test.
* gcc.dg/cpp/pr61854-4.c: New test.
* gcc.dg/cpp/pr61854-5.c: New test.
* gcc.dg/cpp/pr61854-6.c: New test.
* gcc.dg/cpp/pr61854-7.c: New test.
* gcc.dg/cpp/pr61854-c90.c: New test.
* gcc.dg/cpp/pr61854-c94.c: New test.
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-1.c gcc/gcc/testsuite/gcc.dg/cpp/pr61854-1.c
index e69de29..364a511 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-1.c
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-1.c
@@ -0,0 +1,15 @@
+/* PR c/61854 */
+/* { dg-do run } */
+/* { dg-options "-std=c89" } */
+
+int
+main (void)
+{
+ int i = 1 //**/ 2
+ ;
+ int j = 1 //**/ 2
+ ;
+ if (i != 0 || j != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-2.c gcc/gcc/testsuite/gcc.dg/cpp/pr61854-2.c
index e69de29..883db21 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-2.c
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-2.c
@@ -0,0 +1,15 @@
+/* PR c/61854 */
+/* { dg-do run } */
+/* { dg-options "-std=gnu89" } */
+
+int
+main (void)
+{
+ int i = 1 //**/ 2
+ ;
+ int j = 1 //**/ 2
+ ;
+ if (i != 1 || j != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-3.c gcc/gcc/testsuite/gcc.dg/cpp/pr61854-3.c
index e69de29..916c12e 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-3.c
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-3.c
@@ -0,0 +1,6 @@
+/* PR c/61854 */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c89" } */
+
+#include "pr61854-3.h"
+int i;
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-3.h gcc/gcc/testsuite/gcc.dg/cpp/pr61854-3.h
index e69de29..fd798bd 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-3.h
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-3.h
@@ -0,0 +1,4 @@
+#pragma GCC system_header
+// X
+// Y
+// Z
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-4.c gcc/gcc/testsuite/gcc.dg/cpp/pr61854-4.c
index e69de29..5cfa5a7 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-4.c
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-4.c
@@ -0,0 +1,16 @@
+/* PR c/61854 */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c89" } */
+
+void
+foo (void)
+{
+#if 0
+ // Do not error here.
+#endif
+#if 1
+ // But error here.
+#endif
+ /* { dg-error "C\\+\\+ style comments are not allowed in ISO C90" "comments" { target *-*-*} 12 } */
+ /* { dg-error "reported only once" "" { target *-*-*} 12 } */
+}
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-5.c gcc/gcc/testsuite/gcc.dg/cpp/pr61854-5.c
index e69de29..a7628dc 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-5.c
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-5.c
@@ -0,0 +1,15 @@
+/* PR c/61854 */
+/* { dg-do run } */
+/* { dg-options "-std=c89" } */
+
+#define h(x) #x
+#define s(x) h(x)
+#define foo //
+
+int
+main (void)
+{
+ if (__builtin_memcmp (s(foo), "//", 3) != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-6.c gcc/gcc/testsuite/gcc.dg/cpp/pr61854-6.c
index e69de29..1b60cc3 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-6.c
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-6.c
@@ -0,0 +1,19 @@
+/* PR c/61854 */
+/* { dg-do run } */
+/* { dg-options "-std=gnu89" } */
+
+int
+main (void)
+{
+ int i = 0
+#if 0
+// /*
+#else
+// */
++1
+#endif
+;
+ if (i != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-7.c gcc/gcc/testsuite/gcc.dg/cpp/pr61854-7.c
index e69de29..8bf479b 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-7.c
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-7.c
@@ -0,0 +1,19 @@
+/* PR c/61854 */
+/* { dg-do run } */
+/* { dg-options "-std=c89" } */
+
+int
+main (void)
+{
+ int i = 0
+#if 0
+// /*
+#else
+// */
++1
+#endif
+;
+ if (i != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-c90.c gcc/gcc/testsuite/gcc.dg/cpp/pr61854-c90.c
index e69de29..37eecbe 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-c90.c
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-c90.c
@@ -0,0 +1,13 @@
+/* PR c/61854 */
+/* { dg-do preprocess } */
+/* { dg-options "-std=iso9899:1990" } */
+
+void
+foo (void)
+{
+ // 1st
+ /* { dg-error "C\\+\\+ style comments are not allowed in ISO C90" "comments" { target *-*-*} 8 } */
+ /* { dg-error "reported only once" "" { target *-*-*} 8 } */
+ // 2nd
+ // 3rd
+}
diff --git gcc/gcc/testsuite/gcc.dg/cpp/pr61854-c94.c gcc/gcc/testsuite/gcc.dg/cpp/pr61854-c94.c
index e69de29..64f1e18 100644
--- gcc/gcc/testsuite/gcc.dg/cpp/pr61854-c94.c
+++ gcc/gcc/testsuite/gcc.dg/cpp/pr61854-c94.c
@@ -0,0 +1,13 @@
+/* PR c/61854 */
+/* { dg-do preprocess } */
+/* { dg-options "-std=iso9899:199409" } */
+
+void
+foo (void)
+{
+ // 1st
+ /* { dg-error "C\\+\\+ style comments are not allowed in ISO C90" "comments" { target *-*-*} 8 } */
+ /* { dg-error "reported only once" "" { target *-*-*} 8 } */
+ // 2nd
+ // 3rd
+}
diff --git gcc/libcpp/init.c gcc/libcpp/init.c
index d612374..1121962 100644
--- gcc/libcpp/init.c
+++ gcc/libcpp/init.c
@@ -83,7 +83,6 @@ struct lang_flags
char extended_identifiers;
char c11_identifiers;
char std;
- char cplusplus_comments;
char digraphs;
char uliterals;
char rliterals;
@@ -94,23 +93,23 @@ struct lang_flags
};
static const struct lang_flags lang_defaults[] =
-{ /* c99 c++ xnum xid c11 std // digr ulit rlit udlit bincst digsep trig */
- /* GNUC89 */ { 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
- /* GNUC99 */ { 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
- /* GNUC11 */ { 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
- /* STDC89 */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 },
- /* STDC94 */ { 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1 },
- /* STDC99 */ { 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
- /* STDC11 */ { 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 },
- /* GNUCXX */ { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
- /* CXX98 */ { 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
- /* GNUCXX11 */ { 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0 },
- /* CXX11 */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1 },
- /* GNUCXX14 */ { 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0 },
- /* CXX14 */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- /* GNUCXX1Z */ { 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0 },
- /* CXX1Z */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
- /* ASM */ { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }
+{ /* c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig */
+ /* GNUC89 */ { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ /* GNUC99 */ { 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 },
+ /* GNUC11 */ { 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 },
+ /* STDC89 */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
+ /* STDC94 */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1 },
+ /* STDC99 */ { 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1 },
+ /* STDC11 */ { 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1 },
+ /* GNUCXX */ { 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ /* CXX98 */ { 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1 },
+ /* GNUCXX11 */ { 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0 },
+ /* CXX11 */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1 },
+ /* GNUCXX14 */ { 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0 },
+ /* CXX14 */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ /* GNUCXX1Z */ { 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0 },
+ /* CXX1Z */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ /* ASM */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
/* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX11, CXX11,
GNUCXX14, and CXX14 when no longer experimental (when all uses of
identifiers in the compiler have been audited for correct handling
@@ -131,7 +130,6 @@ cpp_set_lang (cpp_reader *pfile, enum c_lang lang)
CPP_OPTION (pfile, extended_identifiers) = l->extended_identifiers;
CPP_OPTION (pfile, c11_identifiers) = l->c11_identifiers;
CPP_OPTION (pfile, std) = l->std;
- CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments;
CPP_OPTION (pfile, digraphs) = l->digraphs;
CPP_OPTION (pfile, uliterals) = l->uliterals;
CPP_OPTION (pfile, rliterals) = l->rliterals;
@@ -775,8 +773,6 @@ post_options (cpp_reader *pfile)
if (CPP_OPTION (pfile, traditional))
{
- CPP_OPTION (pfile, cplusplus_comments) = 0;
-
CPP_OPTION (pfile, trigraphs) = 0;
CPP_OPTION (pfile, warn_trigraphs) = 0;
}
diff --git gcc/libcpp/lex.c gcc/libcpp/lex.c
index 5366dad..8f75851 100644
--- gcc/libcpp/lex.c
+++ gcc/libcpp/lex.c
@@ -2322,13 +2322,16 @@ _cpp_lex_direct (cpp_reader *pfile)
if (_cpp_skip_block_comment (pfile))
cpp_error (pfile, CPP_DL_ERROR, "unterminated comment");
}
- else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments)
- || cpp_in_system_header (pfile)))
+ else if (c == '/' && ! CPP_OPTION (pfile, traditional))
{
+ /* Don't warn for system headers. */
+ if (cpp_in_system_header (pfile))
+ ;
/* Warn about comments if pedantically GNUC89, and not
in system headers. */
- if (CPP_OPTION (pfile, lang) == CLK_GNUC89 && CPP_PEDANTIC (pfile)
- && ! buffer->warned_cplusplus_comments)
+ else if (CPP_OPTION (pfile, lang) == CLK_GNUC89
+ && CPP_PEDANTIC (pfile)
+ && ! buffer->warned_cplusplus_comments)
{
cpp_error (pfile, CPP_DL_PEDWARN,
"C++ style comments are not allowed in ISO C90");
@@ -2347,7 +2350,31 @@ _cpp_lex_direct (cpp_reader *pfile)
"(this will be reported only once per input file)");
buffer->warned_cplusplus_comments = 1;
}
-
+ /* In C89/C94, C++ style comments are forbidden. */
+ else if ((CPP_OPTION (pfile, lang) == CLK_STDC89
+ || CPP_OPTION (pfile, lang) == CLK_STDC94))
+ {
+ /* But don't be confused about valid code such as
+ - // immediately followed by *,
+ - // in a preprocessing directive,
+ - // in an #if 0 block. */
+ if (buffer->cur[1] == '*'
+ || pfile->state.in_directive
+ || pfile->state.skipping)
+ {
+ result->type = CPP_DIV;
+ break;
+ }
+ else if (! buffer->warned_cplusplus_comments)
+ {
+ cpp_error (pfile, CPP_DL_ERROR,
+ "C++ style comments are not allowed in ISO C90");
+ cpp_error (pfile, CPP_DL_ERROR,
+ "(this will be reported only once per input "
+ "file)");
+ buffer->warned_cplusplus_comments = 1;
+ }
+ }
if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments))
cpp_warning (pfile, CPP_W_COMMENTS, "multi-line comment");
}
Marek