Add error messages produced by bounds declaration checking (#237)

We are updating the compiler to do bounds declaration checking for constant-sized ranges (https://github.com/Microsoft/checkedc-clang/pull/414).   This causes new error messages to be produced for a number of tests.  For example, tests for typechecking might pass typechecking (as expected), but then fail bounds declaration checking..  

Update the tests with the expected error messages from clang (most of these errors were expected once enough bounds declaration checking came on-line and were flagged by TODO comments).

As an FYI, there are additional bounds declaration checking tests in the Checked C clang repo.  These contain detailed checks of the expected explanations, and are not placed in the Checked C repo.

The bounds declaration checking detects and gives errors for the bogus C-style casts described in issue #232.
This commit is contained in:
David Tarditi 2017-11-11 05:56:59 -08:00 коммит произвёл GitHub
Родитель f534fb22e8
Коммит 63d7f11474
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 42 добавлений и 40 удалений

Просмотреть файл

@ -14,15 +14,15 @@ extern void f1() {
extern void f2() {
char p[10];
array_ptr<int> a : count(1) = 0;
array_ptr<int> d : count(10) = _Dynamic_bounds_cast<array_ptr<int>>(a, 5);
array_ptr<int> d : count(10) = _Dynamic_bounds_cast<array_ptr<int>>(a, 5); // expected-error {{declared bounds for 'd' are invalid after initialization}}
a = _Assume_bounds_cast<array_ptr<int>) (p, p, p+1); // expected-error {{expected '>'}}
}
extern void f3() {
array_ptr<int> a : count(2) = 0;
array_ptr<ptr<char>> b : count(2) = 0;
array_ptr<char> b : count(2) = 0;
b = _Assume_bounds_cast<array_ptr<ptr<char>>>(a, 2);
b = _Assume_bounds_cast<array_ptr<char>>(a, 2);
}
extern void f4() {
@ -140,9 +140,9 @@ extern void f14(array_ptr<int> arr : count(5)) {
x = _Dynamic_bounds_cast<array_ptr<int>>(p, count(10));
x = _Dynamic_bounds_cast<array_ptr<int>>(p, bounds(p, p + 10));
x = _Dynamic_bounds_cast<array_ptr<int>>(p, bounds(cache1 - 2, cache1 + 3));
x = _Dynamic_bounds_cast<array_ptr<int>>(p, bounds(cache1 - 2, cache1 + 3)); // expected-error {{declared bounds for x are invalid after assignment}}
x = _Dynamic_bounds_cast<array_ptr<int>>(x, bounds(arr, arr + len));
x = _Dynamic_bounds_cast<array_ptr<int>>(x, bounds(arr)); // expected-error {{expected ','}}
x = _Dynamic_bounds_cast<array_ptr<int>>(x, count(3 + 2));
x = _Dynamic_bounds_cast<array_ptr<int>>(x, count(3 + 2));// expected-error {{declared bounds for x are invalid after assignment}}
x = _Dynamic_bounds_cast<array_ptr<int>>(x, count(len));
}

Просмотреть файл

@ -229,7 +229,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
arg2 = &*arg2;
arg2 = &*arg3;
arg3 = &*arg1; // expected-error {{expression has no bounds}}
arg3 = &*arg2; // TODO: issue an error for incorrect bounds;
arg3 = &*arg2; // expected-error {{declared bounds for arg3 are invalid after assignment}}
arg3 = &*arg3;
// variables
@ -241,7 +241,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
g11 = g12;
g12 = g12;
g13 = g12; // TODO: issue an error for incorrect bounds
g13 = g12; // expected-error {{declared bounds for g13 are invalid after assignment}}
g11 = g13;
g12 = g13;
@ -254,7 +254,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
arg1 = g12;
arg2 = g12;
arg3 = g12; // TODO: issue an error for incorrect bounds
arg3 = g12; // expected-error {{declared bounds for arg3 are invalid after assignment}}
arg1 = g13;
arg2 = g13;
@ -268,7 +268,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
g11 = arg2;
g12 = arg2;
g13 = arg3; // TODO: issue an error for incorrect bounds
g13 = arg3;
g11 = arg3;
g12 = arg3;
@ -285,7 +285,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
t1 = arg2;
t2 = arg2;
t3 = arg2; // TODO: issue an error for incorrect bounds.
t3 = arg2; // expected-error {{declared bounds for t3 are invalid after assignment}}
t1 = arg3;
t2 = arg3;
@ -359,7 +359,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
s.f2 = t3;
s.f3 = t1; // expected-error {{expression has no bounds}}
s.f3 = t2; // TODO: issue an error for incorrect bounds.
s.f3 = t2; // expected-error {{declared bounds for s.f3 are invalid after assignment}}
s.f3 = t3;
t1 = s.f1;
@ -371,7 +371,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
t2 = s.f3;
t3 = s.f1; // expected-error {{expression has no bounds}}
t3 = s.f2; // TODO: issue an error for incorrect bounds.
t3 = s.f2; // expected-error {{declared bounds for t3 are invalid after assignment}}
t3 = s.f3;
nt_array_ptr<int> ntp = (int nt_checked[]) { 0, 1, 2, 3, 0 };
@ -381,7 +381,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
*pntp = arg3;
arg1 = *pntp;
arg2 = *pntp;
arg3 = *pntp; // TODO: issue an error for incorrect bounds.
arg3 = *pntp; // expected-error {{declared bounds for arg3 are invalid after assignment}}
}
extern void test_f1(int *p);
@ -446,8 +446,8 @@ extern void check_nullterm_call_args(
test_nullterm_f1(arg2);
test_nullterm_f2(arg2);
test_nullterm_f3(arg2); // TODO: issue an error for incorrect bounds
test_nullterm_f4(arg2, 1); // TODO: issue an error for incorrect bounds
test_nullterm_f3(arg2); // expected-error {{argument does not meet declared bounds for 1st parameter}}
test_nullterm_f4(arg2, 1); // expected-error {{argument does not meet declared bounds for 1st parameter}}
test_nullterm_f1(arg3);
test_nullterm_f2(arg3);
@ -581,7 +581,7 @@ extern void check_nullterm_call_bsi(int *arg1 : itype(nt_array_ptr<int>),
arg3 = *arg7;
arg3 = *arg8;
arg4 = *arg7; // TODO: issue an error for incorrect bounds.
arg4 = *arg7; // expected-error {{declared bounds for arg4 are invalid after assignment}}
}
}

Просмотреть файл

@ -1,7 +1,7 @@
// Feature tests of static checking of Pointer Bounds Cast
// The following lines are for the LLVM test harness:
//
// RUN: %clang_cc1 -verify -fcheckedc-extension %s
// RUN: %clang_cc1 -verify -verify-ignore-unexpected=note -fcheckedc-extension %s
#include <stdchecked.h>
@ -133,8 +133,8 @@ extern void f18(int i) {
q = _Dynamic_bounds_cast<ptr<int>>(r);
r = _Dynamic_bounds_cast<array_ptr<int>>(p, 1); // expected-error {{expression has no bounds}}
r = _Dynamic_bounds_cast<array_ptr<int>>(p, p, p + 1); // expected-error {{expression has no bounds}}
r = _Dynamic_bounds_cast<array_ptr<int>>(p, 1); // expected-error {{expression has no bounds}} expected-error {{declared bounds for r are invalid after assignment}}
r = _Dynamic_bounds_cast<array_ptr<int>>(p, p, p + 1); // expected-error {{expression has no bounds}} expected-error {{declared bounds for r are invalid after assignment}}
r = _Dynamic_bounds_cast<array_ptr<int>>(i, 1); // expected-error {{expression has no bounds}}
r = _Dynamic_bounds_cast<array_ptr<int>>(i, i, i + 1); // expected-error 2 {{expected expression with pointer}}
@ -144,8 +144,8 @@ extern void f18(int i) {
r = _Dynamic_bounds_cast<array_ptr<int>>(q, len);
r = _Dynamic_bounds_cast<array_ptr<int>>(q, q, q + 1); // expected-error {{arithmetic on _Ptr type}}
r = _Dynamic_bounds_cast<array_ptr<int>>(r, 1);
r = _Dynamic_bounds_cast<array_ptr<int>>(r, r, r + 1);
r = _Dynamic_bounds_cast<array_ptr<int>>(r, 1); // expected-error {{declared bounds for r are invalid after assignment}}
r = _Dynamic_bounds_cast<array_ptr<int>>(r, r, r + 1); // expected-error {{declared bounds for r are invalid after assignment}}
p = _Dynamic_bounds_cast<char *>(p); // expected-warning{{incompatible pointer types assigning}} expected-error{{expression has no bounds}}
@ -179,6 +179,6 @@ extern void f19(){
x = _Dynamic_bounds_cast<array_ptr<int>>(p, b); // expected-error {{invalid argument type}}
x = _Dynamic_bounds_cast<array_ptr<int>>(p, p, 1); // expected-error {{expected expression with}}
x = _Dynamic_bounds_cast<array_ptr<int>>(p, p, p + 1);
x = _Dynamic_bounds_cast<array_ptr<int>>(p, p, p + 1); // expected-error {{declared bounds for x are invalid after assignment}}
}

Просмотреть файл

@ -888,7 +888,7 @@ extern void check_call(void) {
// f3(int p checked[10], int y)
f3(x, 0);
f3(y, 0);
f3(z, 0); // TODO: this will produce a bounds error.
f3(z, 0); // expected-error {{argument does not meet declared bounds for 1st parameter}}
f3(x2d, 0); // expected-error {{parameter of incompatible type}}
f3(y2d, 0); // expected-error {{passing 'int _Checked[10][10]' to parameter of incompatible type '_Array_ptr<int>'}}
f3(z2d, 0); // expected-error {{passing 'int _Checked[10]_Nt_checked[10]' to parameter of incompatible type '_Array_ptr<int>'}}
@ -1023,7 +1023,7 @@ extern void check_call(void) {
g2(0, z); // expected-error {{parameter of incompatible type}}
g3(0, x);
g3(0, y);
g3(0, z); // TODO: this should produce a bounds error.
g3(0, z); // expected-error {{argument does not meet declared bounds for 2nd parameter}}
g3a(0, x); // expected-error {{parameter of incompatible type}}
g3a(0, y); // expected-error {{parameter of incompatible type}}
g3a(0, z);
@ -1087,8 +1087,8 @@ void check_call_cv(void) {
const int p_const[10] = { 0, 1, 2, 3, 4,5, 6, 7, 8, 9};
int r checked[10];
const int r_const checked[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int s nt_checked[10];
const int s_const nt_checked[10];
int s nt_checked[11];
const int s_const nt_checked[11];
// Parameters that are pointers to constants being passed pointers to non-const & const values.
f1_const(p, val); // param const int[10], arg int[10] OK
@ -1097,8 +1097,8 @@ void check_call_cv(void) {
f2_const(p_const, val); // param const int checked[10], arg const int[10] OK, provided int * has bounds
f2_const(r, val); // param const int checked[10], arg int checked[10] OK
f2_const(r_const, val); // param const int checked[10], arg const int checked[10] OK
f2a_const(s, val); // param const int nt_checked[10], arg int nt_checked[10] OK
f2a_const(s_const, val); // param const int nt_checked[10], arg const int nt_checked[10] OK
f2a_const(s, val); // param const int nt_checked[11], arg int nt_checked[10] OK
f2a_const(s_const, val); // param const int nt_checked[11], arg const int nt_checked[10] OK
// Parameters that are not pointers to constants being passed arrays of const
f1(p_const, val); // expected-warning {{discards qualifiers}}
@ -1108,7 +1108,7 @@ void check_call_cv(void) {
f3(r_const, val); // expected-warning {{discards qualifiers}}
// param int checked[10], arg const int checked[10] not OK
f3(s_const, val); // expected-warning {{discards qualifiers}}
// param int checked[10], arg const int checked[10] not OK
// param int nt_checked[11], arg const int checked[10] not OK
}
//
@ -1225,8 +1225,9 @@ ptr<int> h17(int arr checked[]) {
}
ptr<int> h17a(int arr nt_checked[]) {
// TODO: bounds declaration checking should fail because count(0) isn't large enough.
return arr; // ptr<T> = nt_array_ptr<T> OK
return arr; // expected-error {{cast source bounds are too narrow for '_Ptr<int>'}}
// ptr<T> = nt_array_ptr<T> OK for typechecking, but bounds
// declaration checking fails.
}
array_ptr<int> h18(int arr checked[]) {
@ -1632,11 +1633,12 @@ void check_cast_operator(void) {
// ptr to array
parr = (ptr<int checked[5]>) &arr;
parr = (ptr<int checked[5]>) ((ptr<int checked[]>) &arr);
parr = (ptr<int checked[5]>) ((ptr<int checked[]>) &arr); // expected-error {{cast source bounds are too narrow for '_Ptr<int _Checked[5]>'}}
parr = (ptr<int checked[3]>) &arr; // expected-error {{incompatible type}}
nt_parr = (ptr<int nt_checked[5]>) &arr;
nt_parr = (ptr<int nt_checked[5]>) ((ptr<int checked[]>) &arr);
nt_parr = (ptr<int nt_checked[5]>) ((ptr<int checked[]>) &arr); //expected-error {{cast source bounds are too narrow for '_Ptr<int _Nt_checked[5]>'}}
nt_parr = (ptr<int nt_checked[3]>) &arr; // expected-error {{incompatible type}}
// array_ptr to array

Просмотреть файл

@ -1488,7 +1488,7 @@ checked void check_cast_operator(void) {
// ptr to array, ptr to unchecked array
parr = (ptr<int checked[5]>) &arr;
parr = (ptr<int checked[5]>) ((ptr<int checked[]>) &arr);
parr = (ptr<int checked[5]>) ((ptr<int checked[]>) &arr); // expected-error {{cast source bounds are too narrow for '_Ptr<int _Checked[5]>'}}
parr = (ptr<int [5]>) &arr; // expected-error {{type in a checked scope must use only checked types or parameter/return types with bounds-safe interfaces}}
parr = (ptr<int *>) &arr; // expected-error {{type in a checked scope must use only checked types or parameter/return types with bounds-safe interfaces}}

Просмотреть файл

@ -172,7 +172,7 @@ checked int test_call_parameters(void) {
f10(arr1);
f10(empty_global_arr); // expected-error {{expression has no bounds}}
f11(param1); // TODO: this should fail with checking of bounds declarations.
f11(param1); // expected-error {{argument does not meet declared bounds for 1st parameter}}
f11(param2);
f11(param3); // expected-error {{argument has no bounds}}
f11(arr1);
@ -190,7 +190,7 @@ checked int test_call_parameters(void) {
f13(arr1);
f13(empty_global_arr);
f14(param1); // TODO: this should fail with checking of bounds declarations.
f14(param1); // expected-error {{argument does not meet declared bounds for 1st parameter}}
f14(param2);
f14(param3); // expected-error {{argument has no bounds}}
f14(arr1);

Просмотреть файл

@ -21,8 +21,8 @@ extern void f2() {
char p[10];
array_ptr<int> a : count(1) = 0;
int b checked[10];
array_ptr<int> c : count(10) = (array_ptr<int>)a;
array_ptr<int> d : count(10) = _Dynamic_bounds_cast<array_ptr<int>>(a, 5);
array_ptr<int> c : count(10) = (array_ptr<int>)a; // expected-error {{declared bounds for 'c' are invalid after initialization}}
array_ptr<int> d : count(10) = _Dynamic_bounds_cast<array_ptr<int>>(a, 5); // expected-error {{declared bounds for 'd' are invalid after initialization}}
a = _Assume_bounds_cast<array_ptr<int>>(p); // expected-error {{invalid bounds cast}}
}
@ -36,9 +36,9 @@ extern void f3() {
extern void f4() {
array_ptr<int> a : count(2) = 0;
array_ptr<ptr<char>> b : count(2) = 0;
array_ptr<char> b : count(2) = 0;
b = _Assume_bounds_cast<array_ptr<ptr<char>>>(a, 2);
b = _Assume_bounds_cast<array_ptr<char>>(a, 2);
a = _Assume_bounds_cast<array_ptr<int>>(b); // expected-error {{invalid bounds cast}}
}