Discussion:
Implementing p0515 - spaceship operator
Tim van Deurzen
2018-01-08 21:07:00 UTC
Permalink
Hi,

I've been spending some time the past few weeks implementing p0515r2,
i.e. the proposal for consistent comparisons for C++ (aka the spaceship
operator). I've received some very valuable help on the IRC channel, but
I'm still a little bit stuck. Note, I'm completely new to the GCC
codebase and am very much still getting oriented.

Following advice from some of the people in IRC channel I implemented
parsing the new token in libcpp and I seem to be successfully parsing it
and creating a new AST node. As this feature is not in the C++ standard
yet, I wanted to add a command line flag to enable usage of the new
operator and ignoring it otherwise. I managed to get cc1plus to accept
the parameter, but it seems that when I invoke my own g++ binary with
that parameter, it complains about unknown parameters.

I'm perfectly happy to dig further on my own, but I get the feeling I'm
missing some documentation / resource somewhere that might help me out.
Is there some documentation about adding and passing around parameters
that will be used both in libcpp and the C++ front-end? What would be
the best place to look to learn more about how part of GCC this is
structured? I want to make sure I go about this correctly.


If this is the wrong place to ask for help, please redirect me, so that
I don't unnecessarily spam the wrong mailing list :-).


Kind regards,

Tim.
Jason Merrill
2018-01-08 22:07:52 UTC
Permalink
Post by Tim van Deurzen
I've been spending some time the past few weeks implementing p0515r2,
i.e. the proposal for consistent comparisons for C++ (aka the spaceship
operator).
Great!
Post by Tim van Deurzen
I've received some very valuable help on the IRC channel, but
I'm still a little bit stuck. Note, I'm completely new to the GCC
codebase and am very much still getting oriented.
Following advice from some of the people in IRC channel I implemented
parsing the new token in libcpp and I seem to be successfully parsing it
and creating a new AST node. As this feature is not in the C++ standard
yet, I wanted to add a command line flag to enable usage of the new
operator and ignoring it otherwise. I managed to get cc1plus to accept
the parameter, but it seems that when I invoke my own g++ binary with
that parameter, it complains about unknown parameters.
I'm perfectly happy to dig further on my own, but I get the feeling I'm
missing some documentation / resource somewhere that might help me out.
Is there some documentation about adding and passing around parameters
that will be used both in libcpp and the C++ front-end? What would be
the best place to look to learn more about how part of GCC this is
structured? I want to make sure I go about this correctly.
There's a gccint.info documentation file, the Options node seems like
what you're looking for. You will want to add a new option to
c-family/c.opt.
Post by Tim van Deurzen
If this is the wrong place to ask for help, please redirect me, so that
I don't unnecessarily spam the wrong mailing list :-).
I'm not sure whether gcc@ or gcc-patches@ is better for this sort of
question (without a patch). I tend to miss a lot that goes by on the
mailing list, so CCing me directly about C++ changes is also helpful.

Jason
Jason Merrill
2018-01-08 22:28:52 UTC
Permalink
Post by Jason Merrill
Post by Tim van Deurzen
I've been spending some time the past few weeks implementing p0515r2,
i.e. the proposal for consistent comparisons for C++ (aka the spaceship
operator).
Great!
Post by Tim van Deurzen
I've received some very valuable help on the IRC channel, but
I'm still a little bit stuck. Note, I'm completely new to the GCC
codebase and am very much still getting oriented.
Following advice from some of the people in IRC channel I implemented
parsing the new token in libcpp and I seem to be successfully parsing it
and creating a new AST node. As this feature is not in the C++ standard
yet, I wanted to add a command line flag to enable usage of the new
operator and ignoring it otherwise. I managed to get cc1plus to accept
the parameter, but it seems that when I invoke my own g++ binary with
that parameter, it complains about unknown parameters.
I'm perfectly happy to dig further on my own, but I get the feeling I'm
missing some documentation / resource somewhere that might help me out.
Is there some documentation about adding and passing around parameters
that will be used both in libcpp and the C++ front-end? What would be
the best place to look to learn more about how part of GCC this is
structured? I want to make sure I go about this correctly.
There's a gccint.info documentation file, the Options node seems like
what you're looking for. You will want to add a new option to
c-family/c.opt.
operator<=> is now in the working paper though, so does it need its
own option? IMHO it should just be enabled for -std=c++2a and
-std=gnu++2a, and not otherwise.
Ah, good point.

