1 /* 2 * Copyright (C) by Argonne National Laboratory 3 * See COPYRIGHT in top-level directory 4 */ 5 6 #ifndef MPIR_POINTERS_H_INCLUDED 7 #define MPIR_POINTERS_H_INCLUDED 8 9 #include "mpi.h" 10 #include "mpichconf.h" 11 #include "mpichconfconst.h" 12 #include "mpir_assert.h" 13 #include "mpl.h" 14 15 16 /* This test is lame. Should eventually include cookie test 17 and in-range addresses */ 18 #define MPIR_Valid_ptr_class(kind,ptr,errclass,err) \ 19 do { \ 20 if (!(ptr)) { \ 21 err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, errclass, \ 22 "**nullptrtype", "**nullptrtype %s", #kind); \ 23 /* Explicitly tell Coverity that errclass != MPI_SUCCESS => err != MPI_SUCCESS */ \ 24 MPIR_Assert((errclass) == MPI_SUCCESS || ((err) != MPI_SUCCESS)); \ 25 } \ 26 } while (0) 27 28 #define MPIR_Info_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Info,ptr,MPI_ERR_INFO,err) 29 /* Check not only for a null pointer but for an invalid communicator, 30 such as one that has been freed. Let's try the ref_count as the test 31 for now */ 32 /* ticket #1441: check (refcount<=0) to cover the case of 0, an "over-free" of 33 * -1 or similar, and the 0xecec... case when --enable-g=mem is used */ 34 #define MPIR_Comm_valid_ptr(ptr,err,ignore_rev) { \ 35 MPIR_Valid_ptr_class(Comm,ptr,MPI_ERR_COMM,err); \ 36 if ((ptr) && MPIR_Object_get_ref(ptr) <= 0) { \ 37 MPIR_ERR_SET(err,MPI_ERR_COMM,"**comm"); \ 38 ptr = 0; \ 39 } else if ((ptr) && (ptr)->revoked && !(ignore_rev)) { \ 40 MPIR_ERR_SET(err,MPIX_ERR_REVOKED,"**comm"); \ 41 } \ 42 } 43 #define MPIR_Win_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Win,ptr,MPI_ERR_WIN,err) 44 #define MPIR_Group_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Group,ptr,MPI_ERR_GROUP,err) 45 #define MPIR_Op_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Op,ptr,MPI_ERR_OP,err) 46 #define MPIR_Errhandler_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Errhandler,ptr,MPI_ERR_ARG,err) 47 #define MPIR_Request_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Request,ptr,MPI_ERR_REQUEST,err) 48 #define MPII_Keyval_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Keyval,ptr,MPI_ERR_KEYVAL,err) 49 50 51 /* Assigns (src_) to (dst_), checking that (src_) fits in (dst_) without 52 * truncation. 53 * 54 * When fiddling with this macro, please keep C's overly complicated integer 55 * promotion/truncation/conversion rules in mind. A discussion of these issues 56 * can be found in Chapter 5 of "Secure Coding in C and C++" by Robert Seacord. 57 */ 58 #define MPIR_Assign_trunc(dst_,src_,dst_type_) \ 59 do { \ 60 /* will catch some of the cases if the expr_inttype macros aren't available */ \ 61 MPIR_Assert((src_) == (dst_type_)(src_)); \ 62 dst_ = (dst_type_)(src_); \ 63 } while (0) 64 65 /* 66 * Ensure an MPI_Aint value fits into a signed int. 67 * Useful for detecting overflow when MPI_Aint is larger than an int. 68 * 69 * \param[in] aint Variable of type MPI_Aint 70 */ 71 #define MPIR_Ensure_Aint_fits_in_int(aint) \ 72 MPIR_Assert((aint) == (MPI_Aint)(int)(aint)); 73 74 #endif /* MPIR_POINTERS_H_INCLUDED */ 75