Merge pull request #127 from rofl0r/master

sanitize the descriptive text displayed for "varFuncNullUB"
This commit is contained in:
Daniel Marjamäki 2013-01-15 21:34:03 -08:00
commit 27eedcd0a3
2 changed files with 9 additions and 8 deletions

View File

@ -3793,11 +3793,12 @@ void CheckOther::varFuncNullUBError(const Token *tok)
reportError(tok, reportError(tok,
Severity::portability, Severity::portability,
"varFuncNullUB", "varFuncNullUB",
"Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n" "Passing NULL after the last typed argument to a variadic function leads to undefined behaviour.\n"
"Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n" "Passing NULL after the last typed argument to a variadic function leads to undefined behaviour.\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" "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"
"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" "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"
"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" "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 <stdarg.h>\n" "#include <stdarg.h>\n"
"#include <stdio.h>\n" "#include <stdio.h>\n"
"\n" "\n"
@ -3814,9 +3815,9 @@ void CheckOther::varFuncNullUBError(const Token *tok)
"\n" "\n"
"void g() {\n" "void g() {\n"
" char *s2 = \"x\";\n" " char *s2 = \"x\";\n"
" char *s3 = \"ERROR\";\n" " char *s3 = \"ERROR\";\n"
"\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" " f(\"first\", s2, s2, s2, s2, s2, 0, s3, (char*)0);\n"
"}\n" "}\n"
"\n" "\n"

View File

@ -6805,7 +6805,7 @@ private:
void varFuncNullUB() { // #4482 void varFuncNullUB() { // #4482
check("void a(...);\n" check("void a(...);\n"
"void b() { a(NULL); }"); "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" check("void a(char *p, ...);\n"
"void b() { a(NULL, 2); }"); "void b() { a(NULL, 2); }");