checkedc icon indicating copy to clipboard operation
checkedc copied to clipboard

type of calloc in stdlib_checked.h

Open mwhicks1 opened this issue 4 years ago • 4 comments

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.

mwhicks1 avatar Aug 10 '20 16:08 mwhicks1

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 avatar Aug 10 '20 17:08 mgrang

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.

mgrang avatar Aug 13 '20 19:08 mgrang

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

mwhicks1 avatar Aug 13 '20 20:08 mwhicks1

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));

dpostol avatar Jul 06 '21 15:07 dpostol