From 1d677c57a8322506b3a6279f45c9e19e992835d4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 7 Jun 2022 21:15:13 +0200 Subject: [PATCH] Fix #11126 FN: noExplicitConstructor with single default parameter (#4174) --- gui/helpdialog.h | 2 +- lib/analyzer.h | 2 +- lib/checkclass.cpp | 3 ++- lib/checkleakautovar.h | 2 +- lib/forwardanalyzer.cpp | 6 +++--- lib/symboldatabase.h | 2 +- test/testclass.cpp | 13 +++++++++++++ 7 files changed, 22 insertions(+), 8 deletions(-) diff --git a/gui/helpdialog.h b/gui/helpdialog.h index 9ad985a77..a3dd21269 100644 --- a/gui/helpdialog.h +++ b/gui/helpdialog.h @@ -32,7 +32,7 @@ namespace Ui { class HelpBrowser : public QTextBrowser { public: - HelpBrowser(QWidget* parent = nullptr) : QTextBrowser(parent), mHelpEngine(nullptr) {} + explicit HelpBrowser(QWidget* parent = nullptr) : QTextBrowser(parent), mHelpEngine(nullptr) {} void setHelpEngine(QHelpEngine *helpEngine); QVariant loadResource(int type, const QUrl& name) override; private: diff --git a/lib/analyzer.h b/lib/analyzer.h index 2ab5544a3..39deb6049 100644 --- a/lib/analyzer.h +++ b/lib/analyzer.h @@ -130,7 +130,7 @@ struct Analyzer { enum class Terminate { None, Bail, Escape, Modified, Inconclusive, Conditional }; struct Result { - Result(Action action = Action::None, Terminate terminate = Terminate::None) + explicit Result(Action action = Action::None, Terminate terminate = Terminate::None) : action(action), terminate(terminate) {} Action action; diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 58ff47d59..99627e583 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -353,7 +353,8 @@ void CheckClass::checkExplicitConstructors() continue; if (!func.isExplicit() && - func.minArgCount() == 1 && + func.argCount() > 0 && func.minArgCount() < 2 && + func.argumentList.front().getTypeName() != "std::initializer_list" && func.type != Function::eCopyConstructor && func.type != Function::eMoveConstructor) { noExplicitConstructorError(func.tokenDef, scope->className, scope->type == Scope::eStruct); diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index 1452d4aeb..8fa720ab9 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -49,7 +49,7 @@ public: int type; int reallocedFromType = -1; const Token * allocTok; - AllocInfo(int type_ = 0, AllocStatus status_ = NOALLOC, const Token* allocTok_ = nullptr) : status(status_), type(type_), allocTok(allocTok_) {} + explicit AllocInfo(int type_ = 0, AllocStatus status_ = NOALLOC, const Token* allocTok_ = nullptr) : status(status_), type(type_), allocTok(allocTok_) {} bool managed() const { return status < 0; diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index a00b1e363..32d5d5e43 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -68,7 +68,7 @@ struct ForwardTraversal { } struct Branch { - Branch(Token* tok = nullptr) : endBlock(tok) {} + explicit Branch(Token* tok = nullptr) : endBlock(tok) {} Token* endBlock = nullptr; Analyzer::Action action = Analyzer::Action::None; bool check = false; @@ -857,12 +857,12 @@ Analyzer::Result valueFlowGenericForward(Token* start, const Token* end, const V { ForwardTraversal ft{a, settings}; ft.updateRange(start, end); - return {ft.actions, ft.terminate}; + return Analyzer::Result{ ft.actions, ft.terminate }; } Analyzer::Result valueFlowGenericForward(Token* start, const ValuePtr& a, const Settings* settings) { ForwardTraversal ft{a, settings}; ft.updateRecursive(start); - return {ft.actions, ft.terminate}; + return Analyzer::Result{ ft.actions, ft.terminate }; } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index c5eb887e7..0cafd4067 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -107,7 +107,7 @@ public: const Token * typeEnd; MathLib::bigint sizeOf; - Type(const Token* classDef_ = nullptr, const Scope* classScope_ = nullptr, const Scope* enclosingScope_ = nullptr) : + explicit Type(const Token* classDef_ = nullptr, const Scope* classScope_ = nullptr, const Scope* enclosingScope_ = nullptr) : classDef(classDef_), classScope(classScope_), enclosingScope(enclosingScope_), diff --git a/test/testclass.cpp b/test/testclass.cpp index ef21cf9b6..131fcf868 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -480,6 +480,19 @@ private: " explicit constexpr Baz(int) {}\n" "};\n"); ASSERT_EQUALS("", errout.str()); + + checkExplicitConstructors("class Token;\n" // #11126 + "struct Branch {\n" + " Branch(Token* tok = nullptr) : endBlock(tok) {}\n" + " Token* endBlock = nullptr;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3]: (style) Struct 'Branch' has a constructor with 1 argument that is not explicit.\n", errout.str()); + + checkExplicitConstructors("struct S {\n" + " S(std::initializer_list il) : v(il) {}\n" + " std::vector v;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); } #define checkDuplInheritedMembers(code) checkDuplInheritedMembers_(code, __FILE__, __LINE__)