forked from mathieu/cppcheck
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchecktu.cpp
More file actions
128 lines (124 loc) · 4.7 KB
/
checktu.cpp
File metadata and controls
128 lines (124 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2009 Daniel Marjamäki and Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/
*/
#include "checktu.h"
// Register this check class into cppcheck by creating a static instance of it..
namespace
{
static CheckTU instance;
}
CheckTU::~CheckTU()
{
}
void CheckTU::checks()
{
TUtils::tokenutils* tu = new TUtils::tokenutils(_tokenizer);
TUtils::TContext* context = tu->getContext();
//context->Print();
checkContext(context);
checkSwitchContext(context);
}
bool CheckTU::invalid_deallication_check(TUtils::TDeclaration* decl, TUtils::TPar* par)
{
if ((decl && decl->isArray) || (decl && !decl->isPointer && par->isPointer))
{
return true;
}
return false;
}
void CheckTU::checkSwitchContext(TUtils::TContext* context)
{
if (context->ObjectId == TUtils::TSwitchContextId)
{
TUtils::TSwitchContext* sc = (TUtils::TSwitchContext*)context;
APPLY_TO_LIST(TUtils::TSwitchCase*,sc->caseList,switchCaseIt)
{
int case_begins=(*switchCaseIt)->beginsAt;
int case_ends=(*switchCaseIt)->endsAt;
std::list<TUtils::TSwitchCase*>::iterator next_it=switchCaseIt;
next_it++;
/*If this switch case has no break and the next case exists*/
if ((!(*switchCaseIt)->hasBreak) && (next_it!=sc->caseList.end()))
{
int nextCaseBegins=(*next_it)->beginsAt;
int nextCaseEnds=(*next_it)->endsAt;
/*Find all assignements in this case*/
std::list<TUtils::TAssignement*>* caseAssigns = sc->getAllAssignementsWithin(case_begins,case_ends);
std::list<TUtils::TAssignement*>* nextCaseAssigns = sc->getAllAssignementsWithin(nextCaseBegins,nextCaseEnds);
APPLY_TO_LIST(TUtils::TAssignement*,(*caseAssigns),caseAssignIt)
{
/*If the same assignements is done in the next case probably it is an error*/
TUtils::TAssignement* ass=*caseAssignIt;
APPLY_TO_LIST(TUtils::TAssignement*,(*nextCaseAssigns),nextCaseAssignIt)
{
TUtils::TAssignement* nextAss=*nextCaseAssignIt;
if (ass->left == nextAss->left)
{
reportError(nextAss->token,
Severity::error,
"Checks using TokenUtils",
"Possible case without break");
}
}
}
delete caseAssigns;
delete nextCaseAssigns;
}
}
}
APPLY_TO_LIST(TUtils::TContext*,context->contextList,It)
{
checkSwitchContext(*It);
}
}
void CheckTU::checkContext(TUtils::TContext* context)
{
std::list<TUtils::TCall*> list = context->getAllCalls("free");
std::list<TUtils::TCall*>::iterator callIt;
for (callIt = list.begin();callIt != list.end();callIt++)
{
if ((*callIt)->parametersList.size() != 1)
{
std::cout << "Errore" << std::endl;
}
else
{
TUtils::TCall* call = *callIt;
TUtils::TPar* par = *call->parametersList.begin();
TUtils::TDeclaration* decl = context->getDeclaration(par->name);
if (decl && decl->alias == NULL && invalid_deallication_check(decl, par))
{
//decl->Print();
reportError(call->token,
Severity::error,
"autoVariables",
"Invalid deallocation");
}
else if (decl && decl->alias && invalid_deallication_check(decl->getRealDeclaration(), par))
{
reportError(call->token,
Severity::error,
"autoVariables",
"Invalid deallocation");
}
}
}
APPLY_TO_LIST(TUtils::TContext*,context->contextList,It)
{
checkContext(*It);
}
}