Handle arbitrary expressions as a subscript

We don't actually need to parse expressions in this context so we can
just skip to the matching closing square bracket.
This commit is contained in:
Olly Betts 2024-09-29 11:36:05 +13:00
parent 1c0fa99009
commit d80ce85819
5 changed files with 26 additions and 4 deletions

View File

@ -18,6 +18,11 @@ Version 4.3.0 (in progress)
[Python] Single line docstring comments are stripped of leading and
trailing whitespace.
2024-09-29: olly
SWIG can now handle arbitrary expressions as a subscript (i.e. in
`[`...`]`). We don't actually need to parse expressions in this
context so we can just skip to the matching closing square bracket.
2024-09-29: olly
C++11 auto variables for which SWIG can't parse the initialiser
now give a warning and are ignored rather than SWIG exiting with a

View File

@ -360,3 +360,10 @@ static SomeClass someobject;
// means SWIG can now handle any expression in a method call parameter list.
int nasty_default_expression(int x = someobject.d(sizeof - sizeof 1)) { return x; }
%}
%inline %{
// Regression test - SWIG >= 4.3.0 avoids parsing subscript expressions and instead
// just skips from `[` to the matching closing `]`. That
// means SWIG can now handle any expression as the subscript.
int subscripted_default_arg(int x = "abcdefghij"[sizeof - sizeof 1]) { return x; }
%}

View File

@ -2,7 +2,7 @@
require "tests.php";
// New functions
check::functions(array('archiving_on', 'archiving_onw', 'doublevalue1','doublevalue2','seek','seek2','seek3','seek4','seek5','seek6','seek7','seek8','seek9','seeka','seekb','anonymous','booltest','casts1','casts2','chartest1','chartest2','chartest3','chartest4','chartest5','chartest6','dummy','afunction','reftest1','reftest2','chops','exceptionspec','constructorcall','cfunc1','cfunc2','cfunc3','nasty_default_expression','slightly_off_square'));
check::functions(array('archiving_on', 'archiving_onw', 'doublevalue1','doublevalue2','seek','seek2','seek3','seek4','seek5','seek6','seek7','seek8','seek9','seeka','seekb','anonymous','booltest','casts1','casts2','chartest1','chartest2','chartest3','chartest4','chartest5','chartest6','dummy','afunction','reftest1','reftest2','chops','exceptionspec','constructorcall','cfunc1','cfunc2','cfunc3','nasty_default_expression','slightly_off_square','subscripted_default_arg'));
// New classes
check::classes(array('TrickyInPython','default_args','EnumClass','DerivedEnumClass','Tree','Foo','MyClass1','MyClass2','Except','Statics','Tricky','Klass','ConstMethods','Pointf','CDA'));
// New vars

View File

@ -5493,9 +5493,13 @@ valparm : parm {
def_args : EQUAL definetype {
$$ = $definetype;
}
| EQUAL definetype LBRACKET expr RBRACKET {
$$ = $definetype;
$$.val = NewStringf("%s[%s]", $definetype.val, $expr.val);
| EQUAL definetype LBRACKET {
if (skip_balanced('[', ']') < 0) Exit(EXIT_FAILURE);
$$ = default_dtype;
$$.type = T_UNKNOWN;
$$.val = $definetype.val;
Append($$.val, scanner_ccode);
Clear(scanner_ccode);
}
| EQUAL LBRACE {
if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);

View File

@ -1618,6 +1618,12 @@ int Scanner_skip_balanced(Scanner *s, int startchar, int endchar) {
num_levels++;
} else if (tok == endtok) {
if (--num_levels == 0) break;
} else if (tok == SWIG_TOKEN_RRBRACKET && endtok == SWIG_TOKEN_RBRACKET) {
num_levels -= 2;
if (num_levels <= 0) {
if (num_levels < 0) Scanner_pushtoken(s, SWIG_TOKEN_RBRACKET, "]");
break;
}
} else if (tok == SWIG_TOKEN_COMMENT) {
char *loc = Char(s->text);
if (strncmp(loc, "/*@SWIG", 7) == 0 && loc[Len(s->text)-3] == '@') {