/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
* (C) 2001 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*
*/
#ifndef MPIR_POINTERS_H_INCLUDED
#define MPIR_POINTERS_H_INCLUDED
#include "mpi.h"
#include "mpichconf.h"
#include "mpichconfconst.h"
#include "mpir_assert.h"
#include "mpl.h"
/* This test is lame. Should eventually include cookie test
and in-range addresses */
#define MPIR_Valid_ptr_class(kind,ptr,errclass,err) \
do { \
if (!(ptr)) { \
err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, errclass, \
"**nullptrtype", "**nullptrtype %s", #kind); \
/* Explicitly tell Coverity that errclass != MPI_SUCCESS => err != MPI_SUCCESS */ \
MPIR_Assert((errclass) == MPI_SUCCESS || ((err) != MPI_SUCCESS)); \
} \
} while (0)
#define MPIR_Info_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Info,ptr,MPI_ERR_INFO,err)
/* Check not only for a null pointer but for an invalid communicator,
such as one that has been freed. Let's try the ref_count as the test
for now */
/* ticket #1441: check (refcount<=0) to cover the case of 0, an "over-free" of
* -1 or similar, and the 0xecec... case when --enable-g=mem is used */
#define MPIR_Comm_valid_ptr(ptr,err,ignore_rev) { \
MPIR_Valid_ptr_class(Comm,ptr,MPI_ERR_COMM,err); \
if ((ptr) && MPIR_Object_get_ref(ptr) <= 0) { \
MPIR_ERR_SET(err,MPI_ERR_COMM,"**comm"); \
ptr = 0; \
} else if ((ptr) && (ptr)->revoked && !(ignore_rev)) { \
MPIR_ERR_SET(err,MPIX_ERR_REVOKED,"**comm"); \
} \
}
#define MPIR_Win_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Win,ptr,MPI_ERR_WIN,err)
#define MPIR_Group_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Group,ptr,MPI_ERR_GROUP,err)
#define MPIR_Op_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Op,ptr,MPI_ERR_OP,err)
#define MPIR_Errhandler_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Errhandler,ptr,MPI_ERR_ARG,err)
#define MPIR_Request_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Request,ptr,MPI_ERR_REQUEST,err)
#define MPII_Keyval_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Keyval,ptr,MPI_ERR_KEYVAL,err)
/* Assigns (src_) to (dst_), checking that (src_) fits in (dst_) without
* truncation.
*
* When fiddling with this macro, please keep C's overly complicated integer
* promotion/truncation/conversion rules in mind. A discussion of these issues
* can be found in Chapter 5 of "Secure Coding in C and C++" by Robert Seacord.
*/
#define MPIR_Assign_trunc(dst_,src_,dst_type_) \
do { \
/* will catch some of the cases if the expr_inttype macros aren't available */ \
MPIR_Assert((src_) == (dst_type_)(src_)); \
dst_ = (dst_type_)(src_); \
} while (0)
/*
* Ensure an MPI_Aint value fits into a signed int.
* Useful for detecting overflow when MPI_Aint is larger than an int.
*
* \param[in] aint Variable of type MPI_Aint
*/
#define MPIR_Ensure_Aint_fits_in_int(aint) \
MPIR_Assert((aint) == (MPI_Aint)(int)(aint));
/*
* Ensure an MPI_Aint value fits into a pointer.
* Useful for detecting overflow when MPI_Aint is larger than a pointer.
*
* \param[in] aint Variable of type MPI_Aint
*/
#ifndef SIZEOF_PTR_IS_AINT
#define MPIR_Ensure_Aint_fits_in_pointer(aint) \
MPIR_Assert((aint) == (MPI_Aint)(uintptr_t) MPIR_AINT_CAST_TO_VOID_PTR(aint));
#else
#define MPIR_Ensure_Aint_fits_in_pointer(aint) do {} while (0)
#endif
#endif /* MPIR_POINTERS_H_INCLUDED */