Jason
Tim van Deurzen
2018-01-09 22:56:05 UTC
Permalink
Post by Jason Merrill
Post by Jason Merrill
Post by Tim van Deurzen
I've been spending some time the past few weeks implementing p0515r2,
i.e. the proposal for consistent comparisons for C++ (aka the spaceship
operator).
Great!
Post by Tim van Deurzen
I've received some very valuable help on the IRC channel, but
I'm still a little bit stuck. Note, I'm completely new to the GCC
codebase and am very much still getting oriented.
Following advice from some of the people in IRC channel I implemented
parsing the new token in libcpp and I seem to be successfully parsing it
and creating a new AST node. As this feature is not in the C++ standard
yet, I wanted to add a command line flag to enable usage of the new
operator and ignoring it otherwise. I managed to get cc1plus to accept
the parameter, but it seems that when I invoke my own g++ binary with
that parameter, it complains about unknown parameters.
I'm perfectly happy to dig further on my own, but I get the feeling I'm
missing some documentation / resource somewhere that might help me out.
Is there some documentation about adding and passing around parameters
that will be used both in libcpp and the C++ front-end? What would be
the best place to look to learn more about how part of GCC this is
structured? I want to make sure I go about this correctly.
There's a gccint.info documentation file, the Options node seems like
what you're looking for. You will want to add a new option to
c-family/c.opt.
operator<=> is now in the working paper though, so does it need its
own option? IMHO it should just be enabled for -std=c++2a and
-std=gnu++2a, and not otherwise.
Ah, good point.
Jason
That makes sense, I'll just use the c++2a and gnu++2a flags. Though I'll
still take some time to figure out how options work, so that I can add
any toggles that (e.g. for warnings) that might be specific to operator<=>.

Just to confirm with you, it does make sense to conditionally parse the
token for operator<=> in libcpp (i.e. only when the cxx standard being
used is >=2a)? I'm just wondering if this does not accidentally affect
other front-ends using libcpp?

Tim.
Tim van Deurzen
2018-01-10 21:24:00 UTC
Permalink
Post by Tim van Deurzen
Just to confirm with you, it does make sense to conditionally
parse the token for operator<=> in libcpp (i.e. only when the cxx
standard being used is >=2a)? I'm just wondering if this does not
accidentally affect other front-ends using libcpp?
Other front ends won't setthe language to C++2a.
      if (CPP_OPTION (pfile, lang) == CLK_CXX2A
          || CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)
This can only be true for a C++ source file when the standard is C++2a.
Ok, good to know, then I'll proceed like this. Thank you!

Tim.
Jakub Jelinek
2018-01-10 21:32:20 UTC
Permalink
Post by Tim van Deurzen
Post by Tim van Deurzen
Just to confirm with you, it does make sense to conditionally
parse the token for operator<=> in libcpp (i.e. only when the cxx
standard being used is >=2a)? I'm just wondering if this does not
accidentally affect other front-ends using libcpp?
Other front ends won't setthe language to C++2a.
      if (CPP_OPTION (pfile, lang) == CLK_CXX2A
          || CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)
This can only be true for a C++ source file when the standard is C++2a.
Ok, good to know, then I'll proceed like this. Thank you!
Well, the usual way of doing stuff is add another field to
struct lang_flags, add it to the lang_defaults table, add it to
struct cpp_options too and then use CPP_OPTION (pfile, spaceship) or so,
e.g. look how va_opt etc. are implemented.

