Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#675 [Perl] Unsigned long constants handled incorrectly in 1.3.29

closed-fixed
Robert Stone
perl (97)
5
2011-09-11
2006-05-04
mas
No

SWIG version is 1.3.29.

The simple code below produces different results on
ActivePerl 5.8.8, Linux Perl 5.8.0 and Cygwin Perl 5.8.7.

ActivePerl produces correct result.
Cygwin's one produces "OverflowError in method
'param2', argument 1 of type 'unsigned long'".
Linux one produces result of 0 instead of 4294967295.

# cat example.i
%module example

%inline %{
#define ULONG_CONSTANT 0xFFFFFFFFU

unsigned long param2(unsigned long param) {
return param;
}
%}

# cat runme.pl
use example;
print "example::param2: " .
example::param2($ULONG_CONSTANT) . "\n";

Discussion

  • Olly Betts
    Olly Betts
    2006-09-25

    Logged In: YES
    user_id=14972

    Thanks for your bug report.

    I've done some investigating, but don't yet fully understand
    what is going on. I'll continue to dig.

    Incidentally, a simpler testcase seems to be:

    use example;
    print "$example::ULONG_CONSTANT\n";

     
  • Olly Betts
    Olly Betts
    2006-09-25

    • assigned_to: nobody --> olly
    • summary: Unsigned long constants handled incorrectly in 1.3.29 --> [Perl] Unsigned long constants handled incorrectly in 1.3.29
     
  • mas
    mas
    2007-01-17

    Logged In: YES
    user_id=1516722
    Originator: YES

    AFAIU the problem is that most Perl ports lose tracking of the unsigned flag of a numeric value, so for the 0xFFFFFFFFU constant internal Perl var contains -1. So SvUOK() doesn't work, only SvIOK() does.
    I made a dirty workaround for myself, patching perlprimtypes.swg:

    SWIG_AsVal_dec(unsigned long)(SV *obj, unsigned long *val)
    {
    if (SvUOK(obj)) {
    if (val) *val = SvUV(obj);
    return SWIG_OK;
    } else if (SvIOK(obj)) {
    long v = SvIV(obj);
    // if (v >= 0) {
    if (val) *val = v;
    return SWIG_OK;
    /* } else {
    return SWIG_OverflowError;
    }
    */
    } else {
    .....

    Please note that SWIG_AsVal_dec(unsigned long long) may require the same modification in SWIG-1.3.31.

    Hope this helps investigating this bug.

     
  • Nik Clayton
    Nik Clayton
    2007-03-03

    Logged In: YES
    user_id=189581
    Originator: NO

    A better fix might be:

    SWIG_AsVal_dec(unsigned long)(SV *obj, unsigned long *val)
    {
    if (SvUOK(obj)) {
    if (val) *val = SvUV(obj);
    return SWIG_OK;
    } else if (SvIOK(obj)) {
    unsigned long v = SvIV(obj); /* addition of "unsigned" here */
    if (v >= 0) {
    if (val) *val = v;
    return SWIG_OK;
    } else {
    return SWIG_OverflowError;
    }
    } else {
    .....

     
  • Olly Betts
    Olly Betts
    2007-03-03

    Logged In: YES
    user_id=14972
    Originator: NO

    Nik: That makes the test for v >= 0 redundant though, so we no longer check for trying
    to set an unsigned variable to a negative value. But if Perl is really losing track of
    the signed/unsigned nature of the value, then we can't reliably check for that here anyway,
    so perhaps this is the best answer (which is pretty much what asmak had):

    SWIG_AsVal_dec(unsigned long)(SV *obj, unsigned long *val)
    {
    if (SvUOK(obj)) {
    if (val) *val = SvUV(obj);
    return SWIG_OK;
    } else if (SvIOK(obj)) {
    /* Many Perl ports apparently lose track of the unsigned/signed nature of a scalar value. */
    if (val) *val = (unsigned long)SvIV(obj);
    return SWIG_OK;
    } else {
    .....

     
  • Nik Clayton
    Nik Clayton
    2007-03-03

    Logged In: YES
    user_id=189581
    Originator: NO

    That would work.

    While we wait for an official fix, is there an easy way for third party projects that use Swig to override this locally? Specifically, I'm thinking of Subversion, where I've just bumped in to this problem as I expand the Subversion Perl bindings. I'd like to get a local fix in to the Subversion tree now (so that we don't need to be dependent on your release schedule), but I'm not sure how best to make the fix.

    I tried copy/pasting the affected code from perlprimtypes.swg in to one of our .i files, but that didn't seem to have an effect on the code generated by Swig.

     
  • Olly Betts
    Olly Betts
    2007-03-05

    Logged In: YES
    user_id=14972
    Originator: NO

    Sorry, I'm not sure how (or if) you can override an individual macro in the UTL stuff. Try asking on the mailing list.

     
  • Robert Stone
    Robert Stone
    2011-09-11

    I've put some time into this, and committed r12802 to trunk. I think the primary issue was that the typemaps didn't seem to be aware that SvIOK(sv) returns true for a UV that is larger than IV_MAX. This was actually news to me too. I've set up better testcases around the integer boundaries and retooled the typemaps to be more cautious.

     
  • Robert Stone
    Robert Stone
    2011-09-11

    • assigned_to: olly --> talby
     
  • Robert Stone
    Robert Stone
    2011-09-11

    • status: open --> closed-fixed