Skip to content

Disallow array_ptrs to function types #34

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

Closed
dtarditi opened this issue Jul 19, 2016 · 1 comment
Closed

Disallow array_ptrs to function types #34

dtarditi opened this issue Jul 19, 2016 · 1 comment

Comments

@dtarditi
Copy link
Member

Function types have no size associated with them. For this reason, it does not make sense to have array_ptrs to function types. Pointer arithmetic is not meaningful for these kinds of array_ptrs, which implies that we can't define bounds checks for these kinds of pointers.

dtarditi added a commit that referenced this issue Oct 10, 2017
#202)

This change adds tests for parsing and typechecking the new Checked C null-terminated array and pointer types.  This matches a corresponding Checked C clang compiler pull request (checkedc/checkedc-clang#394).  The changes are integrated into existing test cases for checked arrays and array_ptrs.  

The tests for parsing are straightforward.  The new keywords `nt_checked` and `nt_array_ptr` can be used in place of the `checked` and `array_ptr` keywords.  For type checking, we add tests for building the new types. We check that null-terminated arrays and pointers can only be built from integer or pointer types (the assumption is that 0 is the null-terminator value, so only types for which 0 is a valid value can be used).

We also add tests that cover implicit conversions at assignments, function calls, and conditional expressions.  Nt_array_ptrs can be converted to array_ptrs and ptrs, but not the reverse.  The problem is that array_ptrs or ptrs may not point to null-terminated data, or, if they do, there may be an alias that permits the null-terminator to be overwritten.  We also add tests that cover uses of operators with the new types.

The tests include positive cases (where no error is expected) and many more negative cases, where the compiler is expected to issue an error. To avoid unnecessary source code changes that would obscure the new tests, I avoided renumbering temporary variables. I added letter suffixes to existing variables instead.

The compiler change disallows array_ptrs to function types (#34), so we add tests of that too.  Functions have indeterminate size, so bounds checking does not make sense for them.  We allow array_ptrs to ptrs to function types.
dtarditi added a commit to checkedc/checkedc-clang that referenced this issue Oct 10, 2017
This change adds parsing and type checking for two new kinds of Checked C types: null-terminated arrays and pointers to null-terminated arrays.  Null-terminated arrays are written using the `nt_checked` keyword in place of the `checked` keyword.  An example declaration is `int arr nt_checked[10];`.   Pointers to null-terminated arrays are constructed using the  `nt_array_ptr` keyword instead of the `array_ptr` keyword (the backward-compatible names for the keywords are `_Nt_checked` and `_Nt_array_ptr`).

To represent nt_array_ptrs in the IR, the existing enumeration for the different kinds of pointers is extended.  For nt_checked arrays, the boolean indicating whether or not an array is checked is changed to an enumeration.  The parsing changes are straightforward.  The new keywords are recognized at the points where the existing Checked C keywords are recognized.  They are then mapped to the appropriate enumeration tag.

For type checking,  the profile methods for type object memorization/construction are changed to take into account the enumeration changes.    We also add checks that null-terminated arrays and pointers are only  constructed from integer or pointer types (the assumption for now is that the integer 0 will be the null terminator, so only data for which 0 is a valid value can be null-terminated).  We do not allow nt_array_ptrs of void (the problem is that conversions through void could allow the null terminator to be partially overwritten when types larger than a character are involved).

With these rules we can construct interesting data structures, such as arrays of null-terminated pointers (i.e. arrays of strings), arrays of null-terminated pointers to null-terminated pointers (and so on), and arrays of null-terminated arrays (arrays of pre-allocated strings of fixed sizes).

Most of the typechecking changes are extending the implicit conversion logic in SemaExpr.cpp to implement the implicit conversion rules for nt_array_ptr.  An nt_array_ptr can be converted implicitly to an array_ptr or ptr (bounds checking and checking of bounds declarations will prevent the null terminator from being overwritten).  However, implicit conversions in the other direction are not allowed. An unchecked pointer, array_ptr, or ptr cannot be converted implicitly to an array_ptr.  The data in memory may not be null-terminated or, if it is, there may be an alias that allows the terminator to be overwritten.

For conditional expressions (`e1 ? e2 : e3`), the implicit conversion rules are a bit more complex.  If the type of one arm of the conditional expression is an nt_array_ptr and the type of the other arm is an unchecked pointer or array_ptr, the resulting type is an array_ptr. Bounds checking will prevent the null terminator from being overwritten.

For pointers to arrays, we allow an unchecked array to be converted to a checked array, but not vice versa.  We do not allow an unchecked array to be converted to an nt_array.

This change contains code for one additional issue: we now disallow array_ptrs of function types (checkedc/checkedc#34).  This is because functions are indeterminate in size, so no bounds checking is possible.  We allow array_ptrs of ptrs to function types.

Testing:
- Extended the existing Checked C typechecking tests to cover nt_array_ptrs and checked arrays. Most of this work for this change went into extending those tests. These tests are pretty comprehensive and cover many situations where types are checked.   This will we be covered by a separate pull request for the Checked C repo.
- Passes existing automated testing for Linux and Windows, including the LNT test suite and LNT tests that have been converted to Checked C.
dtarditi added a commit that referenced this issue Oct 10, 2017
Update the specification to disallow array_ptrs of function types. Bounds checking pointers to function types does not make sense because functions do not have sizes in C.  This addiresses issue #34.

Also correct the capitalization of the _Nt_array_ptr keyword in the specification.
@dtarditi
Copy link
Member Author

The specification has been updated. Compiler support has been added for this check too.

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

No branches or pull requests

1 participant