Fix syntax error parsing an expression

which calls a function with no parameters within additional brackets.

This is more of a hack than a fix as attempts to parse properly
failed, see issue #2640.

Closes #2640
This commit is contained in:
William S Fulton 2023-06-30 08:35:06 +01:00
parent 768bc56c92
commit 3ef3f39516
6 changed files with 115 additions and 4 deletions

View File

@ -7,9 +7,13 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.2.0 (in progress)
===========================
2023-06-30: wsfulton
#2640 Fix syntax error parsing an expression which calls a function
with no parameters within additional brackets.
2023-06-27: mmomtchev
[Javascript] #2545 New Javascript generator targeting the Node.js
binary stable ABI Node-API.
[Javascript] #2545 New Javascript generator targeting the Node.js
binary stable ABI Node-API.
2023-06-27: olly
[Java] Completely remove pragmas which were deprecated in 2002 and

View File

@ -592,6 +592,7 @@ CPP11_TEST_CASES += \
cpp11_alternate_function_syntax \
cpp11_attribute_specifiers \
cpp11_auto_variable \
cpp11_brackets_expression \
cpp11_constexpr \
cpp11_decltype \
cpp11_default_delete \

View File

@ -0,0 +1,35 @@
%module cpp11_brackets_expression
%warnfilter(SWIGWARN_PARSE_ASSIGNED_VALUE) Piece::kMaxSize;
%warnfilter(SWIGWARN_PARSE_ASSIGNED_VALUE) Piece::Just123;
%warnfilter(SWIGWARN_PARSE_ASSIGNED_VALUE) ::kMaxSizeGlobal;
%inline %{
#include <limits>
static constexpr int global_as_you_expect(int val) { return val; }
static constexpr int global_one_two_three() { return 123; }
class Piece {
public:
typedef size_t size_type;
typedef int difference_type;
static constexpr size_type kOk2 = std::numeric_limits<difference_type>::max();
// Failed to parse (issue #2640):
static constexpr size_type kMaxSize = (std::numeric_limits<difference_type>::max)();
// Also fails to parse:
// int f(int x = (std::numeric_limits<difference_type>::max)());
static constexpr size_type SimpleAsYouExpect123 = global_as_you_expect(123);
static constexpr size_type SimpleJust123 = global_one_two_three();
static constexpr size_type AsYouExpect123 = (global_as_you_expect)(123); // Did parse okay
static constexpr size_type Just123 = (global_one_two_three)(); // Did not parse okay
};
static const Piece::size_type kMaxSizeGlobal = (std::numeric_limits<Piece::difference_type>::max)();
%}

View File

@ -0,0 +1,24 @@
import cpp11_brackets_expression.*;
public class cpp11_brackets_expression_runme {
static {
try {
System.loadLibrary("cpp11_brackets_expression");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
long x = Piece.kMaxSize;
x = Piece.SimpleAsYouExpect123;
x = Piece.Just123;
x = cpp11_brackets_expression.getKMaxSizeGlobal();
x = cpp11_brackets_expression.getKMaxSizeGlobal();
x = cpp11_brackets_expression.global_as_you_expect(123);
x = cpp11_brackets_expression.global_one_two_three();
}
}

View File

@ -581,6 +581,13 @@ static void add_symbols(Node *n) {
n = nextSibling(n);
continue;
}
if (GetFlag(n, "valueignored")) {
SWIG_WARN_NODE_BEGIN(n);
Swig_warning(WARN_PARSE_ASSIGNED_VALUE, Getfile(n), Getline(n), "Value assigned to %s not used due to limited parsing implementation.\n", SwigType_namestr(Getattr(n, "name")));
SWIG_WARN_NODE_END(n);
}
if (cparse_cplusplus) {
String *value = Getattr(n, "value");
if (value && Strcmp(value, "delete") == 0) {
@ -3233,8 +3240,47 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$));
}
| storage_class type declarator cpp_const EQUAL error SEMI {
Swig_warning(999, cparse_file, cparse_line, "Ignoring declaration of '%s' due to parser limitation.\n", $3.id);
$$ = 0;
String *decl = $3.type;
$$ = new_node("cdecl");
if ($4.qualifier)
decl = add_qualifier_to_declarator($3.type, $4.qualifier);
Setattr($$, "refqualifier", $4.refqualifier);
Setattr($$, "type", $2);
Setattr($$, "storage", $1);
Setattr($$, "name", $3.id);
Setattr($$, "decl", decl);
Setattr($$, "parms", $3.parms);
/* Set dummy value to avoid adding in code for handling missing value in later stages */
Setattr($$, "value", "*parse error*");
SetFlag($$, "valueignored");
Setattr($$, "throws", $4.throws);
Setattr($$, "throw", $4.throwf);
Setattr($$, "noexcept", $4.nexcept);
Setattr($$, "final", $4.final);
if (Strstr($3.id, "::")) {
String *p = Swig_scopename_prefix($3.id);
if (p) {
if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) ||
(Classprefix && Strcmp(p, Classprefix) == 0)) {
String *lstr = Swig_scopename_last($3.id);
Setattr($$, "name", lstr);
Delete(lstr);
} else {
Delete($$);
$$ = 0;
}
Delete(p);
} else {
Delete($$);
$$ = 0;
}
}
if ($4.qualifier && $1 && Strstr($1, "static"))
Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$));
}
/* Alternate function syntax introduced in C++11:
auto funcName(int x, int y) -> int; */

View File

@ -94,6 +94,7 @@
#define WARN_PARSE_NAMED_NESTED_CLASS 325
#define WARN_PARSE_EXTEND_NAME 326
#define WARN_PARSE_EXTERN_TEMPLATE 327
#define WARN_PARSE_ASSIGNED_VALUE 328
#define WARN_CPP11_LAMBDA 340
#define WARN_CPP11_ALIAS_DECLARATION 341 /* redundant now */