void MultiwayPathsCoveredCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(
      switchStmt(
          hasCondition(allOf(
              // Match on switch statements that have either a bit-field or
              // an integer condition. The ordering in 'anyOf()' is
              // important because the last condition is the most general.
              anyOf(ignoringImpCasts(memberExpr(hasDeclaration(
                        fieldDecl(isBitField()).bind("bitfield")))),
                    ignoringImpCasts(declRefExpr().bind("non-enum-condition"))),
              // 'unless()' must be the last match here and must be bound,
              // otherwise the matcher does not work correctly, because it
              // will not explicitly ignore enum conditions.
              unless(ignoringImpCasts(
                  declRefExpr(hasType(enumType())).bind("enum-condition"))))))
          .bind("switch"),
      this);

  // This option is noisy, therefore matching is configurable.
  if (WarnOnMissingElse) {
    Finder->addMatcher(
        ifStmt(allOf(hasParent(ifStmt()), unless(hasElse(anything()))))
            .bind("else-if"),
        this);
  }
}
bool BitFieldAggregation::getBitFieldAggregations(TYPECONST Type *type, const EDIType *aEDIType, std::vector<BitFieldAggregation> &bfas, bool returnOnError) {
    std::vector<BitFieldAggregation> emptyBfas;
    if(!hasBitFields(type, aEDIType)) {
        return true;
    }
    unsigned typeIndex = 0;
    unsigned EDITypeIndex = 0;
    unsigned typeContainedTypes = type->getNumContainedTypes();
    unsigned aEDITypeContainedTypes = aEDIType->getNumContainedTypes();
    unsigned counter = 1;
    const EDIType privateEDIType(*aEDIType);
    aEDIType = &privateEDIType;
    while(typeIndex < typeContainedTypes) {
        TYPECONST Type *containedType = type->getContainedType(typeIndex);
        if(EDITypeIndex >= aEDITypeContainedTypes && typeIndex == typeContainedTypes-1 && TypeUtil::isPaddedType(type)) {
            break;
        }
        BitFieldAggregation_assert_or_return(returnOnError, false, type, aEDIType, EDITypeIndex < aEDITypeContainedTypes);
        const EDIType containedEDIType = aEDIType->getContainedType(EDITypeIndex);
        unsigned typeBits = TypeUtil::typeToBits(containedType);
        if(typeBits > 0 && containedEDIType.isIntegerTy()) {
            unsigned EDITypeBits = aEDIType->getMember(EDITypeIndex).getSizeInBits();
            assert(typeBits >= EDITypeBits);
            if(typeBits > EDITypeBits) {
                unsigned lastTypeIndex = typeIndex;
                unsigned lastEDITypeIndex = EDITypeIndex;
                while(lastEDITypeIndex+1 < aEDITypeContainedTypes && isBitField(type, aEDIType, lastEDITypeIndex+1)) { // grab all the bitfields following the first one found
                    lastEDITypeIndex++;
                    EDITypeBits += aEDIType->getMember(lastEDITypeIndex).getSizeInBits();
                }
                while(lastTypeIndex+1 < typeContainedTypes && EDITypeBits > typeBits) { // grab all the necessary fields to cover all the bits found in the bitfields
                    lastTypeIndex++;
                    typeBits += TypeUtil::typeToBits(type->getContainedType(lastTypeIndex));
                }
                BitFieldAggregation *bfa = BitFieldAggregation::getBitFieldAggregation(type, aEDIType, returnOnError, typeIndex, EDITypeIndex, lastTypeIndex, lastEDITypeIndex, counter++);
                BitFieldAggregation_assert_or_return(returnOnError, false, type, aEDIType, bfa != NULL);
                if(bfa->getSize() > 1) {
                    //we don't care about single-element aggregates
                    bfas.push_back(*bfa);
                }
                typeIndex++;
                EDITypeIndex += bfa->getSize();
                continue;
            }
        }
        typeIndex++;
        EDITypeIndex++;
    }
    return true;
}
예제 #3
0
void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus11)
    return;

  // FIXME: Bunch of functionality that could be easily added:
  // + add handling of `push_front` for std::forward_list, std::list
  // and std::deque.
  // + add handling of `push` for std::stack, std::queue, std::priority_queue
  // + add handling of `insert` for stl associative container, but be careful
  // because this requires special treatment (it could cause performance
  // regression)
  // + match for emplace calls that should be replaced with insertion
  // + match for make_pair calls.
  auto callPushBack = cxxMemberCallExpr(
      hasDeclaration(functionDecl(hasName("push_back"))),
      on(hasType(cxxRecordDecl(hasAnyName(SmallVector<StringRef, 5>(
          ContainersWithPushBack.begin(), ContainersWithPushBack.end()))))));

  // We can't replace push_backs of smart pointer because
  // if emplacement fails (f.e. bad_alloc in vector) we will have leak of
  // passed pointer because smart pointer won't be constructed
  // (and destructed) as in push_back case.
  auto isCtorOfSmartPtr = hasDeclaration(cxxConstructorDecl(ofClass(hasAnyName(
      SmallVector<StringRef, 5>(SmartPointers.begin(), SmartPointers.end())))));

  // Bitfields binds only to consts and emplace_back take it by universal ref.
  auto bitFieldAsArgument = hasAnyArgument(
      ignoringImplicit(memberExpr(hasDeclaration(fieldDecl(isBitField())))));

  // Initializer list can't be passed to universal reference.
  auto initializerListAsArgument = hasAnyArgument(
      ignoringImplicit(cxxConstructExpr(isListInitialization())));

  // We could have leak of resource.
  auto newExprAsArgument = hasAnyArgument(ignoringImplicit(cxxNewExpr()));
  // We would call another constructor.
  auto constructingDerived =
      hasParent(implicitCastExpr(hasCastKind(CastKind::CK_DerivedToBase)));

  // emplace_back can't access private constructor.
  auto isPrivateCtor = hasDeclaration(cxxConstructorDecl(isPrivate()));

  auto hasInitList = has(ignoringImplicit(initListExpr()));
  // FIXME: Discard 0/NULL (as nullptr), static inline const data members,
  // overloaded functions and template names.
  auto soughtConstructExpr =
      cxxConstructExpr(
          unless(anyOf(isCtorOfSmartPtr, hasInitList, bitFieldAsArgument,
                       initializerListAsArgument, newExprAsArgument,
                       constructingDerived, isPrivateCtor)))
          .bind("ctor");
  auto hasConstructExpr = has(ignoringImplicit(soughtConstructExpr));

  auto ctorAsArgument = materializeTemporaryExpr(
      anyOf(hasConstructExpr, has(cxxFunctionalCastExpr(hasConstructExpr))));

  Finder->addMatcher(cxxMemberCallExpr(callPushBack, has(ctorAsArgument),
                                       unless(isInTemplateInstantiation()))
                         .bind("call"),
                     this);
}
예제 #4
0
파일: funcs.c 프로젝트: cmjonze/evlog_cvs
/*
 * For each non-const attribute in template t, print the appropriate args
 * in the call to evl_log_write().
 */
