Parse common cases of < and > comparisons

Adding full support for these in expressions seems hard to do without
introducing conflicts into the parser grammar, but in fact all reported
cases have had parentheses around the comparison and we can support that
with a few restrictions on the left side of `<`.

Fixes #80 and #635.  Also https://sourceforge.net/p/swig/bugs/1139/
This commit is contained in:
Olly Betts 2021-09-29 17:51:02 +13:00
commit f2de21eb83
14 changed files with 98 additions and 20 deletions

View file

@ -141,6 +141,7 @@ CPP_TEST_CASES += \
compactdefaultargs \
const_const_2 \
constant_directive \
constant_expr \
constant_pointers \
constover \
constructor_copy \
@ -689,7 +690,7 @@ C_TEST_CASES += \
c_delete_function \
char_constant \
const_const \
constant_expr \
constant_expr_c \
default_args_c \
empty_c \
enums \

View file

@ -1,11 +1,17 @@
%module constant_expr;
/* Tests of constant expressions. */
/* Tests of constant expressions (C++ version). */
%include "constant_expr_c.i"
%inline %{
/* % didn't work in SWIG 1.3.40 and earlier. */
const int X = 123%7;
#define FOO 12 % 9
double d_array[12 % 9];
// Testcase from https://sourceforge.net/p/swig/bugs/1139/
template<typename Tp>
struct SizeInfo {
enum {
isLarge = (sizeof(Tp)>sizeof(void*)),
isPointer = false
};
};
%}

View file

@ -0,0 +1,35 @@
%module constant_expr_c;
/* Tests of constant expressions (C version). */
%inline %{
/* % didn't work in SWIG 1.3.40 and earlier. */
const int X = 123%7;
#define FOO 12 % 9
double d_array[12 % 9];
/* `<` and `>` in constant expressions caused parse errors before SWIG 4.1.0.
* They're now supported if inside parentheses (and with some restrictions
* on the LHS of `<`.
*/
// Testcase from https://github.com/swig/swig/issues/635
#define TEST_A 1
#define TEST_B 2
#define TEST_C (TEST_A < TEST_B)
#define TEST_D (TEST_A > TEST_B)
// These have been supported since 1.3.41.
#define TEST_E (TEST_A <= TEST_B)
#define TEST_F (TEST_A >= TEST_B)
// For completeness
#define TEST_G (TEST_A == TEST_B)
#define TEST_H (TEST_A != TEST_B)
// No warning
#if (TEST_A < TEST_B)
#define TEST_I 1
#else
#define TEST_I 0
#endif
%}

View file

@ -51,6 +51,8 @@ public class runme {
assert( typeof(int) == preproc_constants_c.EXPR_MINUS.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_LSHIFT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_RSHIFT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_LT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_GT.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_LTE.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_GTE.GetType() );
assert( typeof(int) == preproc_constants_c.EXPR_INEQUALITY.GetType() );

View file

@ -50,6 +50,8 @@ public class runme {
assert( typeof(int) == preproc_constants.EXPR_MINUS.GetType() );
assert( typeof(int) == preproc_constants.EXPR_LSHIFT.GetType() );
assert( typeof(int) == preproc_constants.EXPR_RSHIFT.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_LT.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_GT.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_LTE.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_GTE.GetType() );
assert( typeof(bool) == preproc_constants.EXPR_INEQUALITY.GetType() );

View file

@ -51,6 +51,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
static assert(is(int == typeof(EXPR_LT())));
static assert(is(int == typeof(EXPR_GT())));
static assert(is(int == typeof(EXPR_LTE())));
static assert(is(int == typeof(EXPR_GTE())));
static assert(is(int == typeof(EXPR_INEQUALITY())));

View file

@ -51,6 +51,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
static assert(is(int == typeof(EXPR_LT())));
static assert(is(int == typeof(EXPR_GT())));
static assert(is(int == typeof(EXPR_LTE())));
static assert(is(int == typeof(EXPR_GTE())));
static assert(is(int == typeof(EXPR_INEQUALITY())));

View file

@ -50,6 +50,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
static assert(is(int == typeof(EXPR_LT())));
static assert(is(int == typeof(EXPR_GT())));
static assert(is(bool == typeof(EXPR_LTE())));
static assert(is(bool == typeof(EXPR_GTE())));
static assert(is(bool == typeof(EXPR_INEQUALITY())));

View file

@ -50,6 +50,8 @@ void main() {
static assert(is(int == typeof(EXPR_MINUS())));
static assert(is(int == typeof(EXPR_LSHIFT())));
static assert(is(int == typeof(EXPR_RSHIFT())));
static assert(is(bool == typeof(EXPR_LT())));
static assert(is(bool == typeof(EXPR_GT())));
static assert(is(bool == typeof(EXPR_LTE())));
static assert(is(bool == typeof(EXPR_GTE())));
static assert(is(bool == typeof(EXPR_INEQUALITY())));

View file

@ -51,6 +51,8 @@ check::equal(gettype(preproc_constants_c::EXPR_PLUS), "integer", "preproc_consta
check::equal(gettype(preproc_constants_c::EXPR_MINUS), "integer", "preproc_constants.EXPR_MINUS has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_LSHIFT), "integer", "preproc_constants.EXPR_LSHIFT has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_RSHIFT), "integer", "preproc_constants.EXPR_RSHIFT has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_LT), "integer", "preproc_constants.EXPR_LTE has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_GT), "integer", "preproc_constants.EXPR_GTE has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_LTE), "integer", "preproc_constants.EXPR_LTE has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_GTE), "integer", "preproc_constants.EXPR_GTE has unexpected type");
check::equal(gettype(preproc_constants_c::EXPR_INEQUALITY), "integer", "preproc_constants.EXPR_INEQUALITY has unexpected type");

View file

@ -72,10 +72,8 @@
#define EXPR_LSHIFT 0xFF << 2
#define EXPR_RSHIFT 0xFF >> 2
/* FIXME
#define EXPR_LT 0xFF < 255
#define EXPR_GT 0xFF > 255
*/
#define EXPR_LT (0xFF < 255)
#define EXPR_GT (0xFF > 255)
#define EXPR_LTE 0xFF <= 255
#define EXPR_GTE 0xFF >= 255
#define EXPR_INEQUALITY 0xFF != 255