1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-08-17 02:41:43 +02: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 CC=gcc
CFLAGS=-fPIC -fexceptions -Wall -Werror -Wpedantic -Wextra CFLAGS=-fPIC -fexceptions -Wall -Werror -Wpedantic -Wextra -g
FC=gfortran 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 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,27 +51,50 @@ typedef long long int qmckl_context ;
#+BEGIN_SRC C :tangle qmckl_context.c #+BEGIN_SRC C :tangle qmckl_context.c
typedef struct qmckl_context_struct { typedef struct qmckl_context_struct {
struct qmckl_context_struct * prev; struct qmckl_context_struct * prev;
unsigned int tag;
int precision; int precision;
int range; int range;
} qmckl_context_struct; } qmckl_context_struct;
#define VALID_TAG 0xBEEFFACE
#define INVALID_TAG 0xDEADBEEF
#+END_SRC #+END_SRC
The tag is used internally to check if the memory domain pointed by
a pointer is a valid context.
*** Test *** Test
We declare here the variables used in the tests. We declare here the variables used in the tests.
#+BEGIN_SRC C :tangle test_qmckl_context.c #+BEGIN_SRC C :tangle test_qmckl_context.c
qmckl_context context; qmckl_context context;
qmckl_context new_context; qmckl_context new_context;
/* 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;
#+END_SRC #+END_SRC
** =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= ** =qmckl_context_create=
To create a new context, use =qmckl_context_create()=. To create a new context, use =qmckl_context_create()=.
@ -97,6 +120,7 @@ qmckl_context qmckl_context_create() {
context->prev = NULL; context->prev = NULL;
context->precision = QMCKL_DEFAULT_PRECISION; context->precision = QMCKL_DEFAULT_PRECISION;
context->range = QMCKL_DEFAULT_RANGE; context->range = QMCKL_DEFAULT_RANGE;
context->tag = VALID_TAG;
return (qmckl_context) context; return (qmckl_context) context;
} }
@ -109,15 +133,14 @@ qmckl_context qmckl_context_create() {
fprintf(stderr,"qmckl_context_create\n"); fprintf(stderr,"qmckl_context_create\n");
rc = QMCKL_FAILURE; rc = QMCKL_FAILURE;
} }
if ( ((qmckl_context_struct*) new_context)->precision != QMCKL_DEFAULT_PRECISION ) { if ( qmckl_context_check(context) != context) {
fprintf(stderr,"qmckl_context_copy: No access to data\n"); fprintf(stderr,"qmckl_context_create: Invalid context\n");
rc = QMCKL_FAILURE; rc = QMCKL_FAILURE;
} }
#+END_SRC #+END_SRC
** =qmckl_context_copy= ** =qmckl_context_copy=
This function makes a shallow copy of the current context. This function makes a shallow copy of the current context.
- Copying the 0-valued context returns 0 - Copying the 0-valued context returns 0
- On success, returns a pointer to the new context using the =qmckl_context= type - 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* old_context;
qmckl_context_struct* new_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; return (qmckl_context) 0;
} }
@ -145,14 +171,16 @@ qmckl_context qmckl_context_copy(const qmckl_context context) {
return (qmckl_context) 0; return (qmckl_context) 0;
} }
old_context = (qmckl_context_struct*) context; old_context = (qmckl_context_struct*) checked_context;
new_context->prev = old_context; new_context->prev = old_context;
new_context->precision = old_context->precision; new_context->precision = old_context->precision;
new_context->range = old_context->range; new_context->range = old_context->range;
new_context->tag = VALID_TAG;
return (qmckl_context) new_context; return (qmckl_context) new_context;
} }
#+END_SRC #+END_SRC
*** Test *** Test
@ -166,10 +194,11 @@ qmckl_context qmckl_context_copy(const qmckl_context context) {
fprintf(stderr,"qmckl_context_copy: Same pointer\n"); fprintf(stderr,"qmckl_context_copy: Same pointer\n");
rc = QMCKL_FAILURE; 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"); fprintf(stderr,"qmckl_context_copy: No access to data\n");
rc = QMCKL_FAILURE; rc = QMCKL_FAILURE;
} }
#+END_SRC #+END_SRC
** =qmckl_context_previous= ** =qmckl_context_previous=
@ -188,33 +217,35 @@ qmckl_context qmckl_context_previous(const qmckl_context context);
#+BEGIN_SRC C :tangle qmckl_context.c #+BEGIN_SRC C :tangle qmckl_context.c
qmckl_context qmckl_context_previous(const qmckl_context context) { qmckl_context qmckl_context_previous(const qmckl_context context) {
qmckl_context checked_context;
qmckl_context_struct* ctx; 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; return (qmckl_context) 0;
} }
ctx = (qmckl_context_struct*) context; ctx = (qmckl_context_struct*) checked_context;
return (qmckl_context) ctx->prev; return qmckl_context_check((qmckl_context) ctx->prev);
} }
#+END_SRC #+END_SRC
*** Test *** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c #+BEGIN_SRC C :tangle test_qmckl_context.c
if (qmckl_context_previous(new_context) == (qmckl_context) 0) { 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; rc = QMCKL_FAILURE;
} }
if (qmckl_context_previous(new_context) != context) { 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; rc = QMCKL_FAILURE;
} }
if (qmckl_context_previous(context) != (qmckl_context) 0) { 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; rc = QMCKL_FAILURE;
} }
if (qmckl_context_previous((qmckl_context) 0) != (qmckl_context) 0) { 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; rc = QMCKL_FAILURE;
} }
#+END_SRC #+END_SRC
@ -224,45 +255,52 @@ qmckl_context qmckl_context_previous(const qmckl_context context) {
Destroys the current context, leaving the ancestors untouched. Destroys the current context, leaving the ancestors untouched.
- Succeeds if the current context is properly destroyed - Succeeds if the current context is properly destroyed
- Fails otherwise - Fails otherwise
- Fails is the 0-valued context is given in argument - Fails if the 0-valued context is given in argument
- Fails if the the pointer is not a valid context
The context given in parameter is overwritten by the 0-valued
context, so a pointer is passed to the function.
*** Header *** Header
#+BEGIN_SRC C :tangle qmckl_context.h #+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 #+END_SRC
*** Source *** Source
#+BEGIN_SRC C :tangle qmckl_context.c #+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_struct* ctx;
qmckl_context checked_context;
checked_context = qmckl_context_check(context);
if (checked_context == (qmckl_context) 0) return QMCKL_FAILURE;
ctx = (qmckl_context_struct*) *context; ctx = (qmckl_context_struct*) context;
if (ctx == NULL) return QMCKL_FAILURE;
if (ctx == NULL) {
return QMCKL_FAILURE;
}
ctx->tag = INVALID_TAG;
free(ctx); free(ctx);
*context = (qmckl_context) 0;
return QMCKL_SUCCESS; return QMCKL_SUCCESS;
} }
#+END_SRC #+END_SRC
*** Test *** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c #+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) { if (new_context == (qmckl_context) 0) {
fprintf(stderr,"qmckl_context_destroy: new_context is NULL\n"); fprintf(stderr,"qmckl_context_destroy: new_context is NULL\n");
rc = QMCKL_FAILURE; 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"); fprintf(stderr,"qmckl_context_destroy: Unable to destroy the new_context\n");
rc = QMCKL_FAILURE; 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"); fprintf(stderr,"qmckl_context_destroy: new_context should be NULL\n");
rc = QMCKL_FAILURE; rc = QMCKL_FAILURE;
} }
@ -272,7 +310,7 @@ qmckl_exit_code qmckl_context_destroy(qmckl_context *context) {
} }
#+END_SRC #+END_SRC
* Precision * Precision
The following functions set and get the expected required precision The following functions set and get the expected required precision