Skip to content

Commit 8b764d8

Browse files
authored
findtoken.h: make sure code is being matchcompiled (#6641)
1 parent 76b1011 commit 8b764d8

File tree

6 files changed

+173
-103
lines changed

6 files changed

+173
-103
lines changed

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ LIBOBJ = $(libcppdir)/valueflow.o \
221221
$(libcppdir)/ctu.o \
222222
$(libcppdir)/errorlogger.o \
223223
$(libcppdir)/errortypes.o \
224+
$(libcppdir)/findtoken.o \
224225
$(libcppdir)/forwardanalyzer.o \
225226
$(libcppdir)/fwdanalysis.o \
226227
$(libcppdir)/importproject.o \
@@ -571,6 +572,9 @@ $(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h li
571572
$(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h
572573
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp
573574

575+
$(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
576+
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp
577+
574578
$(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
575579
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp
576580

lib/astutils.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3115,7 +3115,7 @@ namespace {
31153115
template<class F>
31163116
const Token* operator()(const Token* start, const Token* end, F f) const
31173117
{
3118-
return findTokenSkipDeadCode(library, start, end, f, *evaluate);
3118+
return findTokenSkipDeadCode(library, start, end, std::move(f), *evaluate);
31193119
}
31203120
};
31213121
}

lib/cppcheck.vcxproj

+2
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

+143
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+
static bool findTokensSkipDeadCodeImpl(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 (internal::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+
auto r = result.front();
53+
if (r == 0) {
54+
if (elseStart) {
55+
if (internal::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 (internal::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 (internal::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+
auto 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+
namespace internal {
122+
bool findTokensSkipDeadCodeImpl(const Library& library,
123+
Token* start,
124+
const Token* end,
125+
const std::function<bool(const Token*)>& pred,
126+
const std::function<bool(Token*)>& found,
127+
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate,
128+
bool skipUnevaluated)
129+
{
130+
return ::findTokensSkipDeadCodeImpl(library, start, end, pred, found, evaluate, skipUnevaluated);
131+
}
132+
133+
bool findTokensSkipDeadCodeImpl(const Library& library,
134+
const Token* start,
135+
const Token* end,
136+
const std::function<bool(const Token*)>& pred,
137+
const std::function<bool(const Token*)>& found,
138+
const std::function<std::vector<MathLib::bigint>(const Token*)>& evaluate,
139+
bool skipUnevaluated)
140+
{
141+
return ::findTokensSkipDeadCodeImpl(library, start, end, pred, found, evaluate, skipUnevaluated);
142+
}
143+
}

lib/findtoken.h

+19-102
Original file line numberDiff line numberDiff line change
@@ -74,105 +74,22 @@ T* findToken(T* start, const Token* end, const Predicate& pred)
7474
return result;
7575
}
7676

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

17895
template<class T, class Predicate, class Evaluate, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
@@ -183,7 +100,7 @@ std::vector<T*> findTokensSkipDeadCode(const Library& library,
183100
const Evaluate& evaluate)
184101
{
185102
std::vector<T*> result;
186-
(void)findTokensSkipDeadCodeImpl(
103+
(void)internal::findTokensSkipDeadCodeImpl(
187104
library,
188105
start,
189106
end,
@@ -211,7 +128,7 @@ std::vector<T*> findTokensSkipDeadAndUnevaluatedCode(const Library& library,
211128
const Evaluate& evaluate)
212129
{
213130
std::vector<T*> result;
214-
(void)findTokensSkipDeadCodeImpl(
131+
(void)internal::findTokensSkipDeadCodeImpl(
215132
library,
216133
start,
217134
end,
@@ -236,7 +153,7 @@ template<class T, class Predicate, class Evaluate, REQUIRES("T must be a Token c
236153
T* findTokenSkipDeadCode(const Library& library, T* start, const Token* end, const Predicate& pred, const Evaluate& evaluate)
237154
{
238155
T* result = nullptr;
239-
(void)findTokensSkipDeadCodeImpl(
156+
(void)internal::findTokensSkipDeadCodeImpl(
240157
library,
241158
start,
242159
end,

oss-fuzz/Makefile

+4
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)