Fix spaceship operator bugs, document, add tests

Remove some erroneously added brackets_increment() calls.

Reject <=> in preprocessor expressions with a clear error message (it
seems it isn't supported here - clang and gcc don't at least).

The type returned by `<=>` is not `bool`.  We pretend it's
`int` for now, which should work for how it's likely to be used
in constant expressions.

Fixes #1622
This commit is contained in:
Olly Betts 2022-03-09 10:08:17 +13:00
commit 02b4bd8eca
10 changed files with 91 additions and 7 deletions

View file

@ -1647,7 +1647,8 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%left XOR
%left AND
%left EQUALTO NOTEQUALTO
%left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO LESSEQUALGREATER
%left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO
%left LESSEQUALGREATER
%left LSHIFT RSHIFT
%left PLUS MINUS
%left STAR SLASH MODULO
@ -6844,9 +6845,14 @@ exprcompound : expr PLUS expr {
$$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr LESSEQUALGREATER expr {
| expr LESSEQUALGREATER expr {
$$.val = NewStringf("%s <=> %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = T_BOOL;
// Really `<=>` returns one of `std::strong_ordering`,
// `std::partial_ordering` or `std::weak_ordering`, but we
// fake it by treating the return value as `int`. The main
// thing to do with the return value in this context is to
// compare it with 0, for which `int` does the job.
$$.type = T_INT;
}
| expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
$$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5));

View file

@ -445,6 +445,8 @@ int Preprocessor_expr(DOH *s, int *error) {
stack[sp - 1].svalue = stack[sp].svalue;
sp--;
break;
case SWIG_TOKEN_LTEQUALGT:
goto spaceship_not_allowed;
default:
goto syntax_error_expected_operator;
break;
@ -476,6 +478,11 @@ extra_rparen:
errmsg = "Extra \')\'";
*error = 1;
return 0;
spaceship_not_allowed:
errmsg = "Spaceship operator (<=>) not allowed in preprocessor expression";
*error = 1;
return 0;
}
/* -----------------------------------------------------------------------------

View file

@ -895,17 +895,14 @@ static int look(Scanner *s) {
state = 240;
else if (c == '=') {
if ((c = nextchar(s)) == 0) {
brackets_increment(s);
return SWIG_TOKEN_LTEQUAL;
} else if (c == '>') { /* Spaceship operator */
return SWIG_TOKEN_LTEQUALGT;
} else {
retract(s, 1);
brackets_increment(s);
return SWIG_TOKEN_LTEQUAL;
}
}
else {
} else {
retract(s, 1);
brackets_increment(s);
return SWIG_TOKEN_LESSTHAN;