MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / checkExplicitConstructors

Method checkExplicitConstructors

lib/checkclass.cpp:388–431  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

386}
387
388void CheckClassImpl::checkExplicitConstructors()
389{
390 if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("noExplicitConstructor"))
391 return;
392
393 logChecker("CheckClass::checkExplicitConstructors"); // style
394
395 for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
396 // Do not perform check, if the class/struct has not any constructors
397 if (scope->numConstructors == 0)
398 continue;
399
400 // Is class abstract? Maybe this test is over-simplification, but it will suffice for simple cases,
401 // and it will avoid false positives.
402 const bool isAbstractClass = std::any_of(scope->functionList.cbegin(), scope->functionList.cend(), [](const Function& func) {
403 return func.isPure();
404 });
405
406 // Abstract classes can't be instantiated. But if there is C++11
407 // "misuse" by derived classes then these constructors must be explicit.
408 if (isAbstractClass && mSettings.standards.cpp >= Standards::CPP11)
409 continue;
410
411 for (const Function &func : scope->functionList) {
412
413 // We are looking for constructors, which are meeting following criteria:
414 // 1) Constructor is declared with a single parameter
415 // 2) Constructor is not declared as explicit
416 // 3) It is not a copy/move constructor of non-abstract class
417 // 4) Constructor is not marked as delete (programmer can mark the default constructor as deleted, which is ok)
418 if (!func.isConstructor() || func.isDelete() || (!func.hasBody() && func.access == AccessControl::Private))
419 continue;
420
421 if (!func.isExplicit() &&
422 func.argCount() > 0 && func.minArgCount() < 2 &&
423 func.type != FunctionType::eCopyConstructor &&
424 func.type != FunctionType::eMoveConstructor &&
425 !(func.templateDef && Token::simpleMatch(func.argumentList.front().typeEndToken(), "...")) &&
426 !isPermissibleConversion(func.argumentList.front().getTypeName())) {
427 noExplicitConstructorError(func.tokenDef, scope->className, scope->type == ScopeType::eStruct);
428 }
429 }
430 }
431}
432
433static bool hasNonCopyableBase(const Scope *scope, bool *unknown)
434{

Callers 1

runChecksMethod · 0.80

Calls 7

isPermissibleConversionFunction · 0.85
isPremiumEnabledMethod · 0.80
isPureMethod · 0.80
frontMethod · 0.80
getTypeNameMethod · 0.80
simpleMatchFunction · 0.70
isEnabledMethod · 0.45

Tested by

no test coverage detected