From 4cd0108b93cd02cd4b358a31ae5f703717723608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 6 Oct 2013 16:52:27 +0200 Subject: [PATCH] Fixed #4976 (False positive: (style) A pointer can not be negative (git/sha1_file.c)) --- lib/checkother.cpp | 10 ++++++++-- test/testother.cpp | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 409207afe..c7552010c 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3380,11 +3380,17 @@ void CheckOther::checkSignOfUnsignedVariable() const Scope * scope = symbolDatabase->functionScopes[i]; // check all the code in the function for (const Token *tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { - if (Token::Match(tok, "%var% <|<= 0") && tok->varId() && !Token::Match(tok->previous(), "++|--|)|+|-|*|/|~|<<|>>") && !Token::Match(tok->tokAt(3), "+|-")) { + if (Token::Match(tok, "%var% <|<= 0") && tok->varId() && !Token::Match(tok->tokAt(3), "+|-")) { + // TODO: handle a[10].b , a::b , (unsigned int)x , etc + const Token *prev = tok->previous(); + while (prev && (prev->isName() || prev->str() == ".")) + prev = prev->previous(); + if (!Token::Match(prev, "(|&&|%oror%")) + continue; const Variable *var = tok->variable(); if (var && var->typeEndToken()->isUnsigned()) unsignedLessThanZeroError(tok, var->name(), inconclusive); - else if (var && var->isPointer() && tok->strAt(-1) != "*") + else if (var && (var->isPointer() || var->isArray())) pointerLessThanZeroError(tok, inconclusive); } else if (Token::Match(tok, "0 >|>= %var%") && tok->tokAt(2)->varId() && !Token::Match(tok->tokAt(3), "+|-|*|/") && !Token::Match(tok->previous(), "+|-|<<|>>|~")) { const Variable *var = tok->tokAt(2)->variable(); diff --git a/test/testother.cpp b/test/testother.cpp index 0719f60c0..8306d3c53 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -5220,6 +5220,27 @@ private: " bar();\n" "}"); ASSERT_EQUALS("", errout.str()); + + check_signOfUnsignedVariable( + "struct object_info { int *typep; };\n" + "void packed_object_info(struct object_info *oi) {\n" + " if (oi->typep < 0);\n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (style) A pointer can not be negative so it is either pointless or an error to check if it is.\n", errout.str()); + + check_signOfUnsignedVariable( + "struct object_info { int typep[10]; };\n" + "void packed_object_info(struct object_info *oi) {\n" + " if (oi->typep < 0);\n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (style) A pointer can not be negative so it is either pointless or an error to check if it is.\n", errout.str()); + + check_signOfUnsignedVariable( + "struct object_info { int *typep; };\n" + "void packed_object_info(struct object_info *oi) {\n" + " if (*oi->typep < 0);\n" + "}"); + ASSERT_EQUALS("", errout.str()); } void checkForSuspiciousSemicolon1() {