Exemple #1
0
/**
 * Select apprioriate function to match the buffer type against
 * the specified mpi datatype.
 *
 * @param typeVisitor contains information about the buffer
 * @param mpiCall call whose arguments are observed
 * @param mpiDatatypeString
 * @param idxPair bufferIdx, mpiDatatypeIdx
 */
void MPICheckerAST::selectTypeMatcher(
    const mpi::TypeVisitor &typeVisitor, const MPICall &mpiCall,
    const StringRef mpiDatatypeString,
    const std::pair<size_t, size_t> &idxPair) const {
    const clang::BuiltinType *builtinType = typeVisitor.builtinType();
    bool isTypeMatching{true};

    // check for exact width types (e.g. int16_t, uint32_t)
    if (typeVisitor.isTypedefType()) {
        isTypeMatching = matchExactWidthType(typeVisitor, mpiDatatypeString);
    }
    // check for complex-floating types (e.g. float _Complex)
    else if (typeVisitor.isComplexType()) {
        isTypeMatching = matchComplexType(typeVisitor, mpiDatatypeString);
    }
    // check for basic builtin types (e.g. int, char)
    else if (!builtinType) {
        return;  // if no builtin type cancel checking
    } else if (builtinType->isBooleanType()) {
        isTypeMatching = matchBoolType(typeVisitor, mpiDatatypeString);
    } else if (builtinType->isAnyCharacterType()) {
        isTypeMatching = matchCharType(typeVisitor, mpiDatatypeString);
    } else if (builtinType->isSignedInteger()) {
        isTypeMatching = matchSignedType(typeVisitor, mpiDatatypeString);
    } else if (builtinType->isUnsignedIntegerType()) {
        isTypeMatching = matchUnsignedType(typeVisitor, mpiDatatypeString);
    } else if (builtinType->isFloatingType()) {
        isTypeMatching = matchFloatType(typeVisitor, mpiDatatypeString);
    }

    if (!isTypeMatching)
        bugReporter_.reportTypeMismatch(mpiCall.callExpr(), idxPair,
                                        typeVisitor.qualType_,
                                        mpiDatatypeString);
}
Exemple #2
0
bool MPICheckerAST::matchCharType(const mpi::TypeVisitor &visitor,
                                  const llvm::StringRef mpiDatatype) const {
    bool isTypeMatching;
    switch (visitor.builtinType()->getKind()) {
    case BuiltinType::SChar:
        isTypeMatching =
            (mpiDatatype == "MPI_CHAR" || mpiDatatype == "MPI_SIGNED_CHAR");
        break;
    case BuiltinType::Char_S:
        isTypeMatching =
            (mpiDatatype == "MPI_CHAR" || mpiDatatype == "MPI_SIGNED_CHAR");
        break;
    case BuiltinType::UChar:
        isTypeMatching = (mpiDatatype == "MPI_UNSIGNED_CHAR");
        break;
    case BuiltinType::Char_U:
        isTypeMatching = (mpiDatatype == "MPI_UNSIGNED_CHAR");
        break;
    case BuiltinType::WChar_S:
        isTypeMatching = (mpiDatatype == "MPI_WCHAR");
        break;
    case BuiltinType::WChar_U:
        isTypeMatching = (mpiDatatype == "MPI_WCHAR");
        break;

    default:
        isTypeMatching = true;
    }

    return isTypeMatching;
}
Exemple #3
0
/**
 * Check if invalid argument types are used in a mpi call.
 * This check looks at indices where only integer values are valid.
 * (count, rank, tag) Any non integer type usage is reported.
 *
 * @param mpiCall to check the arguments for
 */
void MPICheckerAST::checkForInvalidArgs(const MPICall &mpiCall) const {
    std::vector<size_t> indicesToCheck = integerIndices(mpiCall);
    if (!indicesToCheck.size()) return;

    // iterate indices which should not have integer arguments
    for (const size_t idx : indicesToCheck) {
        // check for invalid variable types
        const auto &arg = mpiCall.arguments()[idx];
        const auto &vars = arg.vars();
        for (const auto &var : vars) {
            const mpi::TypeVisitor typeVisitor{var->getType()};
            if (!typeVisitor.builtinType() ||
                !typeVisitor.builtinType()->isIntegerType()) {
                bugReporter_.reportInvalidArgumentType(
                    mpiCall.callExpr(), idx, var->getSourceRange(), "Variable");
            }
        }

        // check for float literals
        if (arg.floatingLiterals().size()) {
            bugReporter_.reportInvalidArgumentType(
                mpiCall.callExpr(), idx,
                arg.floatingLiterals().front()->getSourceRange(), "Literal");
        }

        // check for invalid return types from functions
        const auto &functions = arg.functions();
        for (const auto &function : functions) {
            const mpi::TypeVisitor typeVisitor{function->getReturnType()};
            if (!typeVisitor.builtinType() ||
                !typeVisitor.builtinType()->isIntegerType()) {
                bugReporter_.reportInvalidArgumentType(
                    mpiCall.callExpr(), idx, function->getSourceRange(),
                    "Return value");
            }
        }
    }
}
Exemple #4
0
bool MPICheckerAST::matchFloatType(const mpi::TypeVisitor &visitor,
                                   const llvm::StringRef mpiDatatype) const {
    bool isTypeMatching;

    switch (visitor.builtinType()->getKind()) {
    case BuiltinType::Float:
        isTypeMatching = (mpiDatatype == "MPI_FLOAT");
        break;
    case BuiltinType::Double:
        isTypeMatching = (mpiDatatype == "MPI_DOUBLE");
        break;
    case BuiltinType::LongDouble:
        isTypeMatching = (mpiDatatype == "MPI_LONG_DOUBLE");
        break;
    default:
        isTypeMatching = true;
    }
    return isTypeMatching;
}
Exemple #5
0
bool MPICheckerAST::matchUnsignedType(const mpi::TypeVisitor &visitor,
                                      const llvm::StringRef mpiDatatype) const {
    bool isTypeMatching;

    switch (visitor.builtinType()->getKind()) {
    case BuiltinType::UInt:
        isTypeMatching = (mpiDatatype == "MPI_UNSIGNED");
        break;
    case BuiltinType::UShort:
        isTypeMatching = (mpiDatatype == "MPI_UNSIGNED_SHORT");
        break;
    case BuiltinType::ULong:
        isTypeMatching = (mpiDatatype == "MPI_UNSIGNED_LONG");
        break;
    case BuiltinType::ULongLong:
        isTypeMatching = (mpiDatatype == "MPI_UNSIGNED_LONG_LONG");
        break;

    default:
        isTypeMatching = true;
    }
    return isTypeMatching;
}