Skip to content

Commit b2f81a3

Browse files
committed
cpp
1 parent 82f5f83 commit b2f81a3

File tree

5 files changed

+172
-89
lines changed

5 files changed

+172
-89
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \
231231
$(libcppdir)/ctu.o \
232232
$(libcppdir)/errorlogger.o \
233233
$(libcppdir)/errortypes.o \
234+
$(libcppdir)/findtoken.o \
234235
$(libcppdir)/forwardanalyzer.o \
235236
$(libcppdir)/fwdanalysis.o \
236237
$(libcppdir)/importproject.o \
@@ -581,6 +582,9 @@ $(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h li
581582
$(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h
582583
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp
583584

585+
$(libcppdir)/findtoken.o: lib/findtoken.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h
586+
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp
587+
584588
$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h
585589
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp
586590

lib/cppcheck.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
<ClCompile Include="ctu.cpp" />
6767
<ClCompile Include="errorlogger.cpp" />
6868
<ClCompile Include="errortypes.cpp" />
69+
<ClCompile Include="findtoken.cpp" />
6970
<ClCompile Include="forwardanalyzer.cpp" />
7071
<ClCompile Include="fwdanalysis.cpp" />
7172
<ClCompile Include="importproject.cpp" />
@@ -140,6 +141,7 @@
140141
<ClInclude Include="errortypes.h" />
141142
<ClInclude Include="filesettings.h" />
142143
<ClInclude Include="findtoken.h" />
144+
<ClInclude Include="findtoken.h" />
143145
<ClInclude Include="forwardanalyzer.h" />
144146
<ClInclude Include="fwdanalysis.h" />
145147
<ClInclude Include="importproject.h" />

lib/findtoken.cpp

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Cppcheck - A tool for static C/C++ code analysis
3+
* Copyright (C) 2007-2024 Cppcheck team.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include "findtoken.h"
20+
21+
#include "astutils.h"
22+
#include "token.h"
23+
24+
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
25+
bool findTokensSkipDeadCodeImpl2(const Library& library,
26+
T* start,
27+
const Token* end,
28+
const std::function<bool(const Token*)>& pred,
29+
const std::function<bool(T*)>& found,
30+
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate,
31+
bool skipUnevaluated)
32+
{
33+
for (T* tok = start; precedes(tok, end); tok = tok->next()) {
34+
if (pred(tok)) {
35+
if (found(tok))
36+
return true;
37+
}
38+
if (Token::Match(tok, "if|for|while (") && Token::simpleMatch(tok->linkAt(1), ") {")) {
39+
const Token* condTok = getCondTok(tok);
40+
if (!condTok)
41+
continue;
42+
auto result = evaluate(condTok);
43+
if (result.empty())
44+
continue;
45+
if (findTokensSkipDeadCodeImpl(library, tok->next(), tok->linkAt(1), pred, found, evaluate, skipUnevaluated))
46+
return true;
47+
T* thenStart = tok->linkAt(1)->next();
48+
T* elseStart = nullptr;
49+
if (Token::simpleMatch(thenStart->link(), "} else {"))
50+
elseStart = thenStart->link()->tokAt(2);
51+
52+
int r = result.front();
53+
if (r == 0) {
54+
if (elseStart) {
55+
if (findTokensSkipDeadCodeImpl(library, elseStart, elseStart->link(), pred, found, evaluate, skipUnevaluated))
56+
return true;
57+
if (isReturnScope(elseStart->link(), library))
58+
return true;
59+
tok = elseStart->link();
60+
} else {
61+
tok = thenStart->link();
62+
}
63+
} else {
64+
if (findTokensSkipDeadCodeImpl(library, thenStart, thenStart->link(), pred, found, evaluate, skipUnevaluated))
65+
return true;
66+
if (isReturnScope(thenStart->link(), library))
67+
return true;
68+
tok = thenStart->link();
69+
}
70+
} else if (Token::Match(tok->astParent(), "&&|?|%oror%") && astIsLHS(tok)) {
71+
auto result = evaluate(tok);
72+
if (result.empty())
73+
continue;
74+
const bool cond = result.front() != 0;
75+
T* next = nullptr;
76+
if ((cond && Token::simpleMatch(tok->astParent(), "||")) ||
77+
(!cond && Token::simpleMatch(tok->astParent(), "&&"))) {
78+
next = nextAfterAstRightmostLeaf(tok->astParent());
79+
} else if (Token::simpleMatch(tok->astParent(), "?")) {
80+
T* colon = tok->astParent()->astOperand2();
81+
if (!cond) {
82+
next = colon;
83+
} else {
84+
if (findTokensSkipDeadCodeImpl(library, tok->astParent()->next(), colon, pred, found, evaluate, skipUnevaluated))
85+
return true;
86+
next = nextAfterAstRightmostLeaf(colon);
87+
}
88+
}
89+
if (next)
90+
tok = next;
91+
} else if (Token::simpleMatch(tok, "} else {")) {
92+
const Token* condTok = getCondTokFromEnd(tok);
93+
if (!condTok)
94+
continue;
95+
auto result = evaluate(condTok);
96+
if (result.empty())
97+
continue;
98+
if (isReturnScope(tok->link(), library))
99+
return true;
100+
int r = result.front();
101+
if (r != 0) {
102+
tok = tok->linkAt(2);
103+
}
104+
} else if (Token::simpleMatch(tok, "[") && Token::Match(tok->link(), "] (|{")) {
105+
T* afterCapture = tok->link()->next();
106+
if (Token::simpleMatch(afterCapture, "(") && afterCapture->link())
107+
tok = afterCapture->link()->next();
108+
else
109+
tok = afterCapture;
110+
}
111+
if (skipUnevaluated && isUnevaluated(tok)) {
112+
T *next = tok->linkAt(1);
113+
if (!next)
114+
continue;
115+
tok = next;
116+
}
117+
}
118+
return false;
119+
}
120+
121+
template<>
122+
bool findTokensSkipDeadCodeImpl(const Library& library,
123+
Token* start,
124+
const Token* end,
125+
const std::function<bool(const Token*)>& pred,
126+
std::function<bool(Token*)> found,
127+
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate,
128+
bool skipUnevaluated)
129+
{
130+
return findTokensSkipDeadCodeImpl2(library, start, end, pred, found, evaluate, skipUnevaluated);
131+
}
132+
133+
template<>
134+
bool findTokensSkipDeadCodeImpl(const Library& library,
135+
const Token* start,
136+
const Token* end,
137+
const std::function<bool(const Token*)>& pred,
138+
std::function<bool(const Token*)> found,
139+
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate,
140+
bool skipUnevaluated)
141+
{
142+
return findTokensSkipDeadCodeImpl2(library, start, end, pred, found, evaluate, skipUnevaluated);
143+
}

lib/findtoken.h

Lines changed: 19 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -74,102 +74,32 @@ T* findToken(T* start, const Token* end, const std::function<bool(const Token*)>
7474
return result;
7575
}
7676

77-
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
77+
template<class T>
7878
bool findTokensSkipDeadCodeImpl(const Library& library,
7979
T* start,
8080
const Token* end,
8181
const std::function<bool(const Token*)>& pred,
8282
std::function<bool(T*)> found,
8383
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate,
84-
bool skipUnevaluated)
85-
{
86-
for (T* tok = start; precedes(tok, end); tok = tok->next()) {
87-
if (pred(tok)) {
88-
if (found(tok))
89-
return true;
90-
}
91-
if (Token::Match(tok, "if|for|while (") && Token::simpleMatch(tok->linkAt(1), ") {")) {
92-
const Token* condTok = getCondTok(tok);
93-
if (!condTok)
94-
continue;
95-
auto result = evaluate(condTok);
96-
if (result.empty())
97-
continue;
98-
if (findTokensSkipDeadCodeImpl(library, tok->next(), tok->linkAt(1), pred, std::move(found), evaluate, skipUnevaluated))
99-
return true;
100-
T* thenStart = tok->linkAt(1)->next();
101-
T* elseStart = nullptr;
102-
if (Token::simpleMatch(thenStart->link(), "} else {"))
103-
elseStart = thenStart->link()->tokAt(2);
84+
bool skipUnevaluated) = delete;
10485

105-
int r = result.front();
106-
if (r == 0) {
107-
if (elseStart) {
108-
if (findTokensSkipDeadCodeImpl(library, elseStart, elseStart->link(), pred, std::move(found), evaluate, skipUnevaluated))
109-
return true;
110-
if (isReturnScope(elseStart->link(), library))
111-
return true;
112-
tok = elseStart->link();
113-
} else {
114-
tok = thenStart->link();
115-
}
116-
} else {
117-
if (findTokensSkipDeadCodeImpl(library, thenStart, thenStart->link(), pred, std::move(found), evaluate, skipUnevaluated))
118-
return true;
119-
if (isReturnScope(thenStart->link(), library))
120-
return true;
121-
tok = thenStart->link();
122-
}
123-
} else if (Token::Match(tok->astParent(), "&&|?|%oror%") && astIsLHS(tok)) {
124-
auto result = evaluate(tok);
125-
if (result.empty())
126-
continue;
127-
const bool cond = result.front() != 0;
128-
T* next = nullptr;
129-
if ((cond && Token::simpleMatch(tok->astParent(), "||")) ||
130-
(!cond && Token::simpleMatch(tok->astParent(), "&&"))) {
131-
next = nextAfterAstRightmostLeaf(tok->astParent());
132-
} else if (Token::simpleMatch(tok->astParent(), "?")) {
133-
T* colon = tok->astParent()->astOperand2();
134-
if (!cond) {
135-
next = colon;
136-
} else {
137-
if (findTokensSkipDeadCodeImpl(library, tok->astParent()->next(), colon, pred, std::move(found), evaluate, skipUnevaluated))
138-
return true;
139-
next = nextAfterAstRightmostLeaf(colon);
140-
}
141-
}
142-
if (next)
143-
tok = next;
144-
} else if (Token::simpleMatch(tok, "} else {")) {
145-
const Token* condTok = getCondTokFromEnd(tok);
146-
if (!condTok)
147-
continue;
148-
auto result = evaluate(condTok);
149-
if (result.empty())
150-
continue;
151-
if (isReturnScope(tok->link(), library))
152-
return true;
153-
int r = result.front();
154-
if (r != 0) {
155-
tok = tok->linkAt(2);
156-
}
157-
} else if (Token::simpleMatch(tok, "[") && Token::Match(tok->link(), "] (|{")) {
158-
T* afterCapture = tok->link()->next();
159-
if (Token::simpleMatch(afterCapture, "(") && afterCapture->link())
160-
tok = afterCapture->link()->next();
161-
else
162-
tok = afterCapture;
163-
}
164-
if (skipUnevaluated && isUnevaluated(tok)) {
165-
T *next = tok->linkAt(1);
166-
if (!next)
167-
continue;
168-
tok = next;
169-
}
170-
}
171-
return false;
172-
}
86+
template<>
87+
bool findTokensSkipDeadCodeImpl(const Library& library,
88+
Token* start,
89+
const Token* end,
90+
const std::function<bool(const Token*)>& pred,
91+
std::function<bool(Token*)> found,
92+
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate,
93+
bool skipUnevaluated);
94+
95+
template<>
96+
bool findTokensSkipDeadCodeImpl(const Library& library,
97+
const Token* start,
98+
const Token* end,
99+
const std::function<bool(const Token*)>& pred,
100+
std::function<bool(const Token*)> found,
101+
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate,
102+
bool skipUnevaluated);
173103

174104
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
175105
std::vector<T*> findTokensSkipDeadCode(const Library& library,

oss-fuzz/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \
7474
$(libcppdir)/ctu.o \
7575
$(libcppdir)/errorlogger.o \
7676
$(libcppdir)/errortypes.o \
77+
$(libcppdir)/findtoken.o \
7778
$(libcppdir)/forwardanalyzer.o \
7879
$(libcppdir)/fwdanalysis.o \
7980
$(libcppdir)/importproject.o \
@@ -267,6 +268,9 @@ $(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml
267268
$(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h
268269
$(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp
269270

271+
$(libcppdir)/findtoken.o: ../lib/findtoken.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h
272+
$(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp
273+
270274
$(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h
271275
$(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp
272276

0 commit comments

Comments
 (0)