1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-12-22 12:23:56 +01:00

Add tag to check if memory pointers are valid

This commit is contained in:
Anthony Scemama 2020-10-16 23:38:35 +02:00
parent 87cfdc88d3
commit ec7df80028
2 changed files with 77 additions and 39 deletions

View File

@ -1,5 +1,5 @@
CC=gcc
CFLAGS=-fPIC -fexceptions -Wall -Werror -Wpedantic -Wextra
CFLAGS=-fPIC -fexceptions -Wall -Werror -Wpedantic -Wextra -g
FC=gfortran
FFLAGS=-fcheck=all -Waliasing -Wampersand -Wconversion -Wsurprising -Wintrinsics-std -Wno-tabs -Wintrinsic-shadow -Wline-truncation -Wreal-q-constant -Wuninitialized -fbacktrace -ffpe-trap=zero,overflow,underflow -finit-real=nan

View File

@ -51,25 +51,48 @@ typedef long long int qmckl_context ;
#+BEGIN_SRC C :tangle qmckl_context.c
typedef struct qmckl_context_struct {
struct qmckl_context_struct * prev;
unsigned int tag;
int precision;
int range;
} qmckl_context_struct;
#define VALID_TAG 0xBEEFFACE
#define INVALID_TAG 0xDEADBEEF
#+END_SRC
The tag is used internally to check if the memory domain pointed by
a pointer is a valid context.
*** Test
We declare here the variables used in the tests.
#+BEGIN_SRC C :tangle test_qmckl_context.c
qmckl_context context;
qmckl_context new_context;
#+END_SRC
/* This needs to be repeated in the tests because we don't want to
expose it in the headers.
*/
typedef struct qmckl_context_struct {
struct qmckl_context_struct * prev;
int precision;
int range;
} qmckl_context_struct;
** =qmckl_context_check=
Checks if the domain pointed by the pointer is a valid context.
Returns the input =qmckl_context= if the context is valid, 0 otherwise.
*** Header
#+BEGIN_SRC C :tangle qmckl_context.h
qmckl_context qmckl_context_check(qmckl_context context) ;
#+END_SRC
*** Source
#+BEGIN_SRC C :tangle qmckl_context.c
qmckl_context qmckl_context_check(qmckl_context context) {
qmckl_context_struct * ctx;
if (context == (qmckl_context) 0) return (qmckl_context) 0;
ctx = (qmckl_context_struct*) context;
if (ctx->tag != VALID_TAG) return (qmckl_context) 0;
return context;
}
#+END_SRC
** =qmckl_context_create=
@ -97,6 +120,7 @@ qmckl_context qmckl_context_create() {
context->prev = NULL;
context->precision = QMCKL_DEFAULT_PRECISION;
context->range = QMCKL_DEFAULT_RANGE;
context->tag = VALID_TAG;
return (qmckl_context) context;
}
@ -109,15 +133,14 @@ qmckl_context qmckl_context_create() {
fprintf(stderr,"qmckl_context_create\n");
rc = QMCKL_FAILURE;
}
if ( ((qmckl_context_struct*) new_context)->precision != QMCKL_DEFAULT_PRECISION ) {
fprintf(stderr,"qmckl_context_copy: No access to data\n");
if ( qmckl_context_check(context) != context) {
fprintf(stderr,"qmckl_context_create: Invalid context\n");
rc = QMCKL_FAILURE;
}
#+END_SRC
** =qmckl_context_copy=
This function makes a shallow copy of the current context.
- Copying the 0-valued context returns 0
- On success, returns a pointer to the new context using the =qmckl_context= type
@ -135,8 +158,11 @@ qmckl_context qmckl_context_copy(const qmckl_context context) {
qmckl_context_struct* old_context;
qmckl_context_struct* new_context;
qmckl_context checked_context;
if (context == (qmckl_context) 0) {
checked_context = qmckl_context_check(context);
if (checked_context == (qmckl_context) 0) {
return (qmckl_context) 0;
}
@ -145,14 +171,16 @@ qmckl_context qmckl_context_copy(const qmckl_context context) {
return (qmckl_context) 0;
}
old_context = (qmckl_context_struct*) context;
old_context = (qmckl_context_struct*) checked_context;
new_context->prev = old_context;
new_context->precision = old_context->precision;
new_context->range = old_context->range;
new_context->tag = VALID_TAG;
return (qmckl_context) new_context;
}
#+END_SRC
*** Test
@ -166,10 +194,11 @@ qmckl_context qmckl_context_copy(const qmckl_context context) {
fprintf(stderr,"qmckl_context_copy: Same pointer\n");
rc = QMCKL_FAILURE;
}
if ( ((qmckl_context_struct*) new_context)->precision != QMCKL_DEFAULT_PRECISION ) {
if ( qmckl_context_check(new_context) != new_context) {
fprintf(stderr,"qmckl_context_copy: No access to data\n");
rc = QMCKL_FAILURE;
}
#+END_SRC
** =qmckl_context_previous=
@ -188,33 +217,35 @@ qmckl_context qmckl_context_previous(const qmckl_context context);
#+BEGIN_SRC C :tangle qmckl_context.c
qmckl_context qmckl_context_previous(const qmckl_context context) {
qmckl_context checked_context;
qmckl_context_struct* ctx;
if (context == (qmckl_context) 0) {
checked_context = qmckl_context_check(context);
if (checked_context == (qmckl_context) 0) {
return (qmckl_context) 0;
}
ctx = (qmckl_context_struct*) context;
return (qmckl_context) ctx->prev;
ctx = (qmckl_context_struct*) checked_context;
return qmckl_context_check((qmckl_context) ctx->prev);
}
#+END_SRC
*** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c
if (qmckl_context_previous(new_context) == (qmckl_context) 0) {
fprintf(stderr,"qmckl_context_copy: Null pointer\n");
fprintf(stderr,"qmckl_context_previous: Null pointer\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_previous(new_context) != context) {
fprintf(stderr,"qmckl_context_copy: Wrong pointer\n");
fprintf(stderr,"qmckl_context_previous: Wrong pointer\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_previous(context) != (qmckl_context) 0) {
fprintf(stderr,"qmckl_context_copy: Expected null pointer (1)\n");
fprintf(stderr,"qmckl_context_previous: Expected null pointer (1)\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_previous((qmckl_context) 0) != (qmckl_context) 0) {
fprintf(stderr,"qmckl_context_copy: Expected null pointer (2)\n");
fprintf(stderr,"qmckl_context_previous: Expected null pointer (2)\n");
rc = QMCKL_FAILURE;
}
#+END_SRC
@ -224,45 +255,52 @@ qmckl_context qmckl_context_previous(const qmckl_context context) {
Destroys the current context, leaving the ancestors untouched.
- Succeeds if the current context is properly destroyed
- Fails otherwise
- Fails is the 0-valued context is given in argument
The context given in parameter is overwritten by the 0-valued
context, so a pointer is passed to the function.
- Fails if the 0-valued context is given in argument
- Fails if the the pointer is not a valid context
*** Header
#+BEGIN_SRC C :tangle qmckl_context.h
qmckl_exit_code qmckl_context_destroy(qmckl_context * context);
qmckl_exit_code qmckl_context_destroy(qmckl_context context);
#+END_SRC
*** Source
#+BEGIN_SRC C :tangle qmckl_context.c
qmckl_exit_code qmckl_context_destroy(qmckl_context *context) {
qmckl_exit_code qmckl_context_destroy(qmckl_context context) {
qmckl_context_struct* ctx;
qmckl_context checked_context;
ctx = (qmckl_context_struct*) *context;
checked_context = qmckl_context_check(context);
if (checked_context == (qmckl_context) 0) return QMCKL_FAILURE;
if (ctx == NULL) {
return QMCKL_FAILURE;
}
ctx = (qmckl_context_struct*) context;
if (ctx == NULL) return QMCKL_FAILURE;
ctx->tag = INVALID_TAG;
free(ctx);
*context = (qmckl_context) 0;
return QMCKL_SUCCESS;
}
#+END_SRC
*** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c
if (qmckl_context_check(new_context) != new_context) {
fprintf(stderr,"qmckl_context_destroy: new_context is invalid\n");
rc = QMCKL_FAILURE;
}
if (new_context == (qmckl_context) 0) {
fprintf(stderr,"qmckl_context_destroy: new_context is NULL\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_destroy(&new_context) == QMCKL_FAILURE) {
if (qmckl_context_destroy(new_context) == QMCKL_FAILURE) {
fprintf(stderr,"qmckl_context_destroy: Unable to destroy the new_context\n");
rc = QMCKL_FAILURE;
}
if (new_context != (qmckl_context) 0) {
if (qmckl_context_check(new_context) == new_context) {
fprintf(stderr,"qmckl_context_destroy: new_context is valid\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_check(new_context) != (qmckl_context) 0) {
fprintf(stderr,"qmckl_context_destroy: new_context should be NULL\n");
rc = QMCKL_FAILURE;
}