diff --git a/CMakeLists.txt b/CMakeLists.txt index 02aa3697d00..43820159456 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -523,9 +523,7 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") -fsanitize=enum \ -fsanitize=float-cast-overflow \ -fsanitize=float-divide-by-zero \ --fsanitize=leak \ -fsanitize=nonnull-attribute \ --fsanitize=object-size \ -fsanitize=returns-nonnull-attribute \ -fsanitize=signed-integer-overflow \ -fsanitize=undefined \ @@ -533,6 +531,9 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") -fno-sanitize=alignment \ ") + if(NOT MSVC) # not all sanitizers are supported with clang-cl, these two however are very vocal about it + set(_asan_defaults "${_asan_defaults} -fsanitize=leak -fsanitize=object-size" ) + endif() set(COMPILER_ASAN_CFLAGS "${_asan_defaults}" CACHE STRING "C flags for address sanitizer") mark_as_advanced(COMPILER_ASAN_CFLAGS) set(COMPILER_ASAN_CXXFLAGS "${_asan_defaults}" CACHE STRING "C++ flags for address sanitizer") @@ -540,9 +541,15 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") unset(_asan_defaults) - find_library(COMPILER_ASAN_LIBRARY asan ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}) + if(NOT MSVC) + find_library(COMPILER_ASAN_LIBRARY asan ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}) + else() + find_library( COMPILER_ASAN_LIBRARY NAMES clang_rt.asan-x86_64 + PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\LLVM\\LLVM;]/lib/clang/7.0.0/lib/windows + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\LLVM\\LLVM;]/lib/clang/6.0.0/lib/windows + ) + endif() mark_as_advanced(COMPILER_ASAN_LIBRARY) - endif() endif() @@ -816,8 +823,12 @@ if(WITH_COMPILER_ASAN) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMPILER_ASAN_CXXFLAGS}") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMPILER_ASAN_CXXFLAGS}") - - set(PLATFORM_LINKFLAGS_DEBUG "${COMPILER_ASAN_LIBRARY}") + if(MSVC) + set(COMPILER_ASAN_LINKER_FLAGS "/FUNCTIONPADMIN:6") + endif() + set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS};${COMPILER_ASAN_LIBRARY}") + set(PLATFORM_LINKFLAGS "${COMPILER_ASAN_LIBRARY} ${COMPILER_ASAN_LINKER_FLAGS}") + set(PLATFORM_LINKFLAGS_DEBUG "${COMPILER_ASAN_LIBRARY} ${COMPILER_ASAN_LINKER_FLAGS}") endif() #----------------------------------------------------------------------------- diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index a38a6805274..6157730af8e 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -352,6 +352,11 @@ function(SETUP_LIBDIRS) endif() endfunction() +macro(setup_platform_linker_flags) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}") + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}") +endmacro() + function(setup_liblinks target ) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index c14f6013394..f55178b89e2 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -149,7 +149,7 @@ set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MT") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MT") -set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO ") +set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO ") set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib ") # Ignore meaningless for us linker warnings. @@ -162,7 +162,7 @@ else() set(PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ${PLATFORM_LINKFLAGS}") endif() -set(PLATFORM_LINKFLAGS_DEBUG "/IGNORE:4099 /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libc.lib") +set(PLATFORM_LINKFLAGS_DEBUG "${PLATFORM_LINKFLAGS_DEBUG} /IGNORE:4099 /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libc.lib") if(NOT DEFINED LIBDIR) diff --git a/build_files/windows/configure_msbuild.cmd b/build_files/windows/configure_msbuild.cmd index f06f3e317ee..eee21f568be 100644 --- a/build_files/windows/configure_msbuild.cmd +++ b/build_files/windows/configure_msbuild.cmd @@ -12,6 +12,14 @@ if "%BUILD_ARCH%"=="x64" ( if "%WITH_CLANG%"=="1" ( set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -T"LLVM-vs2017" + if "%WITH_ASAN%"=="1" ( + set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DWITH_COMPILER_ASAN=On + ) +) else ( + if "%WITH_ASAN%"=="1" ( + echo ASAN is only supported with clang. + exit /b 1 + ) ) if NOT EXIST %BUILD_DIR%\nul ( diff --git a/build_files/windows/configure_ninja.cmd b/build_files/windows/configure_ninja.cmd index f882ca3dbf0..d3b002e9a24 100644 --- a/build_files/windows/configure_ninja.cmd +++ b/build_files/windows/configure_ninja.cmd @@ -27,6 +27,16 @@ set LLVM_DIR= rem build and tested against 2017 15.7 set CFLAGS=-m64 -fmsc-version=1914 set CXXFLAGS=-m64 -fmsc-version=1914 + if "%WITH_ASAN%"=="1" ( + set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DWITH_COMPILER_ASAN=On + ) +) + +if "%WITH_ASAN%"=="1" ( + if "%WITH_CLANG%" == "" ( + echo ASAN is only supported with clang. + exit /b 1 + ) ) if NOT "%verbose%" == "" ( diff --git a/build_files/windows/parse_arguments.cmd b/build_files/windows/parse_arguments.cmd index a8956d350ae..2cc0acfd243 100644 --- a/build_files/windows/parse_arguments.cmd +++ b/build_files/windows/parse_arguments.cmd @@ -42,6 +42,8 @@ if NOT "%1" == "" ( ) else if "%1" == "release" ( set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -C"%BLENDER_DIR%\build_files\cmake\config\blender_release.cmake" set TARGET=Release + ) else if "%1" == "asan" ( + set WITH_ASAN=1 ) else if "%1" == "x86" ( set BUILD_ARCH=x86 ) else if "%1" == "x64" ( diff --git a/build_files/windows/reset_variables.cmd b/build_files/windows/reset_variables.cmd index d9a50a7f809..f933729b91c 100644 --- a/build_files/windows/reset_variables.cmd +++ b/build_files/windows/reset_variables.cmd @@ -21,4 +21,5 @@ set BUILD_UPDATE= set BUILD_SHOW_HASHES= set SHOW_HELP= set BUILD_WITH_NINJA= -set WITH_CLANG= \ No newline at end of file +set WITH_CLANG= +set WITH_ASAN= \ No newline at end of file diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 03d24c04e2a..6fe650f3699 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -1173,7 +1173,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph, * freed data from the blender side. */ if(preview && b_ob.type() != BL::Object::type_MESH) - b_ob.update_from_editmode(); + b_ob.update_from_editmode(b_data); bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); diff --git a/source/blender/datatoc/CMakeLists.txt b/source/blender/datatoc/CMakeLists.txt index af7f954cad1..0c68cdeb8e9 100644 --- a/source/blender/datatoc/CMakeLists.txt +++ b/source/blender/datatoc/CMakeLists.txt @@ -37,7 +37,7 @@ if(NOT WITH_HEADLESS) set(SRC datatoc_icon.c ) - + setup_platform_linker_flags() if(WIN32) include_directories( ../blenlib @@ -52,8 +52,6 @@ if(NOT WITH_HEADLESS) ../../../intern/utfconv/utfconv.c ) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}") - set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}") endif() include_directories(${PNG_INCLUDE_DIRS}) diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index b3a2f6f7ca6..e3458bcb278 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -129,9 +129,9 @@ bool ED_object_editmode_exit_ex( struct Scene *scene, struct Object *obedit, int flag); bool ED_object_editmode_exit(struct bContext *C, int flag); -bool ED_object_editmode_enter_ex(struct Scene *scene, struct Object *ob, int flag); +bool ED_object_editmode_enter_ex(struct Main *bmain, struct Scene *scene, struct Object *ob, int flag); bool ED_object_editmode_enter(struct bContext *C, int flag); -bool ED_object_editmode_load(struct Object *obedit); +bool ED_object_editmode_load(struct Main *bmain, struct Object *obedit); bool ED_object_editmode_calc_active_center(struct Object *obedit, const bool select_only, float r_center[3]); diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index a3cbdb57fed..7fe252309de 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -164,8 +164,10 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) limit_precision = RNA_boolean_get(op->ptr, "limit_precision"); keep_bind_info = RNA_boolean_get(op->ptr, "keep_bind_info"); + Main *bmain = CTX_data_main(C); + /* get editmode results */ - ED_object_editmode_load(CTX_data_edit_object(C)); + ED_object_editmode_load(bmain, CTX_data_edit_object(C)); Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 9af8169ae41..6dd6a76f129 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -625,7 +625,7 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re /* create new mesh with edit mode changes and modifiers applied */ static Mesh *bake_mesh_new_from_object(Depsgraph *depsgraph, Main *bmain, Scene *scene, Object *ob) { - ED_object_editmode_load(ob); + ED_object_editmode_load(bmain, ob); Mesh *me = BKE_mesh_new_from_object(depsgraph, bmain, scene, ob, 1, 0, 0); if (me->flag & ME_AUTOSMOOTH) { diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index b27e0c96660..5c7c56f9b18 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -149,13 +149,13 @@ Object *ED_object_active_context(bContext *C) /* ******************* toggle editmode operator ***************** */ -static bool mesh_needs_keyindex(const Mesh *me) +static bool mesh_needs_keyindex(Main *bmain, const Mesh *me) { if (me->key) { return false; /* will be added */ } - for (const Object *ob = G.main->object.first; ob; ob = ob->id.next) { + for (const Object *ob = bmain->object.first; ob; ob = ob->id.next) { if ((ob->parent) && (ob->parent->data == me) && ELEM(ob->partype, PARVERT1, PARVERT3)) { return true; } @@ -263,10 +263,9 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f return true; } -bool ED_object_editmode_load(Object *obedit) +bool ED_object_editmode_load(Main *bmain, Object *obedit) { - /* TODO(sergey): use proper main here? */ - return ED_object_editmode_load_ex(G.main, obedit, false); + return ED_object_editmode_load_ex(bmain, obedit, false); } /** @@ -324,7 +323,7 @@ bool ED_object_editmode_exit(bContext *C, int flag) return ED_object_editmode_exit_ex(scene, obedit, flag); } -bool ED_object_editmode_enter_ex(Scene *scene, Object *ob, int flag) +bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag) { bool ok = false; @@ -351,7 +350,8 @@ bool ED_object_editmode_enter_ex(Scene *scene, Object *ob, int flag) if (ob->type == OB_MESH) { BMEditMesh *em; ok = 1; - const bool use_key_index = mesh_needs_keyindex(ob->data); + + const bool use_key_index = mesh_needs_keyindex(bmain, ob->data); EDBM_mesh_make(ob, scene->toolsettings->selectmode, use_key_index); @@ -414,6 +414,7 @@ bool ED_object_editmode_enter_ex(Scene *scene, Object *ob, int flag) bool ED_object_editmode_enter(bContext *C, int flag) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob; @@ -427,7 +428,7 @@ bool ED_object_editmode_enter(bContext *C, int flag) if ((ob == NULL) || ID_IS_LINKED(ob)) { return false; } - return ED_object_editmode_enter_ex(scene, ob, flag); + return ED_object_editmode_enter_ex(bmain, scene, ob, flag); } static int editmode_toggle_exec(bContext *C, wmOperator *op) @@ -435,6 +436,7 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op) struct wmMsgBus *mbus = CTX_wm_message_bus(C); const int mode_flag = OB_MODE_EDIT; const bool is_mode_set = (CTX_data_edit_object(C) != NULL); + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *obact = OBACT(view_layer); @@ -451,7 +453,7 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op) FOREACH_SELECTED_OBJECT_BEGIN(view_layer, ob) { if ((ob != obact) && (ob->type == obact->type)) { - ED_object_editmode_enter_ex(scene, ob, EM_WAITCURSOR | EM_NO_CONTEXT); + ED_object_editmode_enter_ex(bmain, scene, ob, EM_WAITCURSOR | EM_NO_CONTEXT); } } FOREACH_SELECTED_OBJECT_END; diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 0e30c43998e..5ad107c5d3b 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -98,7 +98,7 @@ static void do_outliner_activate_obdata(bContext *C, Scene *scene, ViewLayer *vi ok = ED_object_editmode_exit_ex(scene, ob, EM_FREEDATA | EM_WAITCURSOR); } else { - ok = ED_object_editmode_enter_ex(scene, ob, EM_WAITCURSOR | EM_NO_CONTEXT); + ok = ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_WAITCURSOR | EM_NO_CONTEXT); } if (ok) { ED_object_base_select(base, (ob->mode & OB_MODE_EDIT) ? BA_SELECT : BA_DESELECT); diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index caa3ba593fb..6968702b958 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -114,9 +114,10 @@ static void sequencer_generic_invoke_path__internal(bContext *C, wmOperator *op, Scene *scene = CTX_data_scene(C); Sequence *last_seq = BKE_sequencer_active_get(scene); if (last_seq && last_seq->strip && SEQ_HAS_PATH(last_seq)) { + Main *bmain = CTX_data_main(C); char path[FILE_MAX]; BLI_strncpy(path, last_seq->strip->dir, sizeof(path)); - BLI_path_abs(path, G.main->name); + BLI_path_abs(path, bmain->name); RNA_string_set(op->ptr, identifier, path); } } @@ -173,8 +174,10 @@ static void sequencer_generic_invoke_xy__internal(bContext *C, wmOperator *op, i } } -static void seq_load_operator_info(SeqLoadInfo *seq_load, wmOperator *op) +static void seq_load_operator_info(SeqLoadInfo *seq_load, bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); + PropertyRNA *prop; const bool relative = (prop = RNA_struct_find_property(op->ptr, "relative_path")) && RNA_property_boolean_get(op->ptr, prop); int is_file = -1; @@ -196,7 +199,7 @@ static void seq_load_operator_info(SeqLoadInfo *seq_load, wmOperator *op) } if ((is_file != -1) && relative) - BLI_path_rel(seq_load->path, G.main->name); + BLI_path_rel(seq_load->path, bmain->name); if ((prop = RNA_struct_find_property(op->ptr, "frame_end"))) { @@ -545,7 +548,7 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad SeqLoadInfo seq_load; int tot_files; - seq_load_operator_info(&seq_load, op); + seq_load_operator_info(&seq_load, C, op); if (seq_load.flag & SEQ_LOAD_REPLACE_SEL) ED_sequencer_deselect_all(scene); @@ -855,7 +858,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) StripElem *se; const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders"); - seq_load_operator_info(&seq_load, op); + seq_load_operator_info(&seq_load, C, op); /* images are unique in how they handle this - 1 per strip elem */ if (use_placeholders) { diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index d82028ef2c9..999e0fbf2a4 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -3865,13 +3865,14 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot) static int sequencer_export_subtitles_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { + Main *bmain = CTX_data_main(C); if (!RNA_struct_property_is_set(op->ptr, "filepath")) { char filepath[FILE_MAX]; - if (G.main->name[0] == 0) + if (bmain->name[0] == '\0') BLI_strncpy(filepath, "untitled", sizeof(filepath)); else - BLI_strncpy(filepath, G.main->name, sizeof(filepath)); + BLI_strncpy(filepath, bmain->name, sizeof(filepath)); BLI_replace_extension(filepath, sizeof(filepath), ".srt"); RNA_string_set(op->ptr, "filepath", filepath); diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 6751577bfda..0672a8ab763 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -210,7 +210,7 @@ bool ED_editors_flush_edits(const bContext *C, bool for_render) else if (ob->mode & OB_MODE_EDIT) { /* get editmode results */ has_edited = true; - ED_object_editmode_load(ob); + ED_object_editmode_load(bmain, ob); } } diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index 5b8dcd97108..06fd23cdff2 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -53,6 +53,7 @@ endif() # SRC_DNA_INC is defined in the parent dir add_cc_flags_custom_test(makesdna) +setup_platform_linker_flags() add_executable(makesdna ${SRC} ${SRC_DNA_INC}) diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index c62e8ed4da8..134ec2cc170 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -352,6 +352,7 @@ blender_include_dirs_sys( ) add_cc_flags_custom_test(makesrna) +setup_platform_linker_flags() add_executable(makesrna ${SRC} ${SRC_RNA_INC} ${SRC_DNA_INC}) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index a01192dad68..a837a2ff032 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -445,10 +445,10 @@ void rna_Object_dm_info(struct Object *ob, int type, char *result) } #endif /* NDEBUG */ -static int rna_Object_update_from_editmode(Object *ob) +static int rna_Object_update_from_editmode(Object *ob, Main *bmain) { /* fail gracefully if we aren't in edit-mode. */ - return ED_object_editmode_load(ob); + return ED_object_editmode_load(bmain, ob); } #else /* RNA_RUNTIME */ @@ -676,6 +676,7 @@ void RNA_api_object(StructRNA *srna) func = RNA_def_function(srna, "update_from_editmode", "rna_Object_update_from_editmode"); RNA_def_function_ui_description(func, "Load the objects edit-mode data into the object data"); + RNA_def_function_flag(func, FUNC_USE_MAIN); parm = RNA_def_boolean(func, "result", 0, "", "Success"); RNA_def_function_return(func, parm);