Jakub
Tim van Deurzen
2018-01-10 21:38:46 UTC
Permalink
Hi Jakub,
Post by Jakub Jelinek
Post by Tim van Deurzen
Post by Tim van Deurzen
Just to confirm with you, it does make sense to conditionally
parse the token for operator<=> in libcpp (i.e. only when the cxx
standard being used is >=2a)? I'm just wondering if this does not
accidentally affect other front-ends using libcpp?
Other front ends won't setthe language to C++2a.
      if (CPP_OPTION (pfile, lang) == CLK_CXX2A
          || CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)
This can only be true for a C++ source file when the standard is C++2a.
Ok, good to know, then I'll proceed like this. Thank you!
Well, the usual way of doing stuff is add another field to
struct lang_flags, add it to the lang_defaults table, add it to
struct cpp_options too and then use CPP_OPTION (pfile, spaceship) or so,
e.g. look how va_opt etc. are implemented.
Jakub
I think, I got almost all of that at some point, but probably missed
something somewhere.
For now I will proceed with the cxx standard flags. If I add any kind of
warning or toggle I'll have a good idea where to start at this point.
Thank you!

Tim.
David Brown
2018-01-11 10:05:57 UTC
Permalink
Post by Tim van Deurzen
Just to confirm with you, it does make sense to conditionally parse the
token for operator<=> in libcpp (i.e. only when the cxx standard being used
is >=2a)? I'm just wondering if this does not accidentally affect other
front-ends using libcpp?
Maybe it is easier to say "gcc supports <=> in C++2a, and as an
extension also supports it in C and C++ of any standard" ? I don't
believe there is any way for it to conflict with existing valid code, so
it would do no harm as a gcc extension like that - and C users can then
use it too.
Post by Tim van Deurzen
Other front ends won't setthe language to C++2a.
if (CPP_OPTION (pfile, lang) == CLK_CXX2A
|| CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)
This can only be true for a C++ source file when the standard is C++2a.
David Brown
2018-01-11 11:28:56 UTC
Permalink
Post by David Brown
Maybe it is easier to say "gcc supports <=> in C++2a, and as an
extension also supports it in C and C++ of any standard" ? I don't
believe there is any way for it to conflict with existing valid code, so
it would do no harm as a gcc extension like that - and C users can then
use it too.
It's not very useful in C because you need the comparison category
types, which are classes defined in <compare> (see
http://en.cppreference.com/w/cpp/header/compare)
C doesn't have those types, and can't define anything close.
Surely you can get very close by simply returning an int, value -1, 0 or
1? That is what other languages (like PHP) do for their <=> operator.
There are complications - such as for floating point when you have NaNs.
But I think you could have a very successful operator if you defined "a
<=> b" to be the same as "(a > b) - (a < b)".

Whether it would be particularly /useful/ or not is another matter. I
was thinking mainly in terms of saving effort when making C++2a support
- rather than having to making the new operator conditional on a
particular version of the standards, it could be accepted in any version.
And it's non-conforming to declare those types in pre-C++2a, because
the names could be used by user programs.
Potentially the types could be defined with reserved names like
__strong_ordering, and then make std::strong_ordering a typedef for
that, but there are also changes to the language spec that go with the
new operator, and enabling those pre-C++2a could change the meaning of
valid code.
So it's not ar it does no harm.
David Brown
2018-01-11 11:41:48 UTC
Permalink
Post by David Brown
Post by David Brown
Maybe it is easier to say "gcc supports <=> in C++2a, and as an
extension also supports it in C and C++ of any standard" ? I don't
believe there is any way for it to conflict with existing valid code, so
it would do no harm as a gcc extension like that - and C users can then
use it too.
It's not very useful in C because you need the comparison category
types, which are classes defined in <compare> (see
http://en.cppreference.com/w/cpp/header/compare)
C doesn't have those types, and can't define anything close.
Surely you can get very close by simply returning an int, value -1, 0 or
1? That is what other languages (like PHP) do for their <=> operator.
There are complications - such as for floating point when you have NaNs.
But I think you could have a very successful operator if you defined "a
<=> b" to be the same as "(a > b) - (a < b)".
Whether it would be particularly /useful/ or not is another matter. I
was thinking mainly in terms of saving effort when making C++2a support
- rather than having to making the new operator conditional on a
particular version of the standards, it could be accepted in any version.
It seems like the wrong trade-off. We have dozens of features that
depend on the standards mode, we know how to do that.
Simply slamming a new language feature in all modes (*and* in a
different language with a different front-end!) to save a small amount
of effort doesn't seem like a good idea to me. Especially if it then
doesn't even work the same pre-C++2a, as know we need to test it in
additional ways.
Fair enough. I was merely thinking it might make the development a
little easier by avoiding more feature testing in the front ends. And
gcc has a history of making some features of one language or standard
available in others as gcc extensions. (Sometimes I find these useful
in my coding - though I can't think off-hand for a use of <=> in my own
programs.)

But I see pre-C++2a would be a problem here. You can't make it match
the C++2a version, because you don't have the types available - and you
wouldn't want to make it have different types that are incompatible with
the C++2a version. It would be fine with a -1, 0, 1 int result in C -
but not in pre-C++2a.
Joseph Myers
2018-01-11 14:06:06 UTC
Permalink
Post by David Brown
Maybe it is easier to say "gcc supports <=> in C++2a, and as an
extension also supports it in C and C++ of any standard" ? I don't
believe there is any way for it to conflict with existing valid code, so
it would do no harm as a gcc extension like that - and C users can then
use it too.
As per previous IRC discussion, changing the lexing to support this
pp-token can break valid code in previous standards, e.g. code
concatenating <=> and >, then stringizing the result (the C++ proposal for
adding this feature also notes some obscure cases where the character
sequence <=> can actually occur as tokens, not just pp-tokens -
"X<&Y::operator<=>" and "x+&operator<=>y" - so of course patches adding
this feature should add testcases using such cases with older -std=
options).

Changes to cpp_avoid_paste (so that preprocessed output does not put a
pp-token starting with > immediately after <=) do not need to be
conditional on the standard version, however.
--
Joseph S. Myers
***@codesourcery.com
Jakub Jelinek
2018-08-30 18:07:05 UTC
Permalink
Post by Joseph Myers
Post by David Brown
Maybe it is easier to say "gcc supports <=> in C++2a, and as an
extension also supports it in C and C++ of any standard" ? I don't
believe there is any way for it to conflict with existing valid code, so
it would do no harm as a gcc extension like that - and C users can then
use it too.
As per previous IRC discussion, changing the lexing to support this
pp-token can break valid code in previous standards, e.g. code
concatenating <=> and >, then stringizing the result (the C++ proposal for
adding this feature also notes some obscure cases where the character
sequence <=> can actually occur as tokens, not just pp-tokens -
"X<&Y::operator<=>" and "x+&operator<=>y" - so of course patches adding
this feature should add testcases using such cases with older -std=
options).
Changes to cpp_avoid_paste (so that preprocessed output does not put a
pp-token starting with > immediately after <=) do not need to be
conditional on the standard version, however.
Here is a patch that attempts to implement this (in libcpp + gcc/testsuite
only so far).
It needs to be parsed and handled in the C++ FE obviously, which is missing.

2018-08-30 Jakub Jelinek <***@redhat.com>

P0515R3 - Consistent comparison
* include/cpplib.h (TTYPE_TABLE): Add CPP_SPACESHIP.
(struct cpp_options): Add spaceship field.
* init.c (struct lang_flags): Add spaceship field.
(lang_defaults): Add spaceship column.
(cpp_set_lang): Initialize CPP_OPTION (pfile, spaceship).
* lex.c (_cpp_lex_direct): Lex CPP_SPACESHIP.
(cpp_avoid_paste): Avoid pasting <= with >.

* c-c++-common/cpp/spaceship-1.c: New test.
* g++.dg/cpp/spaceship-1.C: New test.

--- libcpp/include/cpplib.h.jj 2018-08-26 22:43:12.510939169 +0200
+++ libcpp/include/cpplib.h 2018-08-30 18:55:55.483035882 +0200
@@ -91,6 +91,7 @@ struct _cpp_file;
OP(XOR_EQ, "^=") \
OP(RSHIFT_EQ, ">>=") \
OP(LSHIFT_EQ, "<<=") \
+ OP(SPACESHIP, "<=>") \
/* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \
OP(HASH, "#") /* digraphs */ \
OP(PASTE, "##") \
@@ -480,6 +481,9 @@ struct cpp_options
/* Nonzero for C++2a __VA_OPT__ feature. */
unsigned char va_opt;

+ /* Nonzero for C++2a <=> operator. */
+ unsigned char spaceship;
+
/* Holds the name of the target (execution) character set. */
const char *narrow_charset;

--- libcpp/init.c.jj 2018-08-26 22:43:13.760918150 +0200
+++ libcpp/init.c 2018-08-30 18:57:41.479297007 +0200
@@ -92,30 +92,31 @@ struct lang_flags
char trigraphs;
char utf8_char_literals;
char va_opt;
+ char spaceship;
};

static const struct lang_flags lang_defaults[] =
-{ /* c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt */
- /* GNUC89 */ { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 },
- /* GNUC99 */ { 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
- /* GNUC11 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
- /* GNUC17 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
- /* STDC89 */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
- /* STDC94 */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0 },
- /* STDC99 */ { 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0 },
- /* STDC11 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0 },
- /* STDC17 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0 },
- /* GNUCXX */ { 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 },
- /* CXX98 */ { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0 },
- /* GNUCXX11 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1 },
- /* CXX11 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0 },
- /* GNUCXX14 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1 },
- /* CXX14 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
- /* GNUCXX17 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1 },
- /* CXX17 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0 },
- /* GNUCXX2A */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1 },
- /* CXX2A */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 },
- /* ASM */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+{ /* c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt spaceship */
+ /* GNUC89 */ { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
+ /* GNUC99 */ { 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0 },
+ /* GNUC11 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0 },
+ /* GNUC17 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0 },
+ /* STDC89 */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
+ /* STDC94 */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
+ /* STDC99 */ { 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
+ /* STDC11 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0 },
+ /* STDC17 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0 },
+ /* GNUCXX */ { 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
+ /* CXX98 */ { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
+ /* GNUCXX11 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0 },
+ /* CXX11 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 },
+ /* GNUCXX14 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0 },
+ /* CXX14 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ /* GNUCXX17 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0 },
+ /* CXX17 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 },
+ /* GNUCXX2A */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 },
+ /* CXX2A */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 },
+ /* ASM */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};

/* Sets internal flags correctly for a given language. */
@@ -141,6 +142,7 @@ cpp_set_lang (cpp_reader *pfile, enum c_
CPP_OPTION (pfile, trigraphs) = l->trigraphs;
CPP_OPTION (pfile, utf8_char_literals) = l->utf8_char_literals;
CPP_OPTION (pfile, va_opt) = l->va_opt;
+ CPP_OPTION (pfile, spaceship) = l->spaceship;
}

/* Initialize library global state. */
--- libcpp/lex.c.jj 2018-08-26 22:43:14.784900935 +0200
+++ libcpp/lex.c 2018-08-30 19:02:43.261340974 +0200
@@ -2963,7 +2963,11 @@ _cpp_lex_direct (cpp_reader *pfile)

result->type = CPP_LESS;
if (*buffer->cur == '=')
- buffer->cur++, result->type = CPP_LESS_EQ;
+ {
+ buffer->cur++, result->type = CPP_LESS_EQ;
+ if (*buffer->cur == '>' && CPP_OPTION (pfile, spaceship))
+ buffer->cur++, result->type = CPP_SPACESHIP;
+ }
else if (*buffer->cur == '<')
{
buffer->cur++;
@@ -3466,6 +3470,7 @@ cpp_avoid_paste (cpp_reader *pfile, cons
|| (CPP_OPTION (pfile, objc)
&& token1->val.str.text[0] == '@'
&& (b == CPP_NAME || b == CPP_STRING)));
+ case CPP_LESS_EQ: return c == '>';
case CPP_STRING:
case CPP_WSTRING:
case CPP_UTF8STRING:
--- gcc/testsuite/c-c++-common/cpp/spaceship-1.c.jj 2018-08-30 19:41:13.762257530 +0200
+++ gcc/testsuite/c-c++-common/cpp/spaceship-1.c 2018-08-30 19:49:09.338386388 +0200
@@ -0,0 +1,6 @@
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11" { target c } } */
+
+#define A(x, y) x##y
+A(<=, >) /* { dg-error "does not give a valid preprocessing token" "" { target { ! c++2a } } } */
+A(<=>, >) /* { dg-error "does not give a valid preprocessing token" "" { target c++2a } } */
--- gcc/testsuite/g++.dg/cpp/spaceship-1.C.jj 2018-08-30 19:58:56.152695104 +0200
+++ gcc/testsuite/g++.dg/cpp/spaceship-1.C 2018-08-30 19:59:20.802288063 +0200
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++17_down } }
+// { dg-options "-Wno-pointer-arith" }
+
+struct X {};
+bool operator<= (X, X);
+template<bool (X, X)> struct Y {};
+Y<&operator<=> y;
+bool foo (bool (*fn) (X, X), int n) { return n+&operator<=> fn; }


Jakub
Marek Polacek
2018-08-30 18:16:17 UTC
Permalink
Post by Jakub Jelinek
Post by Joseph Myers
Post by David Brown
Maybe it is easier to say "gcc supports <=> in C++2a, and as an
extension also supports it in C and C++ of any standard" ? I don't
believe there is any way for it to conflict with existing valid code, so
it would do no harm as a gcc extension like that - and C users can then
use it too.
As per previous IRC discussion, changing the lexing to support this
pp-token can break valid code in previous standards, e.g. code
concatenating <=> and >, then stringizing the result (the C++ proposal for
adding this feature also notes some obscure cases where the character
sequence <=> can actually occur as tokens, not just pp-tokens -
"X<&Y::operator<=>" and "x+&operator<=>y" - so of course patches adding
this feature should add testcases using such cases with older -std=
options).
Changes to cpp_avoid_paste (so that preprocessed output does not put a
pp-token starting with > immediately after <=) do not need to be
conditional on the standard version, however.
Here is a patch that attempts to implement this (in libcpp + gcc/testsuite
only so far).
It needs to be parsed and handled in the C++ FE obviously, which is missing.
Thanks.

Tim, have you had any success with this, or should I (or somebody else) feel
free to take it over?

Marek
Tim van Deurzen
2018-09-03 21:04:28 UTC
Permalink
Hello Jakub,

I must confess that in the last months I've not been able to find much
time (I do this in my spare time) to work on this. Part of the problem
is also that my new employer hasn't yet provided a written copyright
waiver for the FSF, though they have agreed and my contract already
works out well in that regard.

I would very much like to continue this project, but I'm very happy to
collaborate and join forces to get this feature further. I hang out on
the CppSlack as vdeurzen, if you want to contact me on another platform.
Are there other platforms for GCC development that are well suited to
discussing this topic?


Best regards,

Tim.
Post by Marek Polacek
Post by Jakub Jelinek
Post by Joseph Myers
Post by David Brown
Maybe it is easier to say "gcc supports <=> in C++2a, and as an
extension also supports it in C and C++ of any standard" ? I don't
believe there is any way for it to conflict with existing valid code, so
it would do no harm as a gcc extension like that - and C users can then
use it too.
As per previous IRC discussion, changing the lexing to support this
pp-token can break valid code in previous standards, e.g. code
concatenating <=> and >, then stringizing the result (the C++ proposal for
adding this feature also notes some obscure cases where the character
sequence <=> can actually occur as tokens, not just pp-tokens -
"X<&Y::operator<=>" and "x+&operator<=>y" - so of course patches adding
this feature should add testcases using such cases with older -std=
options).
Changes to cpp_avoid_paste (so that preprocessed output does not put a
pp-token starting with > immediately after <=) do not need to be
conditional on the standard version, however.
Here is a patch that attempts to implement this (in libcpp + gcc/testsuite
only so far).
It needs to be parsed and handled in the C++ FE obviously, which is missing.
Thanks.
Tim, have you had any success with this, or should I (or somebody else) feel
free to take it over?
Marek
Jason Merrill
2018-09-26 15:00:27 UTC
Permalink
I must confess that in the last months I've not been able to find much time
(I do this in my spare time) to work on this. Part of the problem is also
that my new employer hasn't yet provided a written copyright waiver for the
FSF, though they have agreed and my contract already works out well in that
regard.
Any progress on this?
I would very much like to continue this project, but I'm very happy to
collaborate and join forces to get this feature further. I hang out on the
CppSlack as vdeurzen, if you want to contact me on another platform. Are
there other platforms for GCC development that are well suited to discussing
this topic?
Many GCC developers hang out on the #gcc channel on irc.oftc.net.

Jason
Nathan Sidwell
2018-09-27 20:57:58 UTC
Permalink
Post by Jason Merrill
I must confess that in the last months I've not been able to find much time
(I do this in my spare time) to work on this. Part of the problem is also
that my new employer hasn't yet provided a written copyright waiver for the
FSF, though they have agreed and my contract already works out well in that
regard.
Any progress on this?
Tim and I are at the same conference, we've been chatting.

nathan
--
Nathan Sidwell
Jason Merrill
2018-11-05 01:22:52 UTC
Permalink
Post by Jason Merrill
I must confess that in the last months I've not been able to find much time
(I do this in my spare time) to work on this. Part of the problem is also
that my new employer hasn't yet provided a written copyright waiver for the
FSF, though they have agreed and my contract already works out well in that
regard.
Any progress on this?
Has this been worked out? We're getting near the end of GCC stage 1,
which is the deadline for new features going into the next release, so
it would be great to see a patch with whatever you have so far.

Jason
Tim van Deurzen
2018-11-05 07:36:44 UTC
Permalink
Hi Jason,

I've received a lot of good advice from Nathan, but haven't had an
opportunity to apply it yet. I'm happy, however, to show / commit what I
have so far (which covers the parsing of the operator). I've been
working from the git repository until now, but from the mailing list I
gather that this is not the main development RCS yet. How and/or where
would you prefer my changes to be sent to? Just as a patch to the
mailing list or rather as a new branch in the SVN repo? If the latter is
the case I would need a bit of assistance as it's been years since I've
worked with SVN.

When exactly is the feature deadline?


Tim.

P.S. I will make time this month to start applying Nathan's advice and
push the implementation to the next step.

P.P.S. The copyright situation has been resolved and I can continue
contributing without issue.
Post by Jason Merrill
Post by Jason Merrill
I must confess that in the last months I've not been able to find much time
(I do this in my spare time) to work on this. Part of the problem is also
that my new employer hasn't yet provided a written copyright waiver for the
FSF, though they have agreed and my contract already works out well in that
regard.
Any progress on this?
Has this been worked out? We're getting near the end of GCC stage 1,
which is the deadline for new features going into the next release, so
it would be great to see a patch with whatever you have so far.
Jason
Jakub Jelinek
2018-11-05 07:40:02 UTC
Permalink
Post by Tim van Deurzen
I've received a lot of good advice from Nathan, but haven't had an
opportunity to apply it yet. I'm happy, however, to show / commit what I
have so far (which covers the parsing of the operator). I've been working
from the git repository until now, but from the mailing list I gather that
this is not the main development RCS yet. How and/or where would you prefer
my changes to be sent to? Just as a patch to the mailing list or rather as a
new branch in the SVN repo? If the latter is the case I would need a bit of
assistance as it's been years since I've worked with SVN.
When exactly is the feature deadline?
The deadline is end of November 11th, timezone of your choice.
Patches should be just posted to gcc-patches at gcc dot gnu dot org mailing
list. If you could do it today or tomorrow, it would be really appreciated.

Jakub
Tim van Deurzen
2018-11-05 08:08:09 UTC
Permalink
Will take care of it this evening then. If I get stuck or need some help
I'll try the IRC channel or reply to this mail again :).

Tim.
Post by Jakub Jelinek
Post by Tim van Deurzen
I've received a lot of good advice from Nathan, but haven't had an
opportunity to apply it yet. I'm happy, however, to show / commit what I
have so far (which covers the parsing of the operator). I've been working
from the git repository until now, but from the mailing list I gather that
this is not the main development RCS yet. How and/or where would you prefer
my changes to be sent to? Just as a patch to the mailing list or rather as a
new branch in the SVN repo? If the latter is the case I would need a bit of
assistance as it's been years since I've worked with SVN.
When exactly is the feature deadline?
The deadline is end of November 11th, timezone of your choice.
Patches should be just posted to gcc-patches at gcc dot gnu dot org mailing
list. If you could do it today or tomorrow, it would be really appreciated.
Jakub
Jason Merrill
2018-11-05 23:13:36 UTC
Permalink
Post by Tim van Deurzen
I've received a lot of good advice from Nathan, but haven't had an
opportunity to apply it yet. I'm happy, however, to show / commit what I
have so far (which covers the parsing of the operator). I've been
working from the git repository until now, but from the mailing list I
gather that this is not the main development RCS yet. How and/or where
would you prefer my changes to be sent to? Just as a patch to the
mailing list or rather as a new branch in the SVN repo?
Patches against the git mirror is fine, I haven't touched the svn
client in quite a while either.

Jason

Nathan Sidwell
2018-01-09 18:01:48 UTC
Permalink
Post by Jason Merrill
There's a gccint.info documentation file, the Options node seems like
what you're looking for. You will want to add a new option to
c-family/c.opt.
diffing between branches/c++-modules and trunk may be educational, as
that has to do similar things to enable the new keywords.

nathan
--
Nathan Sidwell
Martin Sebor
2018-01-09 16:10:15 UTC
Permalink
Post by Tim van Deurzen
Hi,
I've been spending some time the past few weeks implementing p0515r2,
i.e. the proposal for consistent comparisons for C++ (aka the spaceship
operator). I've received some very valuable help on the IRC channel, but
I'm still a little bit stuck. Note, I'm completely new to the GCC
codebase and am very much still getting oriented.
Following advice from some of the people in IRC channel I implemented
parsing the new token in libcpp and I seem to be successfully parsing it
and creating a new AST node. As this feature is not in the C++ standard
yet, I wanted to add a command line flag to enable usage of the new
operator and ignoring it otherwise. I managed to get cc1plus to accept
the parameter, but it seems that when I invoke my own g++ binary with
that parameter, it complains about unknown parameters.
As Jonathan mentioned, you may not need a new option for this.
But it's useful to know how to add one in any case. Reading
the manual is a good idea but the easiest way to actually add
one by far is to look at a simple change that adds in git or
svn log one and follow its example. This command will give you
such a list: git log -p --grep="New option" Then just look for
an option that affects the front-end. A warning options might
be a good example.

Martin
Post by Tim van Deurzen
I'm perfectly happy to dig further on my own, but I get the feeling I'm
missing some documentation / resource somewhere that might help me out.
Is there some documentation about adding and passing around parameters
that will be used both in libcpp and the C++ front-end? What would be
the best place to look to learn more about how part of GCC this is
structured? I want to make sure I go about this correctly.
If this is the wrong place to ask for help, please redirect me, so that
I don't unnecessarily spam the wrong mailing list :-).
Kind regards,
Tim.
Loading...