Skip to content

Commit 1d95d19

Browse files
authored
refs #10663 - sped up Library::detectContainerOrIterator() by iterating the containers only once (danmar#4380)
1 parent 2ab8de2 commit 1d95d19

6 files changed

Lines changed: 101 additions & 16 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ test/testio.o: test/testio.cpp lib/check.h lib/checkio.h lib/color.h lib/config.
682682
test/testleakautovar.o: test/testleakautovar.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/check.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
683683
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testleakautovar.o test/testleakautovar.cpp
684684

685-
test/testlibrary.o: test/testlibrary.cpp externals/tinyxml2/tinyxml2.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
685+
test/testlibrary.o: test/testlibrary.cpp externals/tinyxml2/tinyxml2.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h test/testutils.h
686686
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testlibrary.o test/testlibrary.cpp
687687

688688
test/testmathlib.o: test/testmathlib.cpp lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/mathlib.h lib/suppressions.h test/testsuite.h

lib/checkstl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1421,7 +1421,7 @@ void CheckStl::stlBoundaries()
14211421
if (!var || !var->scope() || !var->scope()->isExecutable())
14221422
continue;
14231423

1424-
const Library::Container* container = mSettings->library.detectContainer(var->typeStartToken(), true);
1424+
const Library::Container* container = mSettings->library.detectIterator(var->typeStartToken());
14251425
if (!container || container->opLessAllowed)
14261426
continue;
14271427

lib/checkunusedvar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
715715
else if (mTokenizer->isC() ||
716716
i->typeEndToken()->isStandardType() ||
717717
isRecordTypeWithoutSideEffects(i->type()) ||
718-
mSettings->library.detectContainer(i->typeStartToken(), /*iterator*/ false) ||
718+
mSettings->library.detectContainer(i->typeStartToken()) ||
719719
i->isStlType())
720720
type = Variables::standard;
721721
if (type == Variables::none || isPartOfClassStructUnion(i->typeStartToken()))

lib/library.cpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ bool Library::isScopeNoReturn(const Token *end, std::string *unknownFunc) const
11331133
return false;
11341134
}
11351135

