From 4055b0ec5f398a3e734e9a2da4c2bcec9ddd3664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 6 Jul 2011 17:57:39 +0200 Subject: [PATCH] 64-bit portability: fixed two of the TODO test cases. Ticket: #2791 --- lib/check64bit.cpp | 44 +++++++++++++++++++++++++++++++------------- lib/check64bit.h | 6 ++++-- test/test64bit.cpp | 4 ++-- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index cda31dd30..a11954325 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -31,6 +31,19 @@ namespace Check64BitPortability instance; } +/** Is given variable a pointer or array? */ +static bool isaddr(const Variable *var) +{ + const Token *nametok = var ? var->nameToken() : 0; + return (var && (nametok->strAt(-1) == "*" || nametok->strAt(1) == "[")); +} + +/** Is given variable an integer variable */ +static bool isint(const Variable *var) +{ + return (var && Token::Match(var->nameToken()->previous(), "int|long|DWORD")); +} + void Check64BitPortability::pointerassignment() { if (!_settings->_checkCodingStyle) @@ -38,35 +51,40 @@ void Check64BitPortability::pointerassignment() for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { - if (Token::Match(tok, "[;{}] %var% = %var% ;")) + if (Token::Match(tok, "[;{}] %var% = %var% [;+]")) { const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const Variable *var1(symbolDatabase->getVariableFromVarId(tok->tokAt(1)->varId())); const Variable *var2(symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId())); - if (!var1 || !var2) - continue; - // Check if var1 is an int/long/DWORD variable - if (!Token::Match(var1->nameToken()->previous(), "int|long|DWORD")) - continue; + if (isaddr(var1) && isint(var2)) + assignmentIntegerToAddressError(tok->next()); - // Check if var2 is a pointer variable - if (!Token::simpleMatch(var2->nameToken()->previous(), "*")) - continue; - - pointerassignmentError(tok->next()); + else if (isint(var1) && isaddr(var2)) + assignmentAddressToIntegerError(tok->next()); } } } -void Check64BitPortability::pointerassignmentError(const Token *tok) +void Check64BitPortability::assignmentAddressToIntegerError(const Token *tok) { reportError(tok, Severity::portability, - "addresstoint", + "AssignmentAddressToInteger", "Assigning an address value to the integer (int/long/etc) type is not portable\n" "Assigning an address value to the integer (int/long/etc) type is not portable across different platforms and " "compilers. For example in 32-bit Windows and linux they are same width, but in 64-bit Windows and linux " "they are of different width. In worst case you end up assigning 64-bit address to 32-bit integer. The safe " "way is to always assign addresses only to pointer types (or typedefs)."); } + +void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok) +{ + reportError(tok, Severity::portability, + "AssignmentIntegerToAddress", + "Assigning an integer (int/long/etc) to a pointer is not portable\n" + "Assigning an integer (int/long/etc) to a pointer is not portable across different platforms and " + "compilers. For example in 32-bit Windows and linux they are same width, but in 64-bit Windows and linux " + "they are of different width. In worst case you end up assigning 32-bit integer to 64-bit pointer. The safe " + "way is to always assign address to pointer."); +} diff --git a/lib/check64bit.h b/lib/check64bit.h index d2df5385b..ce75f063e 100644 --- a/lib/check64bit.h +++ b/lib/check64bit.h @@ -66,12 +66,14 @@ public: private: - void pointerassignmentError(const Token *tok); + void assignmentAddressToIntegerError(const Token *tok); + void assignmentIntegerToAddressError(const Token *tok); void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { Check64BitPortability c(0, settings, errorLogger); - c.pointerassignmentError(0); + c.assignmentAddressToIntegerError(0); + c.assignmentIntegerToAddressError(0); } std::string myName() const diff --git a/test/test64bit.cpp b/test/test64bit.cpp index 57e22b3d9..5d39ecb8c 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -83,14 +83,14 @@ private: " int a = p;\n" " return a + 4;\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (portability) Assigning an address value to the integer (int/long/etc) type is not portable\n", "", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (portability) Assigning an address value to the integer (int/long/etc) type is not portable\n", errout.str()); check("void foo(int x)\n" "{\n" " int *p = x;\n" " *p = 0;\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (portability) Assigning an address value to the integer (int/long/etc) type is not portable\n", "", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (portability) Assigning an integer (int/long/etc) to a pointer is not portable\n", errout.str()); } void structmember()