From de72ae9f456b936618d27b879baf9651f59aa973 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Mon, 14 Jan 2013 18:11:16 +0100 Subject: [PATCH 1/2] sanitize the descriptive text displayed for "varFuncNullUB" --- lib/checkother.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index b428cecc3..ecbab5725 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3793,11 +3793,12 @@ void CheckOther::varFuncNullUBError(const Token *tok) reportError(tok, Severity::portability, "varFuncNullUB", - "Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n" - "Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n" - "The behaviour is undefined when NULL is #defined as 0, sizeof(int)!=sizeof(void*) and the function expects a pointer. Otherwise the behaviour is defined.\n" - "See section section 7.1.4 and section 7.15.1.1 in the C standard. Section 7.1.4 explains that the function call is UB. Section 7.15.1.1 explains that the va_arg macro has UB.\n" - "To reproduce you might be able to use this little code example. Try it on a platform where sizeof(int)!=sizeof(void*), for instance on a x86_64 machine. If ERROR is written by the program on the screen it means that 0 is not converted to a NULL pointer. Changing the 0 to (void*)0 will fix the program.\n" + "Passing NULL after the last typed argument to a variadic function leads to undefined behaviour.\n" + "Passing NULL after the last typed argument to a variadic function leads to undefined behaviour.\n" + "The C99 standard, in section 7.15.1.1, states that if the type used by va_arg() is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined.\n" + "The value of the NULL macro is an implementation-defined null pointer constant (7.17), which can be any integer constant expression with the value 0, or such an expression casted to (void*) (6.3.2.3). This includes values like 0, 0L, or even 0LL.\n" + "In practice on common architectures, this will cause real crashes if sizeof(int) != sizeof(void*), and NULL is defined to 0 or any other null pointer constant that promotes to int.\n" + "To reproduce you might be able to use this little code example on 64bit platforms. If the output includes \"ERROR\", the sentinel had only 4 out of 8 bytes initialized to zero and was not detected as the final argument to stop argument processing via va_arg(). Changing the 0 to (void*)0 or 0L will make the \"ERROR\" output go away.\n" "#include \n" "#include \n" "\n" @@ -3814,9 +3815,9 @@ void CheckOther::varFuncNullUBError(const Token *tok) "\n" "void g() {\n" " char *s2 = \"x\";\n" - " char *s3 = \"ERROR\";\n" + " char *s3 = \"ERROR\";\n" "\n" - " // changing 0 to 0L makes the error go away on x86_64\n" + " // changing 0 to 0L for the 7th argument (which is intended to act as sentinel) makes the error go away on x86_64\n" " f(\"first\", s2, s2, s2, s2, s2, 0, s3, (char*)0);\n" "}\n" "\n" From 623e30d6771270efd05933460ef0eb1c75b82284 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Tue, 15 Jan 2013 20:45:53 +0100 Subject: [PATCH 2/2] fix unit test for varFuncNullUB --- test/testother.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testother.cpp b/test/testother.cpp index 1ce929b4d..5343450f4 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -6805,7 +6805,7 @@ private: void varFuncNullUB() { // #4482 check("void a(...);\n" "void b() { a(NULL); }"); - ASSERT_EQUALS("[test.cpp:2]: (portability) Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (portability) Passing NULL after the last typed argument to a variadic function leads to undefined behaviour.\n", errout.str()); check("void a(char *p, ...);\n" "void b() { a(NULL, 2); }");