diff --git a/cmake/platform/gcc.cmake b/cmake/platform/gcc.cmake index 480ebb7..1d79ec4 100644 --- a/cmake/platform/gcc.cmake +++ b/cmake/platform/gcc.cmake @@ -39,18 +39,29 @@ UNSET(RP_C11_CFLAG) UNSET(RP_CXX11_CXXFLAG) # Test for common CFLAGS and CXXFLAGS. -FOREACH(FLAG_TEST "-Wall" "-Wextra" "-Wno-multichar" "-fstrict-aliasing" "-fno-common") - CHECK_C_COMPILER_FLAG("${FLAG_TEST}" CFLAG_${FLAG_TEST}) - IF(CFLAG_${FLAG_TEST}) - SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}") - ENDIF(CFLAG_${FLAG_TEST}) - UNSET(CFLAG_${FLAG_TEST}) +# NOTE: Not adding -Werror=format-nonliteral because there are some +# legitimate uses of non-literal format strings. +SET(CFLAGS_WARNINGS -Wall -Wextra -Wno-multichar -Werror=return-type) +SET(CFLAGS_WERROR_FORMAT -Werror=format -Werror=format-security -Werror=format-signedness -Werror=format-truncation -Werror=format-y2k) +IF(MINGW) + # MinGW: Ignore warnings caused by casting from GetProcAddress(). + SET(CFLAGS_WARNINGS ${CFLAGS_WARNINGS} -Wno-cast-function-type) +ENDIF(MINGW) +FOREACH(FLAG_TEST ${CFLAGS_WARNINGS} ${CFLAGS_WERROR_FORMAT} "-fstrict-aliasing" "-fno-common" "-fcf-protection") + # CMake doesn't like certain characters in variable names. + STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") - CHECK_CXX_COMPILER_FLAG("${FLAG_TEST}" CXXFLAG_${FLAG_TEST}) - IF(CXXFLAG_${FLAG_TEST}) + CHECK_C_COMPILER_FLAG("${FLAG_TEST}" CFLAG_${FLAG_TEST_VARNAME}) + IF(CFLAG_${FLAG_TEST_VARNAME}) + SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}") + ENDIF(CFLAG_${FLAG_TEST_VARNAME}) + UNSET(CFLAG_${FLAG_TEST_VARNAME}) + + CHECK_CXX_COMPILER_FLAG("${FLAG_TEST}" CXXFLAG_${FLAG_TEST_VARNAME}) + IF(CXXFLAG_${FLAG_TEST_VARNAME}) SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}") - ENDIF(CXXFLAG_${FLAG_TEST}) - UNSET(CXXFLAG_${FLAG_TEST}) + ENDIF(CXXFLAG_${FLAG_TEST_VARNAME}) + UNSET(CXXFLAG_${FLAG_TEST_VARNAME}) ENDFOREACH() # -Wimplicit-function-declaration should be an error. (C only) @@ -60,6 +71,18 @@ IF(CFLAG_IMPLFUNC) ENDIF(CFLAG_IMPLFUNC) UNSET(CFLAG_IMPLFUNC) +# Enable "suggest override" if available. (C++ only) +# NOTE: If gcc, only enable on 9.2 and later, since earlier versions +# will warn if a function is marked 'final' but not 'override' +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78010 +IF(NOT CMAKE_COMPILER_IS_GNUCC OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 9.1)) + CHECK_CXX_COMPILER_FLAG("-Wsuggest-override" CXXFLAG_SUGGEST_OVERRIDE) + IF(CXXFLAG_SUGGEST_OVERRIDE) + SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} -Wsuggest-override -Wno-error=suggest-override") + ENDIF(CXXFLAG_SUGGEST_OVERRIDE) + UNSET(CXXFLAG_SUGGEST_OVERRIDE) +ENDIF(NOT CMAKE_COMPILER_IS_GNUCC OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 9.1)) + # Code coverage checking. IF(ENABLE_COVERAGE) # Partially based on: @@ -113,7 +136,7 @@ EXECUTE_PROCESS(COMMAND ${CMAKE_LINKER} --help OUTPUT_VARIABLE _ld_out ERROR_QUIET) -FOREACH(FLAG_TEST "--sort-common" "--as-needed" "--build-id") +FOREACH(FLAG_TEST "--sort-common" "--as-needed" "--build-id" "-Bsymbolic-functions") IF(NOT DEFINED LDFLAG_${FLAG_TEST}) MESSAGE(STATUS "Checking if ld supports ${FLAG_TEST}") IF(_ld_out MATCHES "${FLAG_TEST}") diff --git a/cmake/platform/msvc.cmake b/cmake/platform/msvc.cmake index a974c6c..dd10d04 100644 --- a/cmake/platform/msvc.cmake +++ b/cmake/platform/msvc.cmake @@ -13,35 +13,85 @@ ENDIF() # probably cause a linker error. # - C4024: 'function': different types for formal and actual parameter n # - C4047: 'function': 'parameter' differs in levels of indirection from 'argument' -SET(RP_C_FLAGS_COMMON "/nologo /wd4355 /wd4482 /we4013 /we4024 /we4047 -D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE") +SET(RP_C_FLAGS_COMMON "/nologo /wd4355 /wd4482 /we4013 /we4024 /we4047") SET(RP_CXX_FLAGS_COMMON "${RP_C_FLAGS_COMMON} -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") +ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) # NOTE: /TSAWARE is automatically set for Windows 2000 and later. (as of at least Visual Studio .NET 2003) # NOTE 2: /TSAWARE is not applicable for DLLs. SET(RP_EXE_LINKER_FLAGS_COMMON "/NOLOGO /DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE") SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON}") SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON}") +# Enable /EHsc if it isn't enabled already. +# Default in most cases; not enabled for MSVC 2019 on ARM or ARM64. +IF(NOT CMAKE_CXX_FLAGS MATCHES "/EHsc") + SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /EHsc") +ENDIF(NOT CMAKE_CXX_FLAGS MATCHES "/EHsc") + # Test for MSVC-specific compiler flags. # /utf-8 was added in MSVC 2015. INCLUDE(CheckCCompilerFlag) FOREACH(FLAG_TEST "/sdl" "/guard:cf" "/utf-8") # CMake doesn't like certain characters in variable names. - STRING(REGEX REPLACE "/|:" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") + STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") CHECK_C_COMPILER_FLAG("${FLAG_TEST}" CFLAG_${FLAG_TEST_VARNAME}) IF(CFLAG_${FLAG_TEST_VARNAME}) SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}") SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}") - IF(FLAG_TEST STREQUAL "/guard:cf") - # "/guard:cf" must be added to linker flags as well. - SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON} ${FLAG_TEST}") - SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_SHARED_LINKER_FLAGS_COMMON} ${FLAG_TEST}") - SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_LINKER_FLAGS_COMMON} ${FLAG_TEST}") - ENDIF(FLAG_TEST STREQUAL "/guard:cf") ENDIF(CFLAG_${FLAG_TEST_VARNAME}) UNSET(CFLAG_${FLAG_TEST_VARNAME}) ENDFOREACH() +# "/guard:cf" must be added to linker flags in addition to CFLAGS. +CHECK_C_COMPILER_FLAG("/guard:cf" CFLAG__guard_cf) +IF(CFLAG_guard_cf) + SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /guard:cf") + SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /guard:cf") + SET(RP_EXE_LINKER_FLAGS_COMMON "${RP_EXE_LINKER_FLAGS_COMMON} /guard:cf") + SET(RP_SHARED_LINKER_FLAGS_COMMON "${RP_SHARED_LINKER_FLAGS_COMMON} /guard:cf") + SET(RP_MODULE_LINKER_FLAGS_COMMON "${RP_MODULE_LINKER_FLAGS_COMMON} /guard:cf") +ENDIF(CFLAG_guard_cf) +UNSET(CFLAG_guard_cf) + +# MSVC: C/C++ conformance settings +FOREACH(FLAG_TEST "/Zc:wchar_t" "/Zc:inline") + # CMake doesn't like certain characters in variable names. + STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") + + CHECK_C_COMPILER_FLAG("${FLAG_TEST}" CFLAG_${FLAG_TEST_VARNAME}) + IF(CFLAG_${FLAG_TEST_VARNAME}) + SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${FLAG_TEST}") + SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}") + ENDIF(CFLAG_${FLAG_TEST_VARNAME}) + UNSET(CFLAG_${FLAG_TEST_VARNAME}) +ENDFOREACH() + +# MSVC: C++ conformance settings +INCLUDE(CheckCXXCompilerFlag) +FOREACH(FLAG_TEST "/Zc:__cplusplus" "/Zc:externC" "/Zc:noexceptTypes" "/Zc:rvalueCast" "/Zc:ternary") + # CMake doesn't like certain characters in variable names. + STRING(REGEX REPLACE "/|:|=" "_" FLAG_TEST_VARNAME "${FLAG_TEST}") + + CHECK_CXX_COMPILER_FLAG("${FLAG_TEST}" CXXFLAG_${FLAG_TEST_VARNAME}) + IF(CXXFLAG_${FLAG_TEST_VARNAME}) + SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${FLAG_TEST}") + ENDIF(CXXFLAG_${FLAG_TEST_VARNAME}) + UNSET(CXXFLAG_${FLAG_TEST_VARNAME}) +ENDFOREACH() + +# "/Zc:throwingNew" is always enabled on clang-cl, and causes +# warnings to be printed if it's specified. +# NOTE: "/Zc:throwingNew" was added in MSVC 2015. +IF(NOT CMAKE_CXX_COMPILER_ID STREQUAL Clang) + INCLUDE(CheckCXXCompilerFlag) + CHECK_CXX_COMPILER_FLAG("/Zc:throwingNew" CXXFLAG_Zc_throwingNew) + IF(CXXFLAG_Zc_throwingNew) + SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} /Zc:throwingNew") + ENDIF(CXXFLAG_Zc_throwingNew) + UNSET(CXXFLAG_Zc_throwingNew) +ENDIF(NOT CMAKE_CXX_COMPILER_ID STREQUAL Clang) + # Disable warning C4996 (deprecated), then re-enable it. # Otherwise, it gets handled as an error due to /sdl. SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} /wd4996 /w34996") diff --git a/cmake/platform/win32-msvc.cmake b/cmake/platform/win32-msvc.cmake index d6e339e..1998c35 100644 --- a/cmake/platform/win32-msvc.cmake +++ b/cmake/platform/win32-msvc.cmake @@ -1,12 +1,6 @@ # Win32-specific CFLAGS/CXXFLAGS. # For Microsoft Visual C++ compilers. -# Basic platform flags for MSVC: -# - wchar_t should be a distinct type. (MSVC 2002+) -IF(MSVC_VERSION GREATER 1200) - SET(RP_C_FLAGS_WIN32 "${RP_C_FLAGS_WIN32} /Zc:wchar_t") -ENDIF() - # NOTE: This program is Unicode only on Windows. # No ANSI support. @@ -49,8 +43,8 @@ SET(RP_LINKER_FLAGS_CONSOLE_EXE "/SUBSYSTEM:CONSOLE,${RP_WIN32_SUBSYSTEM_VERSION UNSET(RP_WIN32_SUBSYSTEM_VERSION) # Append the CFLAGS and LDFLAGS. -SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${RP_C_FLAGS_WIN32}") -SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${RP_C_FLAGS_WIN32} ${RP_CXX_FLAGS_WIN32}") +SET(RP_C_FLAGS_COMMON "${RP_C_FLAGS_COMMON} ${RP_C_FLAGS_WIN32}") +SET(RP_CXX_FLAGS_COMMON "${RP_CXX_FLAGS_COMMON} ${RP_C_FLAGS_WIN32} ${RP_CXX_FLAGS_WIN32}") # Unset temporary variables. UNSET(RP_C_FLAGS_WIN32) diff --git a/src/librvth/recrypt.cpp b/src/librvth/recrypt.cpp index 4b035c2..cb8360e 100644 --- a/src/librvth/recrypt.cpp +++ b/src/librvth/recrypt.cpp @@ -126,10 +126,10 @@ static int rvth_create_id(uint8_t *id, size_t size, } strftime(ts, sizeof(ts), "%Y/%m/%d %H:%M:%S", &tmbuf_local); if (extra) { - snprintf((char*)&buf[sizeof(id_hdr)], 0x40-sizeof(id_hdr), + snprintf((char*)&buf[sizeof(id_hdr)], /*0x40*/ sizeof(buf)-sizeof(id_hdr), "%s, %s %s", extra, ts, tzval); } else { - snprintf((char*)&buf[sizeof(id_hdr)], 0x40-sizeof(id_hdr), + snprintf((char*)&buf[sizeof(id_hdr)], /*0x40*/ sizeof(buf)-sizeof(id_hdr), "%s %s", ts, tzval); } diff --git a/src/librvth/rvth_time.c b/src/librvth/rvth_time.c index c53807d..a2a4633 100644 --- a/src/librvth/rvth_time.c +++ b/src/librvth/rvth_time.c @@ -102,7 +102,7 @@ int rvth_timestamp_create(char *buf, size_t size, time_t now) // We can't snprintf() directly to nhcd_entry.timestamp because // gcc will complain about buffer overflows, and will crash at // runtime on Gentoo Hardened. - char tsbuf[16]; + char tsbuf[32]; // Validate the parameters. if (!buf || size == 0) { diff --git a/src/qrvthtool/widgets/BankEntryView.cpp b/src/qrvthtool/widgets/BankEntryView.cpp index 4a6b879..5354655 100644 --- a/src/qrvthtool/widgets/BankEntryView.cpp +++ b/src/qrvthtool/widgets/BankEntryView.cpp @@ -143,7 +143,7 @@ QString BankEntryViewPrivate::formatFileSize(quint64 size) if (size >= (2LL << 10)) { // Fractional part. - unsigned int frac_digits = 2; + int frac_digits = 2; if (whole_part >= 10) { unsigned int round_adj = (frac_part % 10 > 5); frac_part /= 10; diff --git a/src/qrvthtool/widgets/BankEntryView.hpp b/src/qrvthtool/widgets/BankEntryView.hpp index b6c5a35..bd2eabd 100644 --- a/src/qrvthtool/widgets/BankEntryView.hpp +++ b/src/qrvthtool/widgets/BankEntryView.hpp @@ -52,7 +52,7 @@ class BankEntryView : public QWidget protected: // State change event. (Used for switching the UI language at runtime.) - void changeEvent(QEvent *event); + void changeEvent(QEvent *event) final; }; #endif /* __RVTHTOOL_QRVTHTOOL_WIDGETS_BANKENTRYVIEW_HPP__ */ diff --git a/src/rvthtool/list-banks.cpp b/src/rvthtool/list-banks.cpp index bc776d6..da76698 100644 --- a/src/rvthtool/list-banks.cpp +++ b/src/rvthtool/list-banks.cpp @@ -225,8 +225,8 @@ int print_bank(const RvtH *rvth, unsigned int bank) case APLERR_DOL_EXCEEDS_SIZE_LIMIT: printf("Total size of text/data sections of the dol file are too big (%d(0x%08x) bytes).\n" "APPLOADER ERROR >>> Currently the limit is set as %d(0x%08x) bytes.\n", - entry->aplerr_val[0], entry->aplerr_val[0], - entry->aplerr_val[1], entry->aplerr_val[1]); + static_cast(entry->aplerr_val[0]), entry->aplerr_val[0], + static_cast(entry->aplerr_val[1]), entry->aplerr_val[1]); break; case APLERR_DOL_ADDR_LIMIT_RETAIL_EXCEEDED: printf("One of the sections in the dol file exceeded its boundary.\n" diff --git a/src/rvthtool/verify.cpp b/src/rvthtool/verify.cpp index b70e6d4..5e83df0 100644 --- a/src/rvthtool/verify.cpp +++ b/src/rvthtool/verify.cpp @@ -66,7 +66,7 @@ static bool progress_callback(const RvtH_Verify_Progress_State *state, void *use break; case RVTH_VERIFY_STATUS: { - printf("\rPartition %u/%u (%s): %4u MiB / %4u MiB checked...", + printf("\rPartition %d/%u (%s): %4u MiB / %4u MiB checked...", pt_current, state->pt_total, ps_pt_type, state->group_cur * 2, state->group_total * 2); diff --git a/src/wadresign/print-info.c b/src/wadresign/print-info.c index 0cf26b0..6f57a6b 100644 --- a/src/wadresign/print-info.c +++ b/src/wadresign/print-info.c @@ -413,7 +413,9 @@ int print_wad_info_FILE(FILE *f_wad, const TCHAR *wad_filename, bool verify) // Title version title_version = be16_to_cpu(tmdHeader->title_version); printf("- Title version: %u.%u (v%u)\n", - title_version >> 8, title_version & 0xFF, title_version); + (unsigned int)(title_version >> 8), + (unsigned int)(title_version & 0xFF), + title_version); // IOS version // TODO: Error message if not an IOS?