diff --git a/build/dehydra/README.txt b/build/dehydra/README.txt index 95ace8e5f9..23fd4f3d0a 100644 --- a/build/dehydra/README.txt +++ b/build/dehydra/README.txt @@ -9,10 +9,40 @@ General usage instructions: * Install Dehydra, as per https://developer.mozilla.org/En/Dehydra/Installing_Dehydra * Build 0 A.D. from build/workspaces/gcc: - export CXX="$HOME/gcc-dehydra/installed/bin/g++ -fplugin=$HOME/gcc-dehydra/dehydra/gcc_treehydra.so -fplugin-arg=../../dehydra/printf-type-check.js -DCONFIG_DEHYDRA=1" + export CXX="$HOME/gcc-dehydra/installed/bin/g++ -fplugin=$HOME/gcc-dehydra/dehydra/gcc_treehydra.so -fplugin-arg-gcc_treehydra-script=../../dehydra/printf-type-check.js -DCONFIG_DEHYDRA=1" make # (or "make test -j3 -k" to build the engine and tests and to do 3 files in parallel and continue past errors, etc) * Wait (it's quite slow) and look for the new compiler warnings/errors. The "tests" directory doesn't actually contain any proper tests, just some example files and expected outputs for rough sanity checking. + + +Some Dehydra fixes might be needed, depending on what version you use, like: + +diff -r 9871caaedb8f dehydra.c +--- a/dehydra.c Sat Mar 12 13:55:41 2011 -0500 ++++ b/dehydra.c Wed May 18 19:27:23 2011 +0100 +@@ -123,7 +123,7 @@ + }; + + this->fndeclMap = pointer_map_create (); +- this->rt = JS_NewRuntime (0x32L * 1024L * 1024L); ++ this->rt = JS_NewRuntime (0x128L * 1024L * 1024L); + if (this->rt == NULL) + exit(1); + +diff -r 9871caaedb8f libs/treehydra.js +--- a/libs/treehydra.js Sat Mar 12 13:55:41 2011 -0500 ++++ b/libs/treehydra.js Wed May 18 19:27:23 2011 +0100 +@@ -209,6 +209,9 @@ + walk_tree (i.stmt (), func, guard, stack); + } + break; ++ case EXPR_STMT: ++ walk_tree (TREE_OPERAND(t, 0), func, guard, stack); ++ break; + case TEMPLATE_PARM_INDEX: + case PTRMEM_CST: + case USING_DECL: + diff --git a/build/dehydra/printf-type-check.js b/build/dehydra/printf-type-check.js index b8c8e64142..7176e30dad 100644 --- a/build/dehydra/printf-type-check.js +++ b/build/dehydra/printf-type-check.js @@ -69,9 +69,11 @@ function find_printf_type(decl, loc) { return ['w', 'printf', 3, 4]; else if (name == 'JS_ReportError') return ['a', 'printf', 2, 3]; + else if (name == 'JS_ReportWarning') + return ['a', 'printf', 2, 3]; // Ignore vararg functions that we know aren't using normal format strings - if (name.match(/^(__builtin_va_start|execlp|open|fcntl|ioctl|sem_open|h_alloc|sys_wopen|ogl_HaveExtensions|JS_ConvertArguments)$/)) + if (name.match(/^(__builtin_va_start|execlp|open|fcntl|ioctl|sem_open|h_alloc|sys_wopen|ogl_HaveExtensions|JS_ConvertArguments|curl_easy_setopt|curl_easy_getinfo|SMBIOS::FieldInitializer::Read|SMBIOS::FieldStringizer::Write)$/)) return; warning('Ignoring unannotated vararg function "'+name+'"', loc()); @@ -115,6 +117,8 @@ function compare_format_type(ctype, functype, fmt, arg, loc) { return (arg == 'int' || arg == 'unsigned int'); // spec says wint_t if (t.match(/^l[diouxX]$/)) return (arg == 'long int' || arg == 'long unsigned int'); + if (t.match(/^ll[diouxX]$/)) + return (arg == 'long long int' || arg == 'long long unsigned int'); if (t.match(/^[fFeEgGaA]$/)) return (arg == 'double'); if (t.match(/^p$/)) @@ -152,10 +156,16 @@ function check_arg_types(ctype, functype, fmt_string, arg_type_names, loc) { var fmt_types = fmt_string.match(/%([-+ #0*]*)(\*|\d+)?(\.\*|\.-?\d+)?(hh|h|ll|l|j|z|t|L)?(.)/g); var num_fmt_types = 0; - for each (var fmt_type in fmt_types) + for each (var fmt_type in fmt_types) { if (fmt_type != '%%') ++num_fmt_types; + // Each '*' eats an extra argument + var stars = fmt_type.match(/\*/g); + if (stars) + num_fmt_types += stars.length; + } + if (num_fmt_types != arg_type_names.length) { error('Number of format string specifiers ('+num_fmt_types+') != number of format arguments ('+arg_type_names.length+')', loc()); return; @@ -163,6 +173,17 @@ function check_arg_types(ctype, functype, fmt_string, arg_type_names, loc) { for each (var fmt_type in fmt_types) { if (fmt_type != '%%') { + // Each '*' eats an extra argument of type int + var stars = fmt_type.match(/\*/g); + if (stars) { + for (var s in stars) { + var arg = arg_type_names.shift(); + if (! compare_format_type(ctype, functype, '%d', arg, loc)) { + error('Invalid argument type "'+arg+'" for format specifier "'+fmt_type+'"', loc()); + } + } + } + var arg = arg_type_names.shift(); if (! compare_format_type(ctype, functype, fmt_type, arg, loc)) { error('Invalid argument type "'+arg+'" for format specifier "'+fmt_type+'"', loc()); diff --git a/build/dehydra/tests/printf-type-check.cpp b/build/dehydra/tests/printf-type-check.cpp index f170660d31..4c4854ada1 100644 --- a/build/dehydra/tests/printf-type-check.cpp +++ b/build/dehydra/tests/printf-type-check.cpp @@ -39,4 +39,7 @@ int main() { wprintf(L"%hs", L"x"); wprintf(L"%ls", "x"); wprintf(L"%ls", L"x"); + printf("%.*ls", 1, L"xy"); + printf("%.*ls", L"z", L"xy"); + printf("%.*ls", L"xy"); } diff --git a/build/dehydra/tests/printf-type-check.txt b/build/dehydra/tests/printf-type-check.txt index fd80b24038..1a7ccbae0f 100644 --- a/build/dehydra/tests/printf-type-check.txt +++ b/build/dehydra/tests/printf-type-check.txt @@ -1,18 +1,20 @@ tests/printf-type-check.cpp: In function ‘int main()’: -tests/printf-type-check.cpp:17: error: Invalid format specifier "%z" -tests/printf-type-check.cpp:18: error: Invalid argument type "long unsigned int" for format specifier "%d" -tests/printf-type-check.cpp:20: error: Invalid argument type "double" for format specifier "%d" -tests/printf-type-check.cpp:22: error: Invalid argument type "int" for format specifier "%s" -tests/printf-type-check.cpp:23: error: Invalid argument type "int" for format specifier "%s" -tests/printf-type-check.cpp:24: error: Invalid argument type "unsigned char*" for format specifier "%d" -tests/printf-type-check.cpp:25: error: Invalid argument type "int" for format specifier "%s" -tests/printf-type-check.cpp:26: error: Invalid argument type "int" for format specifier "%s" -tests/printf-type-check.cpp:27: warning: Ignoring unannotated vararg function "baz" -tests/printf-type-check.cpp:29: error: Number of format string specifiers (1) != number of format arguments (0) -tests/printf-type-check.cpp:30: warning: Non-constant format string argument - can't check types -tests/printf-type-check.cpp:33: error: Invalid argument type "const wchar_t*" for format specifier "%s" -tests/printf-type-check.cpp:36: error: Non-portable %s used in wprintf-style function -tests/printf-type-check.cpp:37: error: Non-portable %s used in wprintf-style function -tests/printf-type-check.cpp:37: error: Invalid argument type "const wchar_t*" for format specifier "%s" -tests/printf-type-check.cpp:39: error: Invalid argument type "const wchar_t*" for format specifier "%hs" -tests/printf-type-check.cpp:40: error: Invalid argument type "const char*" for format specifier "%ls" +tests/printf-type-check.cpp:17:23: error: Invalid format specifier "%z" +tests/printf-type-check.cpp:18:38: error: Invalid argument type "long unsigned int" for format specifier "%d" +tests/printf-type-check.cpp:20:27: error: Invalid argument type "double" for format specifier "%d" +tests/printf-type-check.cpp:22:16: error: Invalid argument type "int" for format specifier "%s" +tests/printf-type-check.cpp:23:16: error: Invalid argument type "int" for format specifier "%s" +tests/printf-type-check.cpp:24:23: error: Invalid argument type "unsigned char*" for format specifier "%d" +tests/printf-type-check.cpp:25:32: error: Invalid argument type "int" for format specifier "%s" +tests/printf-type-check.cpp:26:16: error: Invalid argument type "int" for format specifier "%s" +tests/printf-type-check.cpp:27:16: warning: Ignoring unannotated vararg function "baz" +tests/printf-type-check.cpp:29:18: error: Number of format string specifiers (1) != number of format arguments (0) +tests/printf-type-check.cpp:30:18: warning: Non-constant format string argument - can't check types +tests/printf-type-check.cpp:33:22: error: Invalid argument type "const wchar_t*" for format specifier "%s" +tests/printf-type-check.cpp:36:23: error: Non-portable %s used in wprintf-style function +tests/printf-type-check.cpp:37:24: error: Non-portable %s used in wprintf-style function +tests/printf-type-check.cpp:37:24: error: Invalid argument type "const wchar_t*" for format specifier "%s" +tests/printf-type-check.cpp:39:25: error: Invalid argument type "const wchar_t*" for format specifier "%hs" +tests/printf-type-check.cpp:40:24: error: Invalid argument type "const char*" for format specifier "%ls" +tests/printf-type-check.cpp:43:32: error: Invalid argument type "const wchar_t*" for format specifier "%.*ls" +tests/printf-type-check.cpp:44:26: error: Number of format string specifiers (2) != number of format arguments (1) diff --git a/source/lib/res/graphics/ogl_tex.cpp b/source/lib/res/graphics/ogl_tex.cpp index fb5aeb16d3..d329ab7280 100644 --- a/source/lib/res/graphics/ogl_tex.cpp +++ b/source/lib/res/graphics/ogl_tex.cpp @@ -499,7 +499,7 @@ static Status OglTex_validate(const OglTex* ot) static Status OglTex_to_string(const OglTex* ot, wchar_t* buf) { - swprintf_s(buf, H_STRING_LEN, L"OglTex id=%d flags=%lx", ot->id, ot->flags); + swprintf_s(buf, H_STRING_LEN, L"OglTex id=%d flags=%x", ot->id, ot->flags); return INFO::OK; } diff --git a/source/lib/sysdep/os/linux/ldbg.cpp b/source/lib/sysdep/os/linux/ldbg.cpp index f0cbed35c9..a5cd950f4f 100644 --- a/source/lib/sysdep/os/linux/ldbg.cpp +++ b/source/lib/sysdep/os/linux/ldbg.cpp @@ -108,7 +108,7 @@ Status debug_ResolveSymbol(void* ptr_of_interest, wchar_t* sym_name, wchar_t* fi char** symbols = backtrace_symbols(&ptr_of_interest, 1); if (symbols) { - swprintf_s(sym_name, DBG_SYMBOL_LEN, L"%s", symbols[0]); + swprintf_s(sym_name, DBG_SYMBOL_LEN, L"%hs", symbols[0]); free(symbols); // (Note that this will usually return a pretty useless string, diff --git a/source/lib/sysdep/smbios.cpp b/source/lib/sysdep/smbios.cpp index a9feb5c5f9..feb1449b6a 100644 --- a/source/lib/sysdep/smbios.cpp +++ b/source/lib/sysdep/smbios.cpp @@ -227,7 +227,7 @@ void FieldInitializer::operator()(size_t flags, const char*& t, con if(number > strings.size()) { - debug_printf(L"SMBIOS: invalid string number %d (count=%d)\n", number, strings.size()); + debug_printf(L"SMBIOS: invalid string number %d (count=%d)\n", number, (int)strings.size()); return; } diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 40b1c327ec..5d2bf8e408 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -378,7 +378,7 @@ static size_t ChooseCacheSize() // always provide at least this much to ensure correct operation cache = std::max(cache, (ssize_t)64); - debug_printf(L"Cache: %d (total: %d) MiB\n", cache, total); + debug_printf(L"Cache: %d (total: %d) MiB\n", (int)cache, (int)total); return size_t(cache)*MiB; } diff --git a/source/ps/Joystick.cpp b/source/ps/Joystick.cpp index 93f69f1e99..8c7d4ad214 100644 --- a/source/ps/Joystick.cpp +++ b/source/ps/Joystick.cpp @@ -50,7 +50,7 @@ void CJoystick::Initialise() LOGMESSAGE(L"Found %d joystick(s)", numJoysticks); for (int i = 0; i < numJoysticks; ++i) - LOGMESSAGE(L"Joystick %d: %s", i, SDL_JoystickName(i)); + LOGMESSAGE(L"Joystick %d: %hs", i, SDL_JoystickName(i)); if (numJoysticks) { diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index b4eafa57eb..f4884cc584 100644 --- a/source/simulation2/Simulation2.cpp +++ b/source/simulation2/Simulation2.cpp @@ -548,7 +548,7 @@ std::vector CSimulation2::GetRMSData() { // Some error reading directory wchar_t error[200]; - LOGERROR(L"Error reading directory '%ls': %hs", path.string().c_str(), StatusDescription(ret, error, ARRAY_SIZE(error))); + LOGERROR(L"Error reading directory '%ls': %ls", path.string().c_str(), StatusDescription(ret, error, ARRAY_SIZE(error))); } return data;