diff options
author | Joseph Myers <joseph@codesourcery.com> | 2019-10-02 01:08:40 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2019-10-02 01:08:40 +0100 |
commit | 93313b94fe18f3c3de4f24f5bb3fafb4639f1c7e (patch) | |
tree | cf9d4a06b2f7e0356d2c66aaa9d1e6dd410e538a /gcc | |
parent | e9c9a142b49d069c5b7c24d47b07756e9d591956 (diff) | |
download | gcc-93313b94fe18f3c3de4f24f5bb3fafb4639f1c7e.zip gcc-93313b94fe18f3c3de4f24f5bb3fafb4639f1c7e.tar.gz gcc-93313b94fe18f3c3de4f24f5bb3fafb4639f1c7e.tar.bz2 |
Handle :: tokens in C for C2x.
As part of adding [[]]-style attributes, C2x adds the token :: for use
in scoped attribute names.
This patch adds corresponding support for that token in C to GCC. The
token is supported both for C2x and for older gnu* standards (on the
basis that extensions are normally supported in older gnu* versions;
people will expect to be able to use [[]] attributes, before C2x is
the default, without needing to use -std=gnu2x).
There are no cases in older C standards where the token : can be
followed by a token starting with : in syntactically valid sources;
the only cases the :: token could break in older standard C thus are
ones involving concatenation of pp-tokens where the result does not
end up as tokens (e.g., gets stringized). In GNU C extensions, the
main case where :: might appear in existing sources is in asm
statements, and the C parser is thus made to handle it like two
consecutive : tokens, which the C++ parser already does. A limited
test of various positionings of :: in asm statements is added to the
testsuite (in particular, to cover the syntax error when :: means too
many colons but a single : would be OK), but existing tests cover a
variety of styles there anyway.
Technically there are cases in Objective-C and OpenMP for which this
also changes how previously valid code is lexed: the objc-selector-arg
syntax allows multiple consecutive : tokens (although I don't think
they are particularly useful there), while OpenMP syntax includes
array section syntax such as [:] which, before :: was a token, could
also be written as [::> (there might be other OpenMP cases potentially
affected, I didn't check all the OpenMP syntax in detail). I don't
think either of those cases affects the basis for supporting the ::
token in all -std=gnu* modes, or that there is any obvious need to
special-case handling of CPP_SCOPE tokens for those constructs the way
there is for asm statements.
cpp_avoid_paste, which determines when spaces need adding between
tokens in preprocessed output where there wouldn't otherwise be
whitespace between them (e.g. if stringized), already inserts space
between : and : unconditionally, rather than only for C++, so no
change is needed there (but a C2x test is added that such space is
indeed inserted).
Bootstrapped with no regressions on x86-64-pc-linux-gnu.
gcc/c:
* c-parser.c (c_parser_asm_statement): Handle CPP_SCOPE like two
CPP_COLON tokens.
gcc/testsuite:
* gcc.dg/asm-scope-1.c, gcc.dg/cpp/c11-scope-1.c,
gcc.dg/cpp/c17-scope-1.c, gcc.dg/cpp/c2x-scope-1.c,
gcc.dg/cpp/c2x-scope-2.c, gcc.dg/cpp/c90-scope-1.c,
gcc.dg/cpp/c94-scope-1.c, gcc.dg/cpp/c99-scope-1.c,
gcc.dg/cpp/gnu11-scope-1.c, gcc.dg/cpp/gnu17-scope-1.c,
gcc.dg/cpp/gnu89-scope-1.c, gcc.dg/cpp/gnu99-scope-1.c: New tests.
libcpp:
* include/cpplib.h (struct cpp_options): Add member scope.
* init.c (struct lang_flags, lang_defaults): Likewise.
(cpp_set_lang): Set scope member of pfile.
* lex.c (_cpp_lex_direct): Test CPP_OPTION (pfile, scope) not
CPP_OPTION (pfile, cplusplus) for creating CPP_SCOPE tokens.
From-SVN: r276434
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/asm-scope-1.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/c11-scope-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/c17-scope-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/c2x-scope-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/c2x-scope-2.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/c90-scope-1.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/c94-scope-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/c99-scope-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/gnu11-scope-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/gnu17-scope-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/gnu89-scope-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/gnu99-scope-1.c | 8 |
15 files changed, 150 insertions, 6 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 3156e35..0f263f7 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2019-10-02 Joseph Myers <joseph@codesourcery.com> + + * c-parser.c (c_parser_asm_statement): Handle CPP_SCOPE like two + CPP_COLON tokens. + 2019-10-01 Richard Sandiford <richard.sandiford@arm.com> * c-objc-common.c (useful_aka_type_p): New function. diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index c8afab2..6957297 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -6411,7 +6411,9 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, The form with asm-goto-operands is valid if and only if the asm-qualifier-list contains goto, and is the only allowed form in that case. - Duplicate asm-qualifiers are not allowed. */ + Duplicate asm-qualifiers are not allowed. + + The :: token is considered equivalent to two consecutive : tokens. */ static tree c_parser_asm_statement (c_parser *parser) @@ -6509,17 +6511,28 @@ c_parser_asm_statement (c_parser *parser) nsections = 3 + is_goto; for (section = 0; section < nsections; ++section) { - if (!c_parser_require (parser, CPP_COLON, - is_goto - ? G_("expected %<:%>") - : G_("expected %<:%> or %<)%>"), - UNKNOWN_LOCATION, is_goto)) + if (c_parser_next_token_is (parser, CPP_SCOPE)) + { + ++section; + if (section == nsections) + { + c_parser_error (parser, "expected %<)%>"); + goto error_close_paren; + } + c_parser_consume_token (parser); + } + else if (!c_parser_require (parser, CPP_COLON, + is_goto + ? G_("expected %<:%>") + : G_("expected %<:%> or %<)%>"), + UNKNOWN_LOCATION, is_goto)) goto error_close_paren; /* Once past any colon, we're no longer a simple asm. */ simple = false; if ((!c_parser_next_token_is (parser, CPP_COLON) + && !c_parser_next_token_is (parser, CPP_SCOPE) && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) || section == 3) switch (section) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5949f0a..834ee45 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2019-10-02 Joseph Myers <joseph@codesourcery.com> + + * gcc.dg/asm-scope-1.c, gcc.dg/cpp/c11-scope-1.c, + gcc.dg/cpp/c17-scope-1.c, gcc.dg/cpp/c2x-scope-1.c, + gcc.dg/cpp/c2x-scope-2.c, gcc.dg/cpp/c90-scope-1.c, + gcc.dg/cpp/c94-scope-1.c, gcc.dg/cpp/c99-scope-1.c, + gcc.dg/cpp/gnu11-scope-1.c, gcc.dg/cpp/gnu17-scope-1.c, + gcc.dg/cpp/gnu89-scope-1.c, gcc.dg/cpp/gnu99-scope-1.c: New tests. + 2019-10-01 David Malcolm <dmalcolm@redhat.com> * gcc.dg/plugin/diagnostic_group_plugin.c (test_begin_group_cb): diff --git a/gcc/testsuite/gcc.dg/asm-scope-1.c b/gcc/testsuite/gcc.dg/asm-scope-1.c new file mode 100644 index 0000000..6439104 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asm-scope-1.c @@ -0,0 +1,27 @@ +/* Test :: token handling in asm. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu2x" } */ + +void +f (void) +{ + asm (""); + asm ("" : ); + asm ("" : :); + asm ("" ::); + asm ("" : : :); + asm ("" :: :); + asm ("" : ::); + asm goto ("" : : : : lab); + asm goto ("" :: : : lab); + asm goto ("" : :: : lab); + asm goto ("" : : :: lab); + asm goto ("" :: :: lab); + lab: ; + /* Test errors when :: is at the end of asm and only one : allowed. */ + asm ("" : : ::); /* { dg-error "expected" } */ + asm ("" :: ::); /* { dg-error "expected" } */ + asm goto ("" : : : :: lab); /* { dg-error "expected" } */ + asm goto ("" :: : :: lab); /* { dg-error "expected" } */ + asm goto ("" : :: :: lab); /* { dg-error "expected" } */ +} diff --git a/gcc/testsuite/gcc.dg/cpp/c11-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c11-scope-1.c new file mode 100644 index 0000000..2db0516 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c11-scope-1.c @@ -0,0 +1,8 @@ +/* Test :: token not in C11. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */ +CONCAT (::, >) diff --git a/gcc/testsuite/gcc.dg/cpp/c17-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c17-scope-1.c new file mode 100644 index 0000000..b5b366b --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c17-scope-1.c @@ -0,0 +1,8 @@ +/* Test :: token not in C17. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c17 -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */ +CONCAT (::, >) diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c2x-scope-1.c new file mode 100644 index 0000000..8337ba7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c2x-scope-1.c @@ -0,0 +1,8 @@ +/* Test :: token in C2x. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) +CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */ diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-scope-2.c b/gcc/testsuite/gcc.dg/cpp/c2x-scope-2.c new file mode 100644 index 0000000..73b36e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c2x-scope-2.c @@ -0,0 +1,11 @@ +/* Test :: token in C2x: preprocessed output. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c2x -pedantic-errors -P" } */ + +#define COLON() : +#define TEST() ABC + +/* This must have a space inserted between the two ':' tokens in + preprocessed output. */ +TEST()COLON()COLON()TEST() +/* { dg-final { scan-file c2x-scope-2.i "ABC: :ABC" } } */ diff --git a/gcc/testsuite/gcc.dg/cpp/c90-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c90-scope-1.c new file mode 100644 index 0000000..4c23e21 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c90-scope-1.c @@ -0,0 +1,7 @@ +/* Test :: token not in C90. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c90 -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */ diff --git a/gcc/testsuite/gcc.dg/cpp/c94-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c94-scope-1.c new file mode 100644 index 0000000..0e6da01 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c94-scope-1.c @@ -0,0 +1,8 @@ +/* Test :: token not in C94. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=iso9899:199409 -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */ +CONCAT (::, >) diff --git a/gcc/testsuite/gcc.dg/cpp/c99-scope-1.c b/gcc/testsuite/gcc.dg/cpp/c99-scope-1.c new file mode 100644 index 0000000..e878286 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/c99-scope-1.c @@ -0,0 +1,8 @@ +/* Test :: token not in C99. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c99 -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) /* { dg-error "does not give a valid preprocessing token" } */ +CONCAT (::, >) diff --git a/gcc/testsuite/gcc.dg/cpp/gnu11-scope-1.c b/gcc/testsuite/gcc.dg/cpp/gnu11-scope-1.c new file mode 100644 index 0000000..2dea391 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/gnu11-scope-1.c @@ -0,0 +1,8 @@ +/* Test :: token in gnu11. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=gnu11 -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) +CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */ diff --git a/gcc/testsuite/gcc.dg/cpp/gnu17-scope-1.c b/gcc/testsuite/gcc.dg/cpp/gnu17-scope-1.c new file mode 100644 index 0000000..0c5f20d --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/gnu17-scope-1.c @@ -0,0 +1,8 @@ +/* Test :: token in gnu17. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=gnu17 -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) +CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */ diff --git a/gcc/testsuite/gcc.dg/cpp/gnu89-scope-1.c b/gcc/testsuite/gcc.dg/cpp/gnu89-scope-1.c new file mode 100644 index 0000000..812e62f --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/gnu89-scope-1.c @@ -0,0 +1,8 @@ +/* Test :: token in gnu89. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=gnu89 -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) +CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */ diff --git a/gcc/testsuite/gcc.dg/cpp/gnu99-scope-1.c b/gcc/testsuite/gcc.dg/cpp/gnu99-scope-1.c new file mode 100644 index 0000000..5ba871d --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/gnu99-scope-1.c @@ -0,0 +1,8 @@ +/* Test :: token in gnu99. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=gnu99 -pedantic-errors" } */ + +#define CONCAT(x, y) x ## y + +CONCAT (:, :) +CONCAT (::, >) /* { dg-error "does not give a valid preprocessing token" } */ |