static void
printAttArgs(const evltemplate_t *t, const char *prefix)
{
	evl_listnode_t *head = t->tm_attributes, *end, *p;
	const evltemplate_t *st;	/* struct attribute's template */

	for (end=NULL, p=head; p!=end; end=head, p=p->li_next) {
		evlattribute_t *att = (evlattribute_t*) p->li_data;
		int ty;

		if (isConstAtt(att)) {
			continue;
		}
		if (isBitField(att)) {
			notSupported("bit-fields");
			continue;
		}

		ty = evlatt_gettype(att);
		if (isArray(att)) {
			char *dimString;

			dimString = getDimensionString(att, prefix);
			if (ty == TY_STRUCT) {
				/* Array of structs */
				st = att->ta_type->u.st_template;
				if ((st->tm_flags & TMPL_TF_ALIGNED) != 0) {
					/* Array of aligned structs */
					printf(
"\t\"char[]\",\t%s*sizeof(struct %s),\t%s%s,\n",
						dimString, st->tm_name, prefix,
						att->ta_name);
				} else {
					notSupported("arrays of unaligned structs");
				}
			} else {
				/* Array of scalars or strings */
				printf(
"\t\"%s[]\",\t%s,\t%s%s,\n",
					typeName(ty), dimString, prefix,
					att->ta_name);
			}

			free(dimString);
		} else {
			/* Not an array */
			if (ty == TY_STRUCT) {
				st = att->ta_type->u.st_template;
				if ((st->tm_flags & TMPL_TF_ALIGNED) != 0) {
					printf(
"\t\"char[]\",\tsizeof(struct %s),\t%s%s,\n",
						st->tm_name, prefix,
						att->ta_name);
				} else {
					/* Unaligned struct.  Print all its members. */
					size_t newPrefixSize = strlen(prefix)
						+ strlen(att->ta_name) + 1;
					char *newPrefix = (char*)
						malloc(newPrefixSize);
					assert(newPrefix != NULL);
					snprintf(newPrefix, newPrefixSize, "%s%s.", prefix,
						att->ta_name);
					printAttArgs(st, newPrefix);
					free(newPrefix);
				}
			} else {
				/* Not an array or struct */
				printf(
"\t\"%s\",\t%s%s,\n",
					typeName(ty), prefix, att->ta_name);
			}
		}
	}
}