Fix R function pointer wrappers containing lvalue and rvalue reference parameters

This commit is contained in:
William S Fulton 2017-06-16 07:02:07 +01:00
commit 6a7cd97fe9
4 changed files with 30 additions and 15 deletions

View file

@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.0.0 (in progress)
===========================
2017-06-16: wsfulton
[R] Fix wrapping function pointers containing rvalue and lvalue reference parameters.
2017-06-13: olly
[Perl] Fix testsuite to work without . in @INC - it was removed in
Perl 5.26 for security reasons, and has also been removed from

View file

@ -55,10 +55,11 @@ short && func(short &&i) { return std::move(i); }
Thingy getit() { return Thingy(22, std::move(glob)); }
void rvalrefFunction1(int &&v = (int &&)5) {}
void rvalrefFunctionBYVAL(short (Thingy::*memFunc)(short)) {}
void rvalrefFunctionLVALUE(short &(Thingy::*memFunc)(short &)) {}
void rvalrefFunction2(short && (Thingy::*memFunc)(short &&)) {}
void rvalrefFunction3(short && (*memFunc)(short &&)) {}
void rvalrefFunctionBYVAL(short (Thingy::*fptr)(short)) {}
void rvalrefFunctionPTR(short * (*fptr)(short *)) {}
void rvalrefFunctionLVALUE(short & (Thingy::*fptr)(short &)) {}
void rvalrefFunction2(short && (Thingy::*fptr)(short &&)) {}
void rvalrefFunction3(short && (*fptr)(short &&)) {}
template <typename T> struct RemoveReference {
typedef T type;

View file

@ -15,6 +15,8 @@ int & addByReference(const int &a, int b) { static int val; val = a+b; return va
int call1(int (*d)(const int &, int), int a, int b) { return d(a, b); }
int call2(int * (*d)(const int &, int), int a, int b) { return *d(a, b); }
int call3(int & (*d)(const int &, int), int a, int b) { return d(a, b); }
int call4(int & (*d)(int &, int *), int a, int b) { return d(a, &b); }
int call5(int & (*d)(int &, int const * const), int a, int b) { return d(a, &b); }
%}
%constant int (*ADD_BY_VALUE)(const int &, int) = addByValue;

View file

@ -573,7 +573,7 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
String *lname;
if (!arg && Cmp(Getattr(p, "type"), "void")) {
lname = NewStringf("s_arg%d", i+1);
lname = NewStringf("arg%d", i+1);
Setattr(p, "name", lname);
} else
lname = arg;
@ -616,19 +616,25 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
for(i = 0; p; i++) {
SwigType *tt = Getattr(p, "type");
SwigType *name = Getattr(p, "name");
SwigType *swig_parm_name = NewStringf("swigarg_%s", name);
String *tm = Getattr(p, "tmap:out");
Printf(f->def, "%s %s", SwigType_str(tt, 0), name);
if(tm) {
Replaceall(tm, "$1", name);
if (SwigType_isreference(tt)) {
String *tmp = NewString("");
Append(tmp, "*");
Append(tmp, name);
Replaceall(tm, tmp, name);
bool isVoidParm = Strcmp(tt, "void") == 0;
if (isVoidParm)
Printf(f->def, "%s", SwigType_str(tt, 0));
else
Printf(f->def, "%s %s", SwigType_str(tt, 0), swig_parm_name);
if (tm) {
String *lstr = SwigType_lstr(tt, 0);
if (SwigType_isreference(tt) || SwigType_isrvalue_reference(tt)) {
Printf(f->code, "%s = (%s) &%s;\n", Getattr(p, "lname"), lstr, swig_parm_name);
} else if (!isVoidParm) {
Printf(f->code, "%s = (%s) %s;\n", Getattr(p, "lname"), lstr, swig_parm_name);
}
Replaceall(tm, "$1", name);
Replaceall(tm, "$result", "r_tmp");
replaceRClass(tm, Getattr(p,"type"));
Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
Delete(lstr);
}
Printf(setExprElements, "%s\n", tm);
@ -697,10 +703,13 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
Printv(f->code, "R_SWIG_popCallbackFunctionData(1);\n", NIL);
Printv(f->code, "\n", UnProtectWrapupCode, NIL);
if (SwigType_isreference(rettype)) {
if (SwigType_isreference(rettype)) {
Printv(f->code, "return *", Swig_cresult_name(), ";\n", NIL);
} else if(!isVoidType)
} else if (SwigType_isrvalue_reference(rettype)) {
Printv(f->code, "return std::move(*", Swig_cresult_name(), ");\n", NIL);
} else if (!isVoidType) {
Printv(f->code, "return ", Swig_cresult_name(), ";\n", NIL);
}
Printv(f->code, "\n}\n", NIL);
Replaceall(f->code, "SWIG_exception_fail", "SWIG_exception_noreturn");