Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

type of calloc in stdlib_checked.h #413

Open
mwhicks1 opened this issue Aug 10, 2020 · 4 comments
Open

type of calloc in stdlib_checked.h #413

mwhicks1 opened this issue Aug 10, 2020 · 4 comments
Assignees

Comments

@mwhicks1
Copy link
Collaborator

In stdlib_checked.h the function calloc is defined thus:

extern _Itype_for_any(T) void *calloc(size_t nmemb, size_t size) : itype(_Array_ptr<T>) byte_count(nmemb * size);

but this type fails to recognize that since the returned memory is zeroed out, we can treat the buffer as an _Nt_array_ptr instead. Would the following type be acceptable?

extern _Itype_for_any(T) void *calloc(size_t nmemb, size_t size) : itype(_Nt_array_ptr<T>) byte_count((nmemb-1) * size);

I tried to use this type and the compiler rejected it, saying

x.c:5:74: error: 'type name' declared as _Nt_array_ptr of type 'T' (aka
      '(0, 0) __BoundsInterface'); only integer and pointer types are allowed
  ...void *calloc(size_t nmemb, size_t size) : itype(_Nt_array_ptr<T>) byte_c...

Another problem I can see is that a normal array pointer would be allocated as an NT array pointer first, which could then be cast to the normal one. But doing so would cause the length to drop by one. I.e., a _Nt_array_ptr<char> : count(3) actually represents a buffer of size 4, but you can only cast it to _Array_ptr<char> : count(3) so that the alias cannot be used to destroy the 0 terminator.

@mgrang
Copy link

mgrang commented Aug 10, 2020

Here, the type of T is:

TypedefType 0xb1b80a0 'T' sugar
|-Typedef 0xb1b7f10 'T'
`-TypeVariableType 0xb1b7ed0 '(0, 0) __BoundsInterface'

And we hit the following condition in SemaType.cpp:
// In Checked C, null-terminated array_ptr of non-integer/non-pointer are not allowed.

On relaxing this condition for _Itype_for_any, I could compile calloc with _Nt_array_ptr without errors. However, I could not find any documentation for the intended behavior of _Nt_array_ptrs when used with _Itype_for_any.

@dtarditi Could you please comment on what the intended behavior should be in this case?

@mgrang mgrang self-assigned this Aug 10, 2020
@mgrang
Copy link

mgrang commented Aug 13, 2020

Mike, If we re-write calloc with an nt_array_ptr then as you said that for normal arrays we would no longer be able to overwrite the null terminator. This would be a problem for array_ptrs. @dtarditi is of the opinion that we should create a wrapper for calloc (with a different name) and use it for nt_array_ptrs.

@mwhicks1
Copy link
Collaborator Author

I can't think of a better solution. What will you call it? nt_calloc maybe?

@dpostol
Copy link

dpostol commented Jul 6, 2021

Has this been implemented? Right now I am trying to allocate memory for an nt_array of variable length. There doesn't seem to be a way to do that right now.
Something like,
int x = 4;
nt_array_ptr p = calloc(x, sizeof(int));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants