Ejemplo n.º 1
0
void UseNodiscardCheck::registerMatchers(MatchFinder *Finder) {
  // If we use ``[[nodiscard]]`` attribute, we require at least C++17. Use a
  // macro or ``__attribute__`` with pre c++17 compilers by using
  // ReplacementString option.
  if ((NoDiscardMacro == "[[nodiscard]]" && !getLangOpts().CPlusPlus17) ||
      !getLangOpts().CPlusPlus)
    return;

  auto FunctionObj =
      cxxRecordDecl(hasAnyName("::std::function", "::boost::function"));

  // Find all non-void const methods which have not already been marked to
  // warn on unused result.
  Finder->addMatcher(
      cxxMethodDecl(
          allOf(isConst(), isDefinitionOrInline(),
                unless(anyOf(
                    returns(voidType()), isNoReturn(), isOverloadedOperator(),
                    isVariadic(), hasTemplateReturnType(),
                    hasClassMutableFields(), isConversionOperator(),
                    hasAttr(clang::attr::WarnUnusedResult),
                    hasType(isInstantiationDependentType()),
                    hasAnyParameter(anyOf(
                        parmVarDecl(anyOf(hasType(FunctionObj),
                                          hasType(references(FunctionObj)))),
                        hasType(isNonConstReferenceOrPointer()),
                        hasParameterPack()))))))
          .bind("no_discard"),
      this);
}
void ConstReturnTypeCheck::registerMatchers(MatchFinder *Finder) {
  // Find all function definitions for which the return types are `const`
  // qualified.
  Finder->addMatcher(
      functionDecl(returns(isConstQualified()), isDefinition()).bind("func"),
      this);
}
void AssignOperatorSignatureCheck::registerMatchers(
    ast_matchers::MatchFinder *Finder) {
  // Only register the matchers for C++; the functionality currently does not
  // provide any benefit to other languages, despite being benign.
  if (getLangOpts().CPlusPlus) {
    const auto HasGoodReturnType = methodDecl(returns(lValueReferenceType(
        pointee(unless(isConstQualified()),
                hasDeclaration(equalsBoundNode("class"))))));

    const auto IsSelf = qualType(anyOf(
        hasDeclaration(equalsBoundNode("class")),
        referenceType(pointee(hasDeclaration(equalsBoundNode("class"))))));
    const auto IsSelfAssign =
        methodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
                   hasName("operator="), ofClass(recordDecl().bind("class")),
                   hasParameter(0, parmVarDecl(hasType(IsSelf))))
            .bind("method");

    Finder->addMatcher(
        methodDecl(IsSelfAssign, unless(HasGoodReturnType)).bind("ReturnType"),
        this);

    const auto BadSelf = referenceType(
        anyOf(lValueReferenceType(pointee(unless(isConstQualified()))),
              rValueReferenceType(pointee(isConstQualified()))));

    Finder->addMatcher(
        methodDecl(IsSelfAssign, hasParameter(0, parmVarDecl(hasType(BadSelf))))
            .bind("ArgumentType"),
        this);

    Finder->addMatcher(methodDecl(IsSelfAssign, isConst()).bind("Const"), this);
  }
}
void CloexecSocketCheck::registerMatchers(MatchFinder *Finder) {
  registerMatchersImpl(Finder,
                       functionDecl(isExternC(), returns(isInteger()),
                                    hasName("socket"),
                                    hasParameter(0, hasType(isInteger())),
                                    hasParameter(1, hasType(isInteger())),
                                    hasParameter(2, hasType(isInteger()))));
}
Ejemplo n.º 5
0
_tsTraceMethodExt &_tsTraceMethodExt::returnCOM(HRESULT hr)
{
	tscrypto::tsCryptoString sHr = COMMessage(hr);

	setErrorTo(FAILED(hr) != FALSE);
	m_outMessage = sHr;
	returns(hr);
	return *this;
}
void CloexecAcceptCheck::registerMatchers(MatchFinder *Finder) {
  auto SockAddrPointerType =
      hasType(pointsTo(recordDecl(isStruct(), hasName("sockaddr"))));
  auto SockLenPointerType = hasType(pointsTo(namedDecl(hasName("socklen_t"))));

  registerMatchersImpl(Finder,
                       functionDecl(returns(isInteger()), hasName("accept"),
                                    hasParameter(0, hasType(isInteger())),
                                    hasParameter(1, SockAddrPointerType),
                                    hasParameter(2, SockLenPointerType)));
}
void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) {
  // Only register the matchers for C++; the functionality currently does not
  // provide any benefit to other languages, despite being benign.
  if (!getLangOpts().CPlusPlus)
    return;

  const auto ValidContainer = cxxRecordDecl(isSameOrDerivedFrom(
      namedDecl(
          has(cxxMethodDecl(
                  isConst(), parameterCountIs(0), isPublic(), hasName("size"),
                  returns(qualType(isInteger(), unless(booleanType()))))
                  .bind("size")),
          has(cxxMethodDecl(isConst(), parameterCountIs(0), isPublic(),
                            hasName("empty"), returns(booleanType()))
                  .bind("empty")))
          .bind("container")));

  const auto WrongUse = anyOf(
      hasParent(binaryOperator(
                    matchers::isComparisonOperator(),
                    hasEitherOperand(ignoringImpCasts(anyOf(
                        integerLiteral(equals(1)), integerLiteral(equals(0))))))
                    .bind("SizeBinaryOp")),
      hasParent(implicitCastExpr(
          hasImplicitDestinationType(booleanType()),
          anyOf(
              hasParent(unaryOperator(hasOperatorName("!")).bind("NegOnSize")),
              anything()))),
      hasParent(explicitCastExpr(hasDestinationType(booleanType()))));

  Finder->addMatcher(
      cxxMemberCallExpr(on(expr(anyOf(hasType(ValidContainer),
                                      hasType(pointsTo(ValidContainer)),
                                      hasType(references(ValidContainer))))
                               .bind("STLObject")),
                        callee(cxxMethodDecl(hasName("size"))), WrongUse)
          .bind("SizeCallExpr"),
      this);
}
void UnconventionalAssignOperatorCheck::registerMatchers(
    ast_matchers::MatchFinder *Finder) {
  // Only register the matchers for C++; the functionality currently does not
  // provide any benefit to other languages, despite being benign.
  if (!getLangOpts().CPlusPlus)
    return;

  const auto HasGoodReturnType = cxxMethodDecl(returns(lValueReferenceType(
      pointee(unless(isConstQualified()),
              anyOf(autoType(), hasDeclaration(equalsBoundNode("class")))))));

  const auto IsSelf = qualType(
      anyOf(hasDeclaration(equalsBoundNode("class")),
            referenceType(pointee(hasDeclaration(equalsBoundNode("class"))))));
  const auto IsAssign =
      cxxMethodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
                    hasName("operator="), ofClass(recordDecl().bind("class")))
          .bind("method");
  const auto IsSelfAssign =
      cxxMethodDecl(IsAssign, hasParameter(0, parmVarDecl(hasType(IsSelf))))
          .bind("method");

  Finder->addMatcher(
      cxxMethodDecl(IsAssign, unless(HasGoodReturnType)).bind("ReturnType"),
      this);

  const auto BadSelf = referenceType(
      anyOf(lValueReferenceType(pointee(unless(isConstQualified()))),
            rValueReferenceType(pointee(isConstQualified()))));

  Finder->addMatcher(
      cxxMethodDecl(IsSelfAssign,
                    hasParameter(0, parmVarDecl(hasType(BadSelf))))
          .bind("ArgumentType"),
      this);

  Finder->addMatcher(
      cxxMethodDecl(IsSelfAssign, anyOf(isConst(), isVirtual())).bind("cv"),
      this);

  const auto IsBadReturnStatement = returnStmt(unless(has(ignoringParenImpCasts(
      anyOf(unaryOperator(hasOperatorName("*"), hasUnaryOperand(cxxThisExpr())),
            cxxOperatorCallExpr(argumentCountIs(1),
                                callee(unresolvedLookupExpr()),
                                hasArgument(0, cxxThisExpr())))))));
  const auto IsGoodAssign = cxxMethodDecl(IsAssign, HasGoodReturnType);

  Finder->addMatcher(returnStmt(IsBadReturnStatement, forFunction(IsGoodAssign))
                         .bind("returnStmt"),
                     this);
}
void TrailingReturnCheck::registerMatchers(MatchFinder *Finder) {

  // Requires C++11 or later.
  if (!getLangOpts().CPlusPlus11)
    return;

  // Functions that have trailing returns are disallowed, except for those
  // using decltype specifiers and lambda with otherwise unutterable
  // return types.
  Finder->addMatcher(
      functionDecl(allOf(hasTrailingReturn(),
                         unless(anyOf(returns(decltypeType()),
                                      hasParent(cxxRecordDecl(isLambda()))))))
          .bind("decl"),
      this);
}
void UseToStringCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  Finder->addMatcher(
      callExpr(
          hasDeclaration(functionDecl(
              returns(hasDeclaration(classTemplateSpecializationDecl(
                  hasName("std::basic_string"),
                  hasTemplateArgument(0,
                                      templateArgument().bind("char_type"))))),
              hasName("boost::lexical_cast"),
              hasParameter(0, hasType(qualType(has(substTemplateTypeParmType(
                                  isStrictlyInteger()))))))),
          argumentCountIs(1), unless(isInTemplateInstantiation()))
          .bind("to_string"),
      this);
}
Ejemplo n.º 11
0
_tsTraceMethodExt &_tsTraceMethodExt::returnCOMMsg(HRESULT hr, tscrypto::tsCryptoString fmt, ...)
{
	tscrypto::tsCryptoString sHr;
	va_list args;

	switch (hr)
	{
	case S_OK: sHr = "OK"; break;
	case S_FALSE: sHr = "FALSE"; break;
	case E_NOTIMPL: sHr = "Not Implemented"; break;
	case E_UNEXPECTED: sHr = "Unexpected operation"; break;
	case E_OUTOFMEMORY: sHr = "Out Of Memory"; break;
	case E_INVALIDARG: sHr = "Invalid Argument"; break;
	case E_NOINTERFACE: sHr = "No Interface"; break;
	case E_POINTER: sHr = "Invalid Pointer"; break;
	case E_HANDLE: sHr = "Invalid Handle"; break;
	case E_ABORT: sHr = "Aborted"; break;
	case E_FAIL: sHr = "General Failure"; break;
	case E_ACCESSDENIED: sHr = "Access Denied"; break;
	case E_PENDING: sHr = ""; break;
	default:
		sHr.Format("0x%08X", hr);
		break;
	}
	setErrorTo(FAILED(hr) != FALSE);
	va_start(args, fmt);
	m_outMessage.clear();
	m_outMessage.resize(MAX_TRACE_MSG_LEN);
#ifdef HAVE__VSNPRINTF_S
	_vsnprintf_s(m_outMessage.rawData(), m_outMessage.size(), m_outMessage.size(), fmt.c_str(), args);
#elif defined(HAVE_VSNPRINTF)
	vsnprintf(m_outMessage.rawData(), m_outMessage.size(), fmt.c_str(), args);
#elif defined(HAVE_VSPRINTF_S)
	vsprintf_s(m_outMessage.rawData(), m_outMessage.size(), fmt.c_str(), args);
#elif defined(HAVE_VSPRINTF)
	vsprintf(m_outMessage.rawData(), fmt.c_str(), args);
#else
#error Implement me
#endif
	m_outMessage.resize((uint32_t)TsStrLen(m_outMessage.c_str()));
	m_outMessage.Replace("~~", sHr.c_str());
	returns(hr);
	return *this;
}