Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/werror.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

env:
_R_CHECK_FORCE_SUGGESTS_: "false"
RCPP_CXXFLAGS: "-Werror"
RCPP_CXXFLAGS: "-Werror -Wcast-function-type"

jobs:
ci:
Expand Down
14 changes: 14 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
2026-09-03 Iñaki Ucar <iucar@fedoraproject.org>

* .github/workflows/werror.yaml: Add -Wcast-function-type

* inst/include/Rcpp/routines.h: New function pointer RCPP_FUNC typedef used
as an intermediate cast target to avoid gcc's -Wcast-function-type warnings
* inst/include/Rcpp/Module.h: Idem
* src/rcpp_init.cpp: Idem

* src/attributes.cpp: Generate RCPP_FUNC-routed casts in interface code
* inst/examples/ConvolveBenchmarks/overhead_1.cpp: Update generated code
* inst/tinytest/testRcppInterfaceExporter/src/RcppExports.cpp: Idem
* inst/tinytest/testRcppInterfaceExporter/inst/include/testRcppInterfaceExporter_RcppExports.h: Idem

2026-09-01 Iñaki Ucar <iucar@fedoraproject.org>

* .github/workflows/werror.yaml: Add new CI file with -Werror enabled
Expand Down
2 changes: 1 addition & 1 deletion inst/examples/ConvolveBenchmarks/overhead_1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ SEXP overhead_cpp(SEXP a, SEXP b) {
extern "C" void R_init_overhead_1(DllInfo *info){

R_CallMethodDef callMethods[] = {
{"overhead_cpp", (DL_FUNC) &overhead_cpp, 2},
{"overhead_cpp", (DL_FUNC) (RCPP_FUNC) &overhead_cpp, 2},
{NULL, NULL, 0}
};

Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ namespace Rcpp {
inline int nargs() { return sizeof...(T); }
inline bool is_void() { return std::is_void<RESULT_TYPE>::value; }
inline void signature(std::string& s, const char* name) { Rcpp::signature<RESULT_TYPE, T...>(s, name); }
inline DL_FUNC get_function_ptr() { return (DL_FUNC)ptr_fun; }
inline DL_FUNC get_function_ptr() { return (DL_FUNC)(RCPP_FUNC)ptr_fun; }

private:
RESULT_TYPE (*ptr_fun)(T...);
Expand Down
6 changes: 5 additions & 1 deletion inst/include/Rcpp/routines.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@

#include <Rcpp/iostream/Rstreambuf.h>

// Necessary to cast a function pointer to a seemingly incompatible function
// pointer type while avoiding gcc's -Wcast-function-type warnings.
typedef void (*RCPP_FUNC)(void);

#if defined(COMPILING_RCPP)

// the idea is that this file should be generated automatically by Rcpp::register
Expand Down Expand Up @@ -79,7 +83,7 @@ SEXP rcpp_get_current_error();

namespace Rcpp {

#define GET_CALLABLE(__FUN__) (Fun) R_GetCCallable( "Rcpp", __FUN__ )
#define GET_CALLABLE(__FUN__) (Fun) (RCPP_FUNC) R_GetCCallable( "Rcpp", __FUN__ )

inline attribute_hidden const char* type2name(SEXP x){
typedef const char* (*Fun)(SEXP);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace testRcppInterfaceExporter {
Rcpp::Function require = Rcpp::Environment::base_env()["require"];
require("testRcppInterfaceExporter", Rcpp::Named("quietly") = true);
typedef int(*Ptr_validate)(const char*);
static Ptr_validate p_validate = (Ptr_validate)
static Ptr_validate p_validate = (Ptr_validate) (RCPP_FUNC)
R_GetCCallable("testRcppInterfaceExporter", "_testRcppInterfaceExporter_RcppExport_validate");
if (!p_validate(sig)) {
throw Rcpp::function_not_exported(
Expand All @@ -29,7 +29,7 @@ namespace testRcppInterfaceExporter {
static Ptr_test_cpp_interface p_test_cpp_interface = NULL;
if (p_test_cpp_interface == NULL) {
validateSignature("SEXP(*test_cpp_interface)(SEXP,bool)");
p_test_cpp_interface = (Ptr_test_cpp_interface)R_GetCCallable("testRcppInterfaceExporter", "_testRcppInterfaceExporter_test_cpp_interface");
p_test_cpp_interface = (Ptr_test_cpp_interface) (RCPP_FUNC)R_GetCCallable("testRcppInterfaceExporter", "_testRcppInterfaceExporter_test_cpp_interface");
}
RObject rcpp_result_gen;
{
Expand Down
8 changes: 4 additions & 4 deletions inst/tinytest/testRcppInterfaceExporter/src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ static int _testRcppInterfaceExporter_RcppExport_validate(const char* sig) {

// registerCCallable (register entry points for exported C++ functions)
RcppExport SEXP _testRcppInterfaceExporter_RcppExport_registerCCallable() {
R_RegisterCCallable("testRcppInterfaceExporter", "_testRcppInterfaceExporter_test_cpp_interface", (DL_FUNC)_testRcppInterfaceExporter_test_cpp_interface_try);
R_RegisterCCallable("testRcppInterfaceExporter", "_testRcppInterfaceExporter_RcppExport_validate", (DL_FUNC)_testRcppInterfaceExporter_RcppExport_validate);
R_RegisterCCallable("testRcppInterfaceExporter", "_testRcppInterfaceExporter_test_cpp_interface", (DL_FUNC) (RCPP_FUNC) _testRcppInterfaceExporter_test_cpp_interface_try);
R_RegisterCCallable("testRcppInterfaceExporter", "_testRcppInterfaceExporter_RcppExport_validate", (DL_FUNC) (RCPP_FUNC) _testRcppInterfaceExporter_RcppExport_validate);
return R_NilValue;
}

static const R_CallMethodDef CallEntries[] = {
{"_testRcppInterfaceExporter_test_cpp_interface", (DL_FUNC) &_testRcppInterfaceExporter_test_cpp_interface, 2},
{"_testRcppInterfaceExporter_RcppExport_registerCCallable", (DL_FUNC) &_testRcppInterfaceExporter_RcppExport_registerCCallable, 0},
{"_testRcppInterfaceExporter_test_cpp_interface", (DL_FUNC) (RCPP_FUNC) &_testRcppInterfaceExporter_test_cpp_interface, 2},
{"_testRcppInterfaceExporter_RcppExport_registerCCallable", (DL_FUNC) (RCPP_FUNC) &_testRcppInterfaceExporter_RcppExport_registerCCallable, 0},
{NULL, NULL, 0}
};

Expand Down
8 changes: 4 additions & 4 deletions src/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2103,7 +2103,7 @@ namespace attributes {
ostr() << "static const R_CallMethodDef CallEntries[] = {" << std::endl;
for (std::size_t i=0;i<routineNames.size(); i++) {
ostr() << " {\"" << routineNames[i] << "\", " <<
"(DL_FUNC) &" << routineNames[i] << ", " <<
"(DL_FUNC) (RCPP_FUNC) &" << routineNames[i] << ", " <<
routineArgs[i] << "}," << std::endl;
}
if (callEntries.size() > 0) {
Expand Down Expand Up @@ -2148,7 +2148,7 @@ namespace attributes {
std::string indentStr(indent, ' ');
ostr << indentStr << "R_RegisterCCallable(\"" << package() << "\", "
<< "\"" << packageCppPrefix() << "_" << exportedName << "\", "
<< "(DL_FUNC)" << packageCppPrefix() << "_" << name << ");";
<< "(DL_FUNC) (RCPP_FUNC) " << packageCppPrefix() << "_" << name << ");";
return ostr.str(); // #nocov end
}

Expand Down Expand Up @@ -2221,7 +2221,7 @@ namespace attributes {

std::string ptrName = "p_" + validate;
ostr() << " static " << fnType << " " << ptrName << " = "
<< "(" << fnType << ")" << std::endl
<< "(" << fnType << ") (RCPP_FUNC)" << std::endl
<< " "
<< getCCallable(exportValidationFunctionRegisteredName())
<< ";" << std::endl;
Expand Down Expand Up @@ -2279,7 +2279,7 @@ namespace attributes {
<< "(\"" << function.signature() << "\");"
<< std::endl;
ostr() << " " << ptrName << " = "
<< "(" << fnType << ")"
<< "(" << fnType << ") (RCPP_FUNC)"
<< getCCallable(packageCppPrefix() + "_" + function.name()) << ";"
<< std::endl;
ostr() << " }" << std::endl;
Expand Down
6 changes: 3 additions & 3 deletions src/rcpp_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
#include "internal.h"

// borrowed from Matrix
#define CALLDEF(name, n) {#name, (DL_FUNC) &name, n}
#define EXTDEF(name) {#name, (DL_FUNC) &name, -1}
#define CALLDEF(name, n) {#name, (DL_FUNC) (RCPP_FUNC) &name, n}
#define EXTDEF(name) {#name, (DL_FUNC) (RCPP_FUNC) &name, -1}

static R_CallMethodDef callEntries[] = {
CALLDEF(Class__name,1),
Expand Down Expand Up @@ -89,7 +89,7 @@ void registerFunctions(){
using namespace Rcpp;
using namespace Rcpp::internal;

#define RCPP_REGISTER(__FUN__) R_RegisterCCallable( "Rcpp", #__FUN__ , (DL_FUNC)__FUN__ );
#define RCPP_REGISTER(__FUN__) R_RegisterCCallable( "Rcpp", #__FUN__ , (DL_FUNC) (RCPP_FUNC) __FUN__ );
RCPP_REGISTER(rcpp_get_stack_trace)
RCPP_REGISTER(rcpp_set_stack_trace)
RCPP_REGISTER(type2name)
Expand Down
Loading