1136-
const Library::Container* Library::detectContainer(const Token* typeStart, bool iterator) const
1136+
const Library::Container* Library::detectContainerInternal(const Token* typeStart, DetectContainer detect, bool* isIterator) const
11371137
{
11381138
for (const std::pair<const std::string, Library::Container> & c : containers) {
11391139
const Container& container = c.second;
@@ -1143,32 +1143,48 @@ const Library::Container* Library::detectContainer(const Token* typeStart, bool
11431143
if (!Token::Match(typeStart, container.startPattern2.c_str()))
11441144
continue;
11451145

1146-
if (!iterator && container.endPattern.empty()) // If endPattern is undefined, it will always match, but itEndPattern has to be defined.
1146+
// If endPattern is undefined, it will always match, but itEndPattern has to be defined.
1147+
if (detect != IteratorOnly && container.endPattern.empty()) {
1148+
if (isIterator)
1149+
*isIterator = false;
11471150
return &container;
1151+
}
11481152

11491153
for (const Token* tok = typeStart; tok && !tok->varId(); tok = tok->next()) {
11501154
if (tok->link()) {
1151-
const std::string& endPattern = iterator ? container.itEndPattern : container.endPattern;
1152-
if (Token::Match(tok->link(), endPattern.c_str()))
1155+
if (detect != ContainerOnly && Token::Match(tok->link(), container.itEndPattern.c_str())) {
1156+
if (isIterator)
1157+
*isIterator = true;
1158+
return &container;
1159+
}
1160+
if (detect != IteratorOnly && Token::Match(tok->link(), container.endPattern.c_str())) {
1161+
if (isIterator)
1162+
*isIterator = false;
11531163
return &container;
1164+
}
11541165
break;
11551166
}
11561167
}
11571168
}
11581169
return nullptr;
11591170
}
11601171

1172+
const Library::Container* Library::detectContainer(const Token* typeStart) const
1173+
{
1174+
return detectContainerInternal(typeStart, ContainerOnly);
1175+
}
1176+
1177+
const Library::Container* Library::detectIterator(const Token* typeStart) const
1178+
{
1179+
return detectContainerInternal(typeStart, IteratorOnly);
1180+
}
1181+
11611182
const Library::Container* Library::detectContainerOrIterator(const Token* typeStart, bool* isIterator) const
11621183
{
1163-
const Library::Container* c = detectContainer(typeStart);
1164-
if (c) {
1165-
if (isIterator)
1166-
*isIterator = false;
1167-
return c;
1168-
}
1169-
c = detectContainer(typeStart, true);
1184+
bool res;
1185+
const Library::Container* c = detectContainerInternal(typeStart, Both, &res);
11701186
if (c && isIterator)
1171-
*isIterator = true;
1187+
*isIterator = res;
11721188
return c;
11731189
}
11741190

lib/library.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,8 @@ class CPPCHECKLIB Library {
283283
static Action actionFrom(const std::string& actionName);
284284
};
285285
std::map<std::string, Container> containers;
286-
const Container* detectContainer(const Token* typeStart, bool iterator = false) const;
286+
const Container* detectContainer(const Token* typeStart) const;
287+
const Container* detectIterator(const Token* typeStart) const;
287288
const Container* detectContainerOrIterator(const Token* typeStart, bool* isIterator = nullptr) const;
288289

289290
class ArgumentChecks {
@@ -647,6 +648,9 @@ class CPPCHECKLIB Library {
647648
const std::map<std::string, AllocFunc>::const_iterator it = data.find(name);
648649
return (it == data.end()) ? nullptr : &it->second;
649650
}
651+
652+
enum DetectContainer { ContainerOnly, IteratorOnly, Both };
653+
const Library::Container* detectContainerInternal(const Token* typeStart, DetectContainer detect, bool* isIterator = nullptr) const;
650654
};
651655

652656
CPPCHECKLIB const Library::Container * getLibraryContainer(const Token * tok);

test/testlibrary.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "settings.h"
2222
#include "standards.h"
2323
#include "testsuite.h"
24+
#include "testutils.h"
2425
#include "token.h"
2526
#include "tokenize.h"
2627
#include "tokenlist.h"
@@ -865,6 +866,70 @@ class TestLibrary : public TestFixture {
865866
ASSERT_EQUALS(C.size_templateArgNo, -1);
866867
ASSERT_EQUALS(C.stdStringLike, true);
867868
ASSERT_EQUALS(C.arrayLike_indexOp, true);
869+
870+
{
871+
givenACodeSampleToTokenize var("std::A<int> a;");
872+
ASSERT_EQUALS(&A, library.detectContainer(var.tokens()));
873+
ASSERT(!library.detectIterator(var.tokens()));
874+
bool isIterator;
875+
ASSERT_EQUALS(&A, library.detectContainerOrIterator(var.tokens(), &isIterator));
876+
ASSERT(!isIterator);
877+
}
878+
879+
{
880+
givenACodeSampleToTokenize var("std::A<int>::size_type a_s;");
881+
ASSERT(!library.detectContainer(var.tokens()));
882+
ASSERT(!library.detectIterator(var.tokens()));
883+
ASSERT(!library.detectContainerOrIterator(var.tokens()));
884+
}
885+
886+
{
887+
givenACodeSampleToTokenize var("std::A<int>::iterator a_it;");
888+
ASSERT(!library.detectContainer(var.tokens()));
889+
ASSERT_EQUALS(&A, library.detectIterator(var.tokens()));
890+
bool isIterator;
891+
ASSERT_EQUALS(&A, library.detectContainerOrIterator(var.tokens(), &isIterator));
892+
ASSERT(isIterator);
893+
}
894+
895+
{
896+
givenACodeSampleToTokenize var("std::B<int> b;");
897+
ASSERT_EQUALS(&B, library.detectContainer(var.tokens()));
898+
ASSERT(!library.detectIterator(var.tokens()));
899+
bool isIterator;
900+
ASSERT_EQUALS(&B, library.detectContainerOrIterator(var.tokens(), &isIterator));
901+
ASSERT(!isIterator);
902+
}
903+
904+
{
905+
givenACodeSampleToTokenize var("std::B<int>::size_type b_s;");
906+
ASSERT(!library.detectContainer(var.tokens()));
907+
ASSERT(!library.detectIterator(var.tokens()));
908+
ASSERT(!library.detectContainerOrIterator(var.tokens()));
909+
}
910+
911+
{
912+
givenACodeSampleToTokenize var("std::B<int>::iterator b_it;");
913+
ASSERT(!library.detectContainer(var.tokens()));
914+
ASSERT_EQUALS(&B, library.detectIterator(var.tokens()));
915+
bool isIterator;
916+
ASSERT_EQUALS(&B, library.detectContainerOrIterator(var.tokens(), &isIterator));
917+
ASSERT(isIterator);
918+
}
919+
920+
{
921+
givenACodeSampleToTokenize var("C c;");
922+
ASSERT(!library.detectContainer(var.tokens()));
923+
ASSERT(!library.detectIterator(var.tokens()));
924+
ASSERT(!library.detectContainerOrIterator(var.tokens()));
925+
}
926+
927+
{
928+
givenACodeSampleToTokenize var("D d;");
929+
ASSERT(!library.detectContainer(var.tokens()));
930+
ASSERT(!library.detectIterator(var.tokens()));
931+
ASSERT(!library.detectContainerOrIterator(var.tokens()));
932+
}
868933
}
869934

870935
void version() const {

0 commit comments

Comments
 (0)