From 204a5f7bf3f5daf31b9443dd1eb67b2131b56941 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Wed, 23 Feb 2022 18:52:44 +1300 Subject: [PATCH] Fix a preprocessor expression evaluation bug A subexpression in parentheses lost its string/int type flag and instead used whatever type was left in the stack entry from previous use. In practice we mostly got away with this because most preprocessor expressions are integer, but it could have resulted in a preprocessor expression incorrectly evaluating as zero. If -Wextra was in use you got a warning: Warning 202: Error: 'Can't mix strings and integers in expression' Fixes #1384 --- CHANGES.current | 11 +++++++++++ Examples/test-suite/preproc.i | 16 ++++++++++++++++ Source/Preprocessor/expr.c | 1 + 3 files changed, 28 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index bb1377c0c..902a5f548 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,17 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.1.0 (in progress) =========================== +2022-02-23: olly + #1384 Fix a preprocessor expression evaluation bug. A + subexpression in parentheses lost its string/int type flag and + instead used whatever type was left in the stack entry from + previous use. In practice we mostly got away with this because + most preprocessor expressions are integer, but it could have + resulted in a preprocessor expression incorrectly evaluating as + zero. If -Wextra was in use you got a warning: + + Warning 202: Error: 'Can't mix strings and integers in expression' + 2022-02-20: wsfulton Fix %warnfilter warning suppress for warning 315 SWIGWARN_PARSE_USING_UNDEF. diff --git a/Examples/test-suite/preproc.i b/Examples/test-suite/preproc.i index a69973f13..dff6dbca1 100644 --- a/Examples/test-suite/preproc.i +++ b/Examples/test-suite/preproc.i @@ -11,6 +11,22 @@ #pragma SWIG nowarn=890 /* lots of Go name conflicts */ #pragma SWIG nowarn=206 /* Unexpected tokens after #endif directive. */ +/* Regression test: in SWIG < 4.1.0 this triggered the two #error cases. + * Github issue #1384 + */ +#if "" != "" +#endif +#if 1 && (!0) +// Should go here +#else +# error BUG +#endif +#if ((("" == ""))) || (1 && (!1)) +// Should go here +#else +# error BUG +#endif + %{ #if defined(__clang__) /*Suppress: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]*/ diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c index a36588983..661e94840 100644 --- a/Source/Preprocessor/expr.c +++ b/Source/Preprocessor/expr.c @@ -406,6 +406,7 @@ int Preprocessor_expr(DOH *s, int *error) { goto extra_rparen; stack[sp - 1].op = EXPR_VALUE; stack[sp - 1].value = stack[sp].value; + stack[sp - 1].svalue = stack[sp].svalue; sp--; break; default: