diff --git a/CHANGES.current b/CHANGES.current index 1f0dd3807..15769cbdf 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.1.0 (in progress) =========================== +2022-07-26: olly + Fix incorrect operator precedence in preprocessor expressions. + 2022-07-20: wsfulton [C#, Java] Ensure the order of interfaces generated in proxy interfaces for the %interface family of macros is the same as that parsed from the bases in C++. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 32444688d..7626872cd 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -746,6 +746,7 @@ C_TEST_CASES += \ preproc \ preproc_constants_c \ preproc_defined \ + preproc_expr \ preproc_gcc_output \ preproc_include \ preproc_line_file \ diff --git a/Examples/test-suite/preproc_expr.i b/Examples/test-suite/preproc_expr.i new file mode 100644 index 000000000..a24f7715c --- /dev/null +++ b/Examples/test-suite/preproc_expr.i @@ -0,0 +1,34 @@ +%module preproc_expr + +// Check expressions which suffered from incorrect operator precedence prior +// to SWIG 4.1.0. + +%inline %{ +// `!` should have higher precedence than binary `+`. +#if !0 + 1 +#else +# error Bad preprocessor expression operator precedence +#endif + +// `!=` should have higher precedence than bitwise and. +#if 1 & 2 != 0 +#else +# error Bad preprocessor expression operator precedence +#endif + +// `==` should have higher precedence than bitwise or. +#if (2 | 1 == 3) != 2 +# error Bad preprocessor expression operator precedence +#endif + +// `!=` should have higher precedence than bitwise xor. +#if 1 ^ 2 != 4 +# error Bad preprocessor expression operator precedence +#endif + +// `<` should have higher precedence than '=='. +#if 2 == 2 < 2 +# error Bad preprocessor expression operator precedence +#endif + +%} diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c index 52e467b6c..b2efba57e 100644 --- a/Source/Preprocessor/expr.c +++ b/Source/Preprocessor/expr.c @@ -54,6 +54,7 @@ static const char *errmsg = 0; /* Parsing error */ /* Initialize the precedence table for various operators. Low values have higher precedence */ static void init_precedence(void) { prec[SWIG_TOKEN_NOT] = 10; + prec[SWIG_TOKEN_LNOT] = 10; prec[OP_UMINUS] = 10; prec[OP_UPLUS] = 10; prec[SWIG_TOKEN_STAR] = 20; @@ -63,16 +64,15 @@ static void init_precedence(void) { prec[SWIG_TOKEN_MINUS] = 30; prec[SWIG_TOKEN_LSHIFT] = 40; prec[SWIG_TOKEN_RSHIFT] = 40; - prec[SWIG_TOKEN_AND] = 50; - prec[SWIG_TOKEN_XOR] = 60; - prec[SWIG_TOKEN_OR] = 70; - prec[SWIG_TOKEN_EQUALTO] = 80; - prec[SWIG_TOKEN_NOTEQUAL] = 80; - prec[SWIG_TOKEN_LESSTHAN] = 80; - prec[SWIG_TOKEN_GREATERTHAN] = 80; - prec[SWIG_TOKEN_LTEQUAL] = 80; - prec[SWIG_TOKEN_GTEQUAL] = 80; - prec[SWIG_TOKEN_LNOT] = 90; + prec[SWIG_TOKEN_LESSTHAN] = 50; + prec[SWIG_TOKEN_GREATERTHAN] = 50; + prec[SWIG_TOKEN_LTEQUAL] = 50; + prec[SWIG_TOKEN_GTEQUAL] = 50; + prec[SWIG_TOKEN_EQUALTO] = 60; + prec[SWIG_TOKEN_NOTEQUAL] = 60; + prec[SWIG_TOKEN_AND] = 70; + prec[SWIG_TOKEN_XOR] = 80; + prec[SWIG_TOKEN_OR] = 90; prec[SWIG_TOKEN_LAND] = 100; prec[SWIG_TOKEN_LOR] = 110; expr_init = 1;