Avoid parse errors for C++ attributes

Just ignore anything in between [[ and ]] in the scanner, which is better
that failing with a parse error.

Fixes #1158
Fixes #2286
This commit is contained in:
Julien Marrec 2022-07-08 15:23:05 +12:00 committed by Olly Betts
commit d3759a9b36
6 changed files with 86 additions and 4 deletions

View file

@ -583,6 +583,7 @@ CPP11_TEST_CASES += \
cpp11_alias_nested_template_scoping \
cpp11_alignment \
cpp11_alternate_function_syntax \
cpp11_attribute_specifiers \
cpp11_constexpr \
cpp11_decltype \
cpp11_default_delete \

View file

@ -0,0 +1,41 @@
%module cpp11_attribute_specifiers
%inline %{
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // We're using a deprecated attribute here...
#pragma GCC diagnostic ignored "-Wattributes" // likely is C++20
#pragma GCC diagnostic ignored "-Wunused-variable" // We are using an unused variable on purpose here
#pragma GCC diagnostic ignored "-Wunused-parameter" // We are using an unused param on purpose here
#endif
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wattributes"
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic ignored "-Wunused-parameter"
#endif
[[noreturn]] void noReturn() { throw; }
[[nodiscard]] bool noDiscard() { return true; }
[[nodiscard, deprecated("This has been replaced")]] bool noDiscardDeprecated() { return true; }
void maybeUnused1([[maybe_unused]] bool b) { }
bool maybeUnused2(bool a, [[maybe_unused]] bool b) { return a; }
[[deprecated, nodiscard]] bool likely([[maybe_unused]] bool a, bool b) {
[[maybe_unused]] bool c = b;
if (b) [[likely]] {
return true;
} else [[unlikely]] {
if(a) {
return true;
}
}
return false;
}
struct [[nodiscard]] S { };
%}

View file

@ -354,6 +354,18 @@ static int yylook(void) {
case SWIG_TOKEN_ELLIPSIS:
return ELLIPSIS;
case SWIG_TOKEN_LLBRACKET:
do {
tok = Scanner_token(scan);
} while ((tok != SWIG_TOKEN_RRBRACKET) && (tok > 0));
if (tok <= 0) {
Swig_error(cparse_file, cparse_line, "Unbalanced double brackets, missing closing (']]'). Reached end of input.\n");
}
break;
case SWIG_TOKEN_RRBRACKET:
return RRBRACKET;
/* Look for multi-character sequences */
case SWIG_TOKEN_RSTRING:

View file

@ -1613,6 +1613,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD ELLIPSIS
%token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
%token LLBRACKET RRBRACKET /* C++11 Attribute specifier sequence */
%token BEGINFILE ENDOFFILE
%token ILLEGAL CONSTANT
%token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS

View file

@ -596,10 +596,6 @@ static int look(Scanner *s) {
state = 3;
else if (c == '\\')
return SWIG_TOKEN_BACKSLASH;
else if (c == '[')
return SWIG_TOKEN_LBRACKET;
else if (c == ']')
return SWIG_TOKEN_RBRACKET;
else if (c == '@')
return SWIG_TOKEN_AT;
else if (c == '$')
@ -637,6 +633,10 @@ static int look(Scanner *s) {
else if (c == '.')
state = 100; /* Maybe a number, maybe ellipsis, just a period */
else if (c == '[')
state = 102; /* Maybe a bracket or a double bracket */
else if (c == ']')
state = 103; /* Maybe a bracket or a double bracket */
else if (isdigit(c))
state = 8; /* A numerical value */
else
@ -1358,6 +1358,31 @@ static int look(Scanner *s) {
}
break;
/* A left bracket or a double left bracket */
case 102:
if ((c = nextchar(s)) == 0) {
return SWIG_TOKEN_LBRACKET;
} else if (c == '[') {
return SWIG_TOKEN_LLBRACKET;
} else {
retract(s, 1);
return SWIG_TOKEN_LBRACKET;
}
break;
/* a right bracket or a double right bracket */
case 103:
if ((c = nextchar(s)) == 0) {
return SWIG_TOKEN_RBRACKET;
} else if (c == ']') {
return SWIG_TOKEN_RRBRACKET;
} else {
retract(s, 1);
return SWIG_TOKEN_RBRACKET;
}
break;
case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */
if ((c = nextchar(s)) == 0)
return SWIG_TOKEN_PLUS;

View file

@ -71,6 +71,8 @@ extern void Scanner_locator(Scanner *, String *loc);
#define SWIG_TOKEN_WSTRING 33 /* L"str" */
#define SWIG_TOKEN_WCHAR 34 /* L'c' */
#define SWIG_TOKEN_ELLIPSIS 35 /* ... */
#define SWIG_TOKEN_LLBRACKET 36 /* [[ */
#define SWIG_TOKEN_RRBRACKET 37 /* ]] */
#define SWIG_TOKEN_ILLEGAL 99
#define SWIG_TOKEN_ERROR -1