Skip to content

Commit

Permalink
fixes and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
thradams committed May 16, 2024
1 parent 57a2237 commit 34a942a
Show file tree
Hide file tree
Showing 26 changed files with 84,910 additions and 83,867 deletions.
30 changes: 15 additions & 15 deletions ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,12 @@ For instance, Berkeley sockets use an integer to identify the socket.
Sample
```c
owner int server_socket = socket(AF_INET, SOCK_STREAM, 0);
_Owner int server_socket = socket(AF_INET, SOCK_STREAM, 0);
/*...*/
close(server_socket);
```

> Note: The location and usage of the qualifier owner is similar to
> Note: The location and usage of the qualifier \_Owner is similar to
the const qualifier. For pointers, it goes after *, and for this socket sample,
it can be before int. The owner qualifier belongs to the object (memory)
that holds the reference.
Expand Down Expand Up @@ -563,7 +563,7 @@ However in C, structs are typically passed by pointer rather than by value. To t
A pointer qualified with **\_Obj\_owner** is the owner of the pointed object but not responsible for managing its memory.
The next sample illustrates how to implement a destructor using a _Obj_owner pointer parameter.
The next sample illustrates how to implement a destructor using a \_Obj\_owner pointer parameter.
**Sample - Implementing a destructor using \_Obj\_owner**
Expand All @@ -576,7 +576,7 @@ struct X {
char * _Owner _Opt text;
};
void x_destroy(_Opt _struct X * _Obj_owner x) {
void x_destroy(_Opt struct X * _Obj_owner x) {
free(x->text);
/*x is not the owner of the memory*/
}
Expand Down Expand Up @@ -640,10 +640,10 @@ void x_delete(_Opt struct X * _Owner _Opt p) {
}
int main() {
struct X * _Owner pX = calloc(1, sizeof * pX);
struct X * _Opt _Owner pX = calloc(1, sizeof * pX);
if (pX) {
/*...*/;
x_delete( pX);
x_delete(pX);
}
}
Expand Down Expand Up @@ -823,9 +823,9 @@ without causing a memory leak.
**Rule:** All objects passed as arguments must be initialized and all objects reachable must be initialized.

**Rule:** By default, the parameters of a function are considered initialized. The exception is created with out qualifier.
**Rule:** By default, the parameters of a function are considered initialized. The exception is created with \_Out qualifier.

**Rule:** We cannot pass initialized objects, or reachable initialized objects to **out** qualified object.
**Rule:** We cannot pass initialized objects, or reachable initialized objects to **\_Out** qualified object.

For instance, at set implementation we need free text before assignment.

Expand Down Expand Up @@ -872,7 +872,7 @@ TODO void objects.
#include <stdlib.h>
struct X {
char * owner name;
char * _Owner _Opt_ name;
};
void x_destroy(struct X * _Obj_owner p) {
Expand Down Expand Up @@ -992,11 +992,6 @@ int main()
<button onclick="Try(this)">try</button>


**Rule:** Pointer parameters are consider not-null by default. The exception is created using the qualifier **_Opt**.

The **_Opt**. qualifier is used to tell the caller that the pointer can be at null state and tells the implementation that it is necessary to check the pointer for null before usage.


#### Zero and Not-Zero state

The **zero** state is used for non-pointer objects to complement and support uninitialized checks.
Expand All @@ -1019,6 +1014,11 @@ This difference is necessary because, for non-pointers like the socket sample,
0 does not necessarily means null.
The compiler does not know the semantics for types that are not pointers.

#### lifetime-ended state

This is the state when variables leave the scope or when objects are moved.


#### static_set

We can use **static_set** to override states.
Expand Down Expand Up @@ -1057,7 +1057,7 @@ int main() {
Now let's consider `realloc` function.

```c
void * _Owner realloc( void * _Opt ptr, size_t new_size );
void * _Owner _Opt _realloc( void * _Opt ptr, size_t new_size );
```
In the declaration of `realloc`, we are not moving the ptr. The reason for that is because the `ptr` may or may not be moved. If the function returns NULL, `ptr` was not moved.
Expand Down
8 changes: 6 additions & 2 deletions src/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,15 @@ int main()
#define NC " -nullable=disable "
#endif

//if (mysytem("cake ../tests/unit-tests/*.c -fanalyzer -test-mode") != 0)
// exit(1);

if (mysytem("cake.exe " NC " -ownership=enable -Wstyle -fanalyzer -Wno-unused-parameter -Wno-unused-variable -sarif " HEADER_FILES SOURCE_FILES) != 0)
exit(1);

if (mysytem("cake ../tests/unit-tests/*.c -fanalyzer -test-mode") != 0)
exit(1);
printf("\n");
printf("To run unit test use:\n");
printf("cake ../tests/unit-tests/*.c -test-mode\n");


#endif
Expand Down
2 changes: 1 addition & 1 deletion src/expressions.c
Original file line number Diff line number Diff line change
Expand Up @@ -3855,7 +3855,7 @@ void argument_expression_list_push(struct argument_expression_list* list, struct
}
else
{
assert(list->tail->next == NULL);
assert(list->tail->next == NULL);
list->tail->next = pitem;
}
list->tail = pitem;
Expand Down
30 changes: 23 additions & 7 deletions src/file.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
#pragma safety enable

int strcmp(const char* s1, const char* s2);
char* _Opt f();

int main()
struct X
{
const char* _Opt s = f();
if (s && strcmp(s, "a") == 0)
char* _Owner _Opt text;
};

void free(void* _Owner _Opt p);
void* _Owner _Opt calloc(int n, int sz);


struct X* _Owner make();
char* _Owner _Opt strdup(const char* s);

void f(int condition)
{
struct X* _Owner _Opt p = calloc(1, sizeof * p);
try
{
if (p == nullptr)
throw;


if (condition)
throw;
p->text = strdup("a");
}
else if (s)
catch
{
}
}

Loading

0 comments on commit 34a942a

Please sign in to comment.