Skip to content

String literals with checked types and improved support for array literals. #396

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

Merged
merged 5 commits into from
Oct 17, 2017

Conversation

dtarditi
Copy link
Member

This adds compiler support for using string literals in checked scopes. In C, a string literal has the type "array of character", where there are several possible character types. In Checked C, that corresponds to an "unchecked array of character". To be able to use string in checked scopes, we need a way that they can be typed as a "checked null-terminated array of characters."

We support this in two ways. First we alter the type of string literals that appears in checked scopes to have null-terminated array types. Array-to-pointer conversion converts this to having an nt_array_ptr test, and at assignments nt_array_ptr can converted array_ptr..

Second, we allow array literals (of which strings are a special case) to be converted implicitly to a checked pointer type when a checked pointer type is expected. The checked pointer type should have the same pointer kind as the expected pointer type. The implicit conversions can happen at assignments, function calls, and within initializers. The language rules haven't been added to the Checked C specification yet. The proposed rule is describedhere.

Array literals specified using initializers or compound literal expressions already worked for the most part. The C language rules use the type of the variable being initialized or the type of the compound literal expression as guides for filling in the type. The clang machinery for filling in arrays worked for checked arrays too.

This commit adds one important missing case: incomplete array types. We were not propagating the checked enum when the complete array type was formed after the number of array elements had been determined. It also checks in a checked scope that the compound literal type is a checked type. This closes off one more route by which an unchecked type could appear in a checked scope.

This commit adds a new method for checking types that appear syntactically in expressions in checked scopes (for example, in cast operators and compound literal expressions). This produces error message with similar detail to those produced for declarations, calling out the problematic unchecked type within a constructed type if necessary. The existing error message for cast operations are switched to use this method, so we get better error message for cast expressions too.

Testing:

  • Added new tests in the Checked C repo in initializers.c that cover strings, array initializers, and pointers initialized via strings or compound literal expressions with array type.
  • Passes existing automated testing for Linux and Windows. I had to modify several LNT benchmarks because the improved typing discovered that we were passing strings to methods with bounds-safe interfaces.

- Make string literals have checked array type in checked scopes.
- If an array literal occurs as the RHS of an expression and the
  LHS is checked pointer type, change array-to-pointer decay to
  produce a checked pointer.
- Incomplete checked array types with initializers should produce
  checked types.  The array kind was not being passed in when constructing
  the complete type.  The argument default to unchecked array kind.

Testing:
- Added new Checked C repo tests for array literals.
In checked scopes, only allow checked types to be used for compound
literals.

Allow parenthesized string literals to appear in ocntext where a
a checked type are expected.
… scopes.

We recently improved the diagnostics for declarations in checked scopes that
use types that are not allowed.  This improves the diagnostics for the types
used by casts and array literals.  We centralize the checking of types
used in checked scopes.
QualType StrTy = Context.getConstantArrayType(CharTyConst,
llvm::APInt(32, Literal.GetNumStringChars()+1),
ArrayType::Normal, 0);
llvm::APInt(32, Literal.GetNumStringChars() + 1),
Copy link
Collaborator

@lenary lenary Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this constant 32 correct? Surely it should be the same as the width of size_t which you can get from… somewhere?

Edit: I'm wrong, looking on the left and they also use 32. I think this is fine.

Copy link
Collaborator

@lenary lenary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes look good to me. Thanks!

Copy link
Collaborator

@awruef awruef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

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

Successfully merging this pull request may close these issues.

3 participants