X Tutup
Skip to content

Commit fe5d2fc

Browse files
AneeshASdanmar
authored andcommitted
Fixed danmar#5906 (false negative: 'else if' expression is always false (use library to determine if function is pure))
1 parent 332254e commit fe5d2fc

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

lib/tokenize.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9210,6 +9210,12 @@ void Tokenizer::simplifyDeclspec()
92109210
void Tokenizer::simplifyAttribute()
92119211
{
92129212
for (Token *tok = list.front(); tok; tok = tok->next()) {
9213+
if (Token::Match(tok, "%type% (") && !_settings->library.isNotLibraryFunction(tok)) {
9214+
if (_settings->library.functionpure.find(tok->str()) != _settings->library.functionpure.end())
9215+
tok->isAttributePure(true);
9216+
if (_settings->library.functionconst.find(tok->str()) != _settings->library.functionconst.end())
9217+
tok->isAttributeConst(true);
9218+
}
92139219
while (Token::Match(tok, "__attribute__|__attribute (") && tok->next()->link() && tok->next()->link()->next()) {
92149220
if (Token::Match(tok->tokAt(2), "( constructor|__constructor__")) {
92159221
// prototype for constructor is: void func(void);

test/testcondition.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "checkcondition.h"
2222
#include "testsuite.h"
2323
#include <sstream>
24+
#include <tinyxml2.h>
2425

2526
extern std::ostringstream errout;
2627

@@ -319,8 +320,57 @@ class TestCondition : public TestFixture {
319320
" else { if (x & 1); }\n"
320321
"}");
321322
ASSERT_EQUALS("[test.cpp:4]: (style) Expression is always false because 'else if' condition matches previous condition at line 3.\n", errout.str());
323+
324+
check("extern int bar() __attribute__((pure));\n"
325+
"void foo(int x)\n"
326+
"{\n"
327+
" if ( bar() >1 && b) {}\n"
328+
" else if (bar() >1 && b) {}\n"
329+
"}");
330+
ASSERT_EQUALS("[test.cpp:5]: (style) Expression is always false because 'else if' condition matches previous condition at line 4.\n", errout.str());
331+
332+
checkPureFunction("extern int bar();\n"
333+
"void foo(int x)\n"
334+
"{\n"
335+
" if ( bar() >1 && b) {}\n"
336+
" else if (bar() >1 && b) {}\n"
337+
"}");
338+
ASSERT_EQUALS("[test.cpp:5]: (style) Expression is always false because 'else if' condition matches previous condition at line 4.\n", errout.str());
322339
}
323340

341+
void checkPureFunction(const char code[]) {
342+
// Clear the error buffer..
343+
errout.str("");
344+
345+
const char cfg[] = "<?xml version=\"1.0\"?>\n"
346+
"<def>\n"
347+
" <function name=\"bar\"> <pure/> </function>\n"
348+
"</def>";
349+
tinyxml2::XMLDocument xmldoc;
350+
xmldoc.Parse(cfg, sizeof(cfg));
351+
352+
Settings settings;
353+
settings.addEnabled("style");
354+
settings.addEnabled("warning");
355+
settings.library.load(xmldoc);
356+
357+
// Tokenize..
358+
Tokenizer tokenizer(&settings, this);
359+
std::istringstream istr(code);
360+
tokenizer.tokenize(istr, "test.cpp");
361+
362+
CheckCondition checkCondition;
363+
checkCondition.runChecks(&tokenizer, &settings, this);
364+
const std::string str1(tokenizer.tokens()->stringifyList(0,true));
365+
tokenizer.simplifyTokenList2();
366+
const std::string str2(tokenizer.tokens()->stringifyList(0,true));
367+
checkCondition.runSimplifiedChecks(&tokenizer, &settings, this);
368+
369+
// Ensure that the test case is not bad.
370+
if (str1 != str2) {
371+
warnUnsimplified(str1, str2);
372+
}
373+
}
324374
void duplicateIf() {
325375
check("void f(int a, int &b) {\n"
326376
" if (a) { b = 1; }\n"

0 commit comments

Comments
 (0)
X Tutup