This adds a CMake file for copying the Checked C headers into the
clang system header directory as part of the clang build. This avoids
people having to copy the Checked C header files to their specific project,
which would be error prone and result in synchronization problems. This
change also fixes an issue with strncmp on Linux by undefining a problematic
macro.
It is a little clunky to store all of these header files in the clang system
header directory because it includes wrapper files that are not needed
by the compiler. This seems to be better and simpler than the
alternatives, so we're using it.
This updates all the samples in the Checked C repo to no longer
use the full relative path the stdchecked.h. We can just rely on
it being picked up as part of the system search path.
This change has matching changes for the Checked C LLVM repo, the
Checked C clang repo, and the Checked C LLVM Test Suite Repo.
Testing:
- Passed automation testing for Linux x64 LNT testing and Windows
x86 when the testing was pointed at the matching branches in all
the repos.
* Cast to checked array pointers in bounds declarations, not unchecked pointers
* Port Changes from LLVM Test Suite
These changes mostly include adding `_Unchecked` to declarations and adding `#pragma BOUNDS_CHECKED ON` around the header contents.
This improves the parallelism of running the Checked C regression tests. The tests for bounds checking of member expressions were doing 8 different compiles: 4 for the dot operator and 4 for the arrow operators. This change creates separate test automation driver files for the arrow operators.
The elapsed time for a test run on my 12 core Windows machine drops from 68 seconds to 45 seconds. The original time before new tests were added was 30 seconds. From back-of-the-envelope calculations, we would expect about a 50-60% increase in testing time with the additional tests. This changes brings testing time into that range.
Testing:
- Passed automation testing on Linux
- Build and tested locally on Windows.
The prior commit failed automated testing on Linux because there were backward slashes in clang test automation commands that needed to be forward slashes, causing files to not be found. This commit fixes that.
Testing:
- Passed automation testing on Linux.
This adds tests of pointer dereference (`*`) and array-subscript operators (`[]`) applied to member reference expressions with pointer type. This addresses issue #154. For example:
struct S v ...
struct S *pv ...
*(v.f)
*(pv->f)
v.f[5]
pv->f[5]
The number of test files started to get out-of-hand, so I merged all the existing bounds checking tests (which had 4 different variants) into single files. I used pre-processing to cut back on the redundancy. Now we defined a macro to get a specific variant. The README.md file is updated to describe this new organization.
Testing:
Revised Checked C tests pass on x86 Windows.
Add tests for _bounds cast expressions with bounds specified by bounds expressions. For example:
array_ptr<int> x : count(10) = _Dynamic_bounds_cast<array_ptr<int>>(x, count(10));
array_ptr<int> x : count(10) = _Dynamic_bounds_cast<array_ptr<int>>(x, bounds(a, b));
Add test code for the type checking requirement that the first expression in a bounds cast operation has a pointer type or an integral type.
Test the following situations that are not allowed in checked scopes:
- Bound casts to unchecked type.
- _Assume_bounds_cast operations
- Variable argument function types.
Add tests of type checking for the _Assume_bounds_cast and _Dynamic_bound_cast operators. Also add tests of static checking of bounds for the _Dynamic_bounds_cast operator: the subexpression must have bounds. The tests are added in the directories for testing that functionality of the compiler.
The address-of (&) operator produces a checked array_ptr<T> type in a checked scope. However, array_ptr<FunctionType> is not the correct type to produce when the address-of operator is applied to a function type. It should produce a ptr type for a checked function pointer, not an array_ptr.
The span type seems like a type that is better suited for a library than a core
language extension. In C++, which has templates, there is already a proposal
for adding a span-like type to the C++ Standard Library. Remove the span
type for the language extension design and move it to the design alternatives
section.
To be clear, we are postponing adding the span type to the language extension
design (and the clang implementation as well). We may decide to add it in
the future, especially because implicit conversions involving library types
and pointers can be messy. However, for now, it can wait until the need
becomes clearer.
* Add test code for dynamic and assume bounds cast (#204)
* Add More test code for Pointer Bounds Cast (#204)
* Add More test code for Pointer Bounds Cast (#204)
* + Add test code for variable argument function call in checked block (#251)
+ Variable argument function call is not allowed in checked blocks
+ variadic function call & printf function call is checked
+ Add test code for BOUNDS_CHECKED pragma (#247)
+ For elaborate test BOUNDS_CHECKED pragma with a scope, add test cases
+ For elaborate scope handling, implementation is changed to use annotation token
By using annotation token, it can recognize scope corresponding to annotation token
+ Restore on-off-switch syntax in pragma BOUNDS_CHECKED
+ #pragma BOUNDS_CHECKED [on-off-switch]
+ on-off-switch = ON/OFF/DEFAULT
* + Add test code for variable arguments issue(check-clang#251) & constructed type in checked scope (checkedc/#142)
+ add expected-error for incorrect constructed type in checked scope
+ add test cases for variable arguments type handling
+ variable arguments function definitino
+ variable arguments function use
+ variable arguments function pointer type
* + Add test code for variable arguments issue(check-clang#251)
+ test code for checking variable arguments C-style cast is added
+ modified expected error message due to check-clang modification
* + Test code clean-up for checked scope(#189) & BOUNDS_CHECKED pragma (checkedc-clang/#247, checkedc/#135) & variable arguments type (checkedc-clang/#251)
+ test code is updated to simplify & fortify test cases
+ code clean-up for checked_scope.c
+ remove useless codes
+ modify test cases for type restrictions on expression
+ modify test cases to check if expression has an use with unchecked type
+ modify test cases to check if there is a C-style type casts to unchecked/variadic type
+ add test code for BOUNDS_CHECKED pragma
+ modify BOUNDS_CHECKED pragma test code within struct/union body
+ code clean-up for variable arguments checking
+ remove useless codes
* + simpify code by removing useless/redundant code
* + simplify and extend test code in checked_scope_pragma.c (#135)
+ it works well with corresponding latest checkedc-clang implementation
+ simplify test code for BOUNDS_CHECKED pragma
+ #pragma BOUNDS_CHECKED on
+ In checked scope of compilation unit
Test unchecked function specifier
By default, all functions are checked function
By default, all global variables are checked type
By default, all structures are checked type
Function parameter & return values SHOULD be checked type in checked scope of compilation unit
Also, local variables, global variables, structure members SHOULD be checked type
+ modify specification related to BOUNDS_CHECKED pragma value
+ BOUNDS_CHECKED on-off-switch value can be [on|off]
+ default value is off
* + Extend test code for BOUNDS_CHECKED pragma (#135)
+ add test code for scope-specific BOUNDS_CHECKED pragma
It changes checked property of scope which is not only top-level scope but also normal scope
If BOUNDS_CHECKED pragma is set, it modifies checked property of a scope in which '#pragma BOUNDS_CHECKED' is set
It works as if it is checked/unchecked scope
+ Tested for a local variable within a function scope
+ Tested for a global variable within a cmopilation unit scope
* + Add test code for unchecked scope (#203)
+ unchecked scope keyword clears checked function specifier
+ check unchecked compound statement with checked function specifier
+ unchecked scope clears checked property & prevents inheritance of checked property
+ check unchecked block with nested checked block (compound statement, structure)
* + apply review's feedback for unchecked scope test code
+ code clean-up including changing comments and addition of periods at the end of sentence
+ change return the address of local variable
+ add parameters with an unchecked type in checked function specifier for some test cases
+ TODO
+ unchecked function specifier is not yet implemented
after it is implemented, I will add test code, too
* + add test code for unchecked scope (#203, #246)
+ unchecked function specifier test code is added
+ structure member variable interop-type test code is added
+ add test code for BOUNDS_CHECKED pragma (#247)
+ #pragma BOUNDS_CHECKED on is added
+ checked top-level scope of translation unit is introduced
+ checked function specifier is not used since top-level scope is checked. all functions are checked function
+ globally-scoped variable SHOULD be checked pointer since top-level scope is checked
* + Add test code for change of the result type of the address-of operator in checked scopes. (#201)
* + Test code modified for checkedc modification (#201, #202, #189).
- Checkedc implicit cast rule changed:
- pointer_types.c, checked_arrays.c modified
- Incompatible type expected error is modified to apply modified implicit cast rule between checked pointer types.
- Implicit cast rule between checked pointer types is added and implicit casts between checked pointer types (ptr<T>) and checked array pointer types (array_ptr<T>) are allowed..
- Previous incompatible type error is removed (expected-error {{incompatible type}} -> expected-correct {{incompatible type}})
- While implementing checked scope work-item (#201, #202, #189), related checked_scope test code is modified.
- checked_scope.c file is modified.
- Ensure no uses of unchecked pointer/array types in checked blocks.
- Ensure no use of unchecked pointer type casting in checked blocks.
- Changed type produced by address-of operator in checked block.
* + Copy and modify checked array test code to test various operation & function call.
- To extend test cases for checked scopes, I have added various kinds of tests in checked arrays.
In checked arrays, it has various kinds of operations such as arithmetic, logical and compare
I believe that extended test cases enhance reliability of current checked scope implementation.
- Checked scope errors precede other type checking error or warnings in checked array test code
Therefore, expected errors in checked array test case is overridden by checked scope errors.
In other words, checked scope error almost overrides other errors or warnings in checked array test,
* Apply reviewer's feedback.
- Femoved unnecessary expected-<kind> comments
- If declaration is invalid, DO NOT emit error message for use of declaration.
- Adjust related expected-error comments
- Tests using modified compiler passed.
Before this change, it was required that programmers were careful with the order in which they included headers - in particular, the inclusion of `<stdchecked.h>` must come after the final inclusion of `<stdlib_checked.h>` or the final inclusion of `<stdio_checked.h>`, whichever came later.
This is a problem if you want to be able to use the `ptr<T>` in a header file rather than `_Ptr<T>`, especially as this almost definitely brings the include of `<stdchecked.h>` earlier.
The solution is to rename these parameters. As these are declarations, all that matters is the types are compatible, the names are effectively erased (even if we use them in a `count(e)` or `bounds(e1, e2)` expression, these are canonicalised to argument position rather than name.
* + Add test code for checked scope implementation (#189)
- simple version of checked scope parsing & type checking
- checked function
- checked keyword is before function definition and it is used as function specifier
- in checked function, it checks if function declaration(return & parameter) is checked scope
- in checked function, it checks if function definition(function statement boyd) is checked scope
- in checked function, function with no prototype is not allowed
- checked scope
- checked keyword is before l_brace and corresponding compound statments are affected by checked scope
- in checked scope, checked pointer or unchecked pointer with bounds-safe interface is only allowed
- in checked scope, child scope inherits parent checked property
* + simple checked scope/function test code
- add checked scope for structure/union
- checked scope structure member variable checking
- nested structure definition
- adjust error message
- function without a prototype cannot be used in a checked scope
* + extend simple test code for checked scope
- add checked scope parsing error case
- checked scope expects l_brace
- for error case (checked '[', checked '('), it works well
- reword expected-error for declaration type restriction
* + reword unchecked array/pointer type error message for parameter
Remove error-check in rel_align.c to go along with "Avoiding generating error message 'expected bounds expression' when there is a typechecking error [ checkedc-clang issue 195 ]"
This adds high-level tests of compound assignment and increment operators to our codebase.
Given these tests are all very similar, we saw fit to document the structure of the tests in this directory for future maintainers/testers.
* Adds Compound Assignment Tests
* Adds Increment Tests
* Documentation
* Corrects failing tests to avoid non-null check
* Add relative Bounds Clause parsing test cases (#037).
- include rel_align test cases.
- include rel_align_value test cases.
- relative bounds clause test after declaration bounds.
- relative bounds clause test in member bounds.
- relative bounds clause test after range boundse expression in
function parameter.
- relative bounds clause test in return bounds expression.
* Change Checking error message after pasing relative bounds clause
This commit slightly reorganises the dynamic_checking directory, and duplicates the deref tests to make them test using a checked array/array_ptr on the left side of an assignment operator.
This way processes exit gracefully, instead of relying on the OS to handle
a crash. On Windows, crashes cause Windows Error Reporting (WER) to fire up,
invoking system logging.
We have been using the not program from the LLVM test harness with the --crash
option to determine when processes have exited with a crash. We have found
that this approach is not working reliably on Windows. The not program spawns
a child process and looks at the process exit code, looking for negative exit
codes to indicate a crash. When running automated testing under Visual Studio
Team Services, sometimes the exit code is a positive number.
Testing:
- Changed tests run successfully for x86 Windows x64 Linux.
On Mac, there is no declaration for some standard library functionality, instead they are translated (using macros) into calls to these checked functions, which have specific compiler support.
They helpfully define some macros (`__APPLE__`, `_FORTIFY_SOURCE` and one or two others) which let us know when they're doing this. If they are, we don't define our checked interface version. Instead, we provide checked interfaces for the builtin functions that they are translated to.
We are adding a check to the compiler that the source expressions of casts
to ptr types have bounds. This uncovered a number of tests where the
source expressions do not have bounds. Usually, the problem was a cast
from a variable with unchecked pointer type to T to ptr<T>. The fix is to
use an expression that has known bounds instead, such as an expression
that takes the address of a variable with type T instead.
Makes sure we're always using `long` or `long long` when casting between pointers in platform-specific tests, as we can't be sure of the size of `int`.
The compiler now checks that assignments through array_ptrs and
reads through array_ptrs use array_ptrs that have bounds. These checks found
some tests where bounds declarations are missing for array_ptr variables.
These are the tests to go along with Microsoft/checkedc-clang#129
I've had to comment out the checked version of wctomb because the bounds use a macro that expand into a call.
This updates some of the tests for Microsoft/checkedc-clang#128 to make sure we get some warnings on super-simple dynamic checks that will fail.
We probably want to be careful to only use the `-verify` flag in a few tests, so the tests are not too coupled to clang's constant folder/default optimization level/the accuracy of our implemented static analysis. I think it's fine in these tests, but probably no others.
This adds the `dynamic_check` macro for `_Dynamic_check`, and some initial tests for its functionality
These initial tests make sure that successful programs don't exit with a failure on a dynamic check failure, and that dynamic checks that fail cause an exit with an error. Unfortunately, the execution of `llvm.trap()` counts as a crash for the "not" tool, which could make these tests more brittle. But they at least pass without having to add a SEH or similar.
This change matches a corresponding change in the Checked C
clang repo. The compiler will be checking that automatic variables with
_Ptr types or bounds declarations are always initialized using an
initializer.
This adds missing initializers to existing tests. It also adds tests that
the compiler produces errors for uninitialized automatic variables.
Note that static variables are always initialized to 0, if they do not
have an initializer. This means that we do not have to check that they
are initialized. 0 is valid for any bounds declaration, so it works well as
a default initialization value.
The C Standard is purposefully vague on the subject of the size of pointers, and their comparison to the size of various integral types.
Here, we split the tests that contain integer <-> pointer casts into two groups. In the first group (the vast majority of platforms), `void*` is the same size as `long`, so we do all our casts to `long`s. In the second group (notably including Win64), `void*` is not the same size as `long`, but it is the same size as `long long`, so we do all our casts to that.
The only place this approach doesn't work is with Enums, which have an implementation-defined size (according to my reading of the spec), so I've commented out the pointer->enum casts.
Fixes#92
This addresses issue #93. In the tests of bounds-safe interfaces for `wcstoimax` and `wcstoumax`, we are only including `<inttypes.h>`. We are not including `<stddef.h>`. This results in a test failure on a Linux x64 Ubuntu box because `wchar_t` is missing. The fix is to add the missing include.
Testing:
- Test now passes on Linux Ubuntu x64.
- Test continues to pass on Windows x86.