Skip to content

Commit 19a8cfd

Browse files
committed
Library: add new "define" tag
This tag will allow to add some preprocessor defs into library. It would be useful to provide more information about libraries implementation details. As example GLib's library include tag was added that helps to detect more memory leaks.
1 parent 3c0619c commit 19a8cfd

6 files changed

Lines changed: 82 additions & 1 deletion

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ test/testlibrary.o: test/testlibrary.cpp lib/library.h lib/config.h lib/path.h l
452452
test/testmathlib.o: test/testmathlib.cpp lib/mathlib.h lib/config.h test/testsuite.h lib/errorlogger.h lib/suppressions.h test/redirect.h lib/library.h lib/path.h
453453
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) -std=c++0x -c -o test/testmathlib.o test/testmathlib.cpp
454454

455-
test/testmemleak.o: test/testmemleak.cpp lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checkmemoryleak.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/path.h lib/standards.h lib/timer.h test/testsuite.h test/redirect.h lib/symboldatabase.h
455+
test/testmemleak.o: test/testmemleak.cpp lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checkmemoryleak.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/path.h lib/standards.h lib/timer.h test/testsuite.h test/redirect.h lib/symboldatabase.h lib/preprocessor.h
456456
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CFG) $(CXXFLAGS) -std=c++0x -c -o test/testmemleak.o test/testmemleak.cpp
457457

458458
test/testnonreentrantfunctions.o: test/testnonreentrantfunctions.cpp lib/tokenize.h lib/errorlogger.h lib/config.h lib/suppressions.h lib/tokenlist.h lib/checknonreentrantfunctions.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/settings.h lib/library.h lib/path.h lib/standards.h lib/timer.h test/testsuite.h test/redirect.h

cfg/gtk.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<?xml version="1.0"?>
22
<!-- THIS FILE IS GENERATED AUTOMATICALLY. See https://github.com/scriptum/cppcheck-libs -->
33
<def>
4+
<define name="g_return_if_fail(expr)" value="do{if(!(expr)){return;}}while(0)"/>
5+
<define name="g_return_val_if_fail(expr, val)" value="do{if(!(expr)){return val;}}while(0)"/>
6+
<define name="g_return_if_reached()" value="do{return;}while(0)"/>
7+
<define name="g_return_val_if_reached(val)" value="do{return val;}while(0)"/>
48
<memory>
59
<alloc init="true">g_thread_new</alloc>
610
<alloc init="true">g_thread_try_new</alloc>

lib/library.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,20 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
127127
}
128128
}
129129

130+
else if (strcmp(node->Name(),"define")==0) {
131+
const char *name = node->Attribute("name");
132+
if (name == NULL)
133+
return false;
134+
const char *value = node->Attribute("value");
135+
if (value == NULL)
136+
return false;
137+
defines.push_back(std::string("#define ") +
138+
name +
139+
" " +
140+
value +
141+
"\n");
142+
}
143+
130144
else if (strcmp(node->Name(),"function")==0) {
131145
const char *name = node->Attribute("name");
132146
if (name == NULL)

lib/library.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ class CPPCHECKLIB Library {
269269
}
270270

271271
std::set<std::string> returnuninitdata;
272+
std::vector<std::string> defines; // to provide some library defines
272273

273274
private:
274275
class ExportedFunctions {

lib/preprocessor.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,13 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
994994
"#endfile\n"
995995
;
996996
}
997+
998+
for (std::vector<std::string>::iterator it = _settings->library.defines.begin();
999+
it != _settings->library.defines.end();
1000+
++it)
1001+
{
1002+
forcedIncludes += *it;
1003+
}
9971004
}
9981005

9991006
if (!forcedIncludes.empty()) {

test/testmemleak.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "checkmemoryleak.h"
2424
#include "testsuite.h"
2525
#include "symboldatabase.h"
26+
#include "preprocessor.h"
2627
#include <sstream>
2728

2829
extern std::ostringstream errout;
@@ -6273,3 +6274,57 @@ class TestMemleakNoVar : public TestFixture {
62736274
}
62746275
};
62756276
REGISTER_TEST(TestMemleakNoVar)
6277+
6278+
6279+
6280+
6281+
6282+
class TestMemleakGLib : public TestFixture {
6283+
public:
6284+
TestMemleakGLib() : TestFixture("TestMemleakGLib") {
6285+
}
6286+
6287+
private:
6288+
void check(const char code[]) {
6289+
// Clear the error buffer..
6290+
errout.str("");
6291+
6292+
Settings settings;
6293+
LOAD_LIB("gtk.cfg");
6294+
settings.library = _lib;
6295+
6296+
// Preprocess...
6297+
Preprocessor preprocessor(&settings, this);
6298+
std::istringstream istrpreproc(code);
6299+
std::map<std::string, std::string> actual;
6300+
preprocessor.preprocess(istrpreproc, actual, "test.c");
6301+
6302+
// Tokenize..
6303+
Tokenizer tokenizer(&settings, this);
6304+
std::istringstream istr(actual[""]);
6305+
tokenizer.tokenize(istr, "test.c");
6306+
tokenizer.simplifyTokenList2();
6307+
6308+
// Check for memory leaks..
6309+
CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings, this);
6310+
checkMemoryLeak.checkReallocUsage();
6311+
checkMemoryLeak.check();
6312+
}
6313+
6314+
void run() {
6315+
TEST_CASE(glib1);
6316+
}
6317+
6318+
void glib1() {
6319+
check("void f(gchar *_a, gchar *_b) {"
6320+
" g_return_if_fail(_a);"
6321+
" gchar *a = g_strdup(_a);"
6322+
" g_return_if_fail(_b);"
6323+
" gchar *b = g_strdup(_b);"
6324+
" g_free(a);"
6325+
" g_free(b);"
6326+
"}");
6327+
ASSERT_EQUALS("[test.c:1]: (error) Memory leak: a\n", errout.str());
6328+
}
6329+
};
6330+
static TestMemleakGLib testMemleakGLib;

0 commit comments

Comments
 (0)