Revamp error messages for issues in checked scopes involving unchecked pointers nested in other types. (#189)

Checked C clang pull request https://github.com/Microsoft/checkedc-clang/pull/363 addresses the problem that bounds-safe interfaces on function pointers were not being used during type checking.  It substantially revised the error messages for cases where the term "unchecked type" might be unclear to programmers (for example, a function or array type that uses an unchecked type). 

This updates the error messages in the existing Checked C tests.  It also adds tests of typecheckng function pointer types involving bounds-safe interfaces.
This commit is contained in:
David Tarditi 2017-08-29 15:19:00 -07:00 коммит произвёл GitHub
Родитель e51720c47a
Коммит 66527b795a
4 изменённых файлов: 497 добавлений и 426 удалений

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

@ -63,7 +63,8 @@ extern ptr<int> f4(int arr checked[]) {
return _Dynamic_bounds_cast<ptr<int>>(arr); // expected-error{{expression has no bounds}}
}
checked int *f5(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s: count(2)) unchecked { // expected-error {{return cannot have an unchecked pointer type}} expected-error {{parameter cannot have an unchecked pointer type}}
checked int *f5(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s: count(2)) unchecked { // expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}} \
expected-error {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
ptr<int> t8 = 0;
t8 = _Assume_bounds_cast<ptr<int>>(r, 1); // expected-error{{invalid bounds cast}}
int a = 5;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -22,14 +22,14 @@
// Test for checked function in top-level checked scope.
// Check if paremeter, return, local variable is checked type
int* checked_func0(ptr<int> p, int *q : itype(ptr<int>), int r[], array_ptr<int> s : count(len), int len) { // expected-error {{return cannot have an unchecked pointer type}} \
// expected-error {{parameter cannot have an unchecked array type}}
int* checked_func0(ptr<int> p, int *q : itype(ptr<int>), int r[], array_ptr<int> s : count(len), int len) { // expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
int a = 5;
int *upa = &a; // expected-error {{variable cannot have an unchecked pointer type in a checked scope}}
int *upb = q; // expected-error {{variable cannot have an unchecked pointer type in a checked scope}}
int *upa = &a; // expected-error {{local variable in a checked scope must have a checked type}}
int *upb = q; // expected-error {{local variable in a checked scope must have a checked type}}
ptr<int> pc = p;
array_ptr<int> pd = q;
int e[5][5]; // expected-error {{variable cannot have an unchecked array type}}
int e[5][5]; // expected-error {{local variable in a checked scope must have a checked type}}
return upa;
}
@ -44,18 +44,18 @@ unchecked int* unchecked_func0(ptr<int> p, int *q : itype(ptr<int>), int r[], ar
}
array_ptr<int> checked_func1_checked_body(int *x, int *y) { // expected-error 2 {{parameter cannot have an unchecked pointer type}}
int *upa = x; // expected-error {{variable cannot have an unchecked pointer type in a checked scope}}
int *upb = y; // expected-error {{variable cannot have an unchecked pointer type in a checked scope}}
array_ptr<int> checked_func1_checked_body(int *x, int *y) { // expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
int *upa = x; // expected-error {{local variable in a checked scope must have a checked type}}
int *upb = y; // expected-error {{local variable in a checked scope must have a checked type}}
return upb;
}
unchecked array_ptr<int> unchecked_func1_checked_body(int *x, int *y) {
#pragma BOUNDS_CHECKED ON
int *upa = x; // expected-error {{variable cannot have an unchecked pointer type in a checked scope}} \
// expected-error {{cannot use a parameter with an unchecked type}}
int *upb = y; // expected-error {{variable cannot have an unchecked pointer type in a checked scope}} \
// expected-error {{cannot use a parameter with an unchecked type}}
int *upa = x; // expected-error {{local variable in a checked scope must have a checked type}} \
// expected-error {{parameter used in a checked scope must have a checked type or a bounds-safe interface}}
int *upb = y; // expected-error {{local variable in a checked scope must have a checked type}} \
// expected-error {{parameter used in a checked scope must have a checked type or a bounds-safe interface}}
return upb;
}
@ -65,7 +65,7 @@ unchecked array_ptr<int> unchecked_func1_unchecked_body(int *x, int *y) {
return upb;
}
array_ptr<int> checked_func1_unchecked_body(int *x, int *y) { // expected-error 2 {{parameter cannot have an unchecked pointer type}}
array_ptr<int> checked_func1_unchecked_body(int *x, int *y) { // expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
int *upa = x;
int *upb = y;
@ -76,34 +76,32 @@ array_ptr<int> checked_func1_unchecked_body(int *x, int *y) { // expected-error
int* checked_func2_checked_parm_checked_ret(int a checked[][5], int b checked[][5]) : itype(ptr<int>) {
}
int* checked_func2_unchecked_parm_checked_ret(int a [][5], int b [][5]) : itype(ptr<int>) { // expected-error 2 {{parameter cannot have an unchecked array type in a checked scope}}
int* checked_func2_unchecked_parm_checked_ret(int a [][5], int b [][5]) : itype(ptr<int>) { // expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
}
int* checked_func2_checked_parm_unchecked_ret(int a checked[][5], int b checked[][5]) { // expected-error {{return cannot have an unchecked pointer type}}
int* checked_func2_checked_parm_unchecked_ret(int a checked[][5], int b checked[][5]) { // expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}}
}
int* checked_func2_unchecked_parm_unchecked_ret(int a [][5], int b [][5]) { // expected-error 2 {{parameter cannot have an unchecked array type in a checked scope}} \
// expected-error {{return cannot have an unchecked pointer type}}
int* checked_func2_unchecked_parm_unchecked_ret(int a [][5], int b [][5]) { // expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}}
}
int* checked_func_check_call(int *a : itype(ptr<int>), int *b : itype(array_ptr<int>)) : itype(array_ptr<int>) {
int e checked[5][5];
int f[5][5]; // expected-error {{variable cannot have an unchecked array type in a checked scope}}
int *upa = checked_func2_checked_parm_checked_ret(e, e); // expected-error {{variable cannot have an unchecked pointer type in a checked scope}}
int f[5][5]; // expected-error {{local variable in a checked scope must have a checked type}}
int *upa = checked_func2_checked_parm_checked_ret(e, e); // expected-error {{local variable in a checked scope must have a checked type}}
ptr<int> pb = checked_func2_checked_parm_checked_ret(e, e);
ptr<int> pc = 0;
pc = checked_func2_unchecked_parm_checked_ret(f, f);
return upa;
}
int* checked_func_itype(int a[] : itype(int *), char b[] : itype(char *)) : itype(int *) {// expected-error 3 {{type must be a checked type}} \
// expected-error 2 {{parameter cannot have an unchecked array type in a checked scope}} \
// expected-error {{return cannot have an unchecked pointer type}}
int* checked_func_itype(int a[] : itype(int *), char b[] : itype(char *)) : itype(int *) {// expected-error 3 {{type must be a checked type}}
}
// Test for checked function with mixed scope in top-level checked scope.
int * checked_func_u(int *p, int *q) unchecked {// expected-error {{return cannot have an unchecked pointer type}} \
// expected-error 2 {{parameter cannot have an unchecked pointer type}}
int * checked_func_u(int *p, int *q) unchecked {// expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
int a = 5;
*p = *q = 0;
ptr<int> pa = &a;
@ -116,8 +114,8 @@ int * checked_func_u(int *p, int *q) unchecked {// expected-error {{return canno
return 0;
}
int * checked_func_u_pragma(int *p, int *q) { // expected-error {{return cannot have an unchecked pointer type}} \
// expected-error 2 {{parameter cannot have an unchecked pointer type}}
int * checked_func_u_pragma(int *p, int *q) { // expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
int a = 5;
*p = *q = 0;
@ -131,14 +129,14 @@ int * checked_func_u_pragma(int *p, int *q) { // expected-error {{return cannot
return 0;
}
int * checked_func_uc(int *p, int *q) unchecked { // expected-error {{return cannot have an unchecked pointer type}} \
// expected-error 2 {{parameter cannot have an unchecked pointer type}}
int * checked_func_uc(int *p, int *q) unchecked { // expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
int *upa;
checked {
int a = 5;
*p = *q = 0;
ptr<int> pa = &a;
int b[5][5]; // expected-error {{variable cannot have an unchecked array type}}
int b[5][5]; // expected-error {{local variable in a checked scope must have a checked type}}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
b[i][j] = -1;
@ -148,15 +146,15 @@ int * checked_func_uc(int *p, int *q) unchecked { // expected-error {{return can
return upa;
}
int * checked_func_uc_pragma(int *p, int *q) {// expected-error {{return cannot have an unchecked pointer type}} \
// expected-error 2 {{parameter cannot have an unchecked pointer type}}
int * checked_func_uc_pragma(int *p, int *q) {// expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
int *upa;
#pragma BOUNDS_CHECKED ON
int a = 5;
*p = *q = 0;
ptr<int> pa = &a;
int b[5][5]; // expected-error {{variable cannot have an unchecked array type}}
int b[5][5]; // expected-error {{local variable in a checked scope must have a checked type}}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
b[i][j] = -1;
@ -166,8 +164,8 @@ int * checked_func_uc_pragma(int *p, int *q) {// expected-error {{return cannot
return upa;
}
int * checked_func_uc1(int *p, int *q) unchecked {// expected-error {{return cannot have an unchecked pointer type}} \
// expected-error 2 {{parameter cannot have an unchecked pointer type}}
int * checked_func_uc1(int *p, int *q) unchecked {// expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
int *upa;
int a = 5;
*p = *q = 0;
@ -175,16 +173,16 @@ int * checked_func_uc1(int *p, int *q) unchecked {// expected-error {{return can
int b[5][5];
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) checked {
b[i][j] = -1; // expected-error {{cannot use a variable with an unchecked type}}
b[i][j] = -1; // expected-error {{local variable used in a checked scope must have a checked type}}
}
}
checked {
return upa; // expected-error {{cannot use a variable with an unchecked type}}
return upa; // expected-error {{local variable used in a checked scope must have a checked type}}
}
}
int * checked_func_uc1_pragma(int *p, int *q) { // expected-error {{return cannot have an unchecked pointer type}} \
// expected-error 2 {{parameter cannot have an unchecked pointer type}}
int * checked_func_uc1_pragma(int *p, int *q) { // expected-error {{return in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
int *upa;
int a = 5;
@ -194,14 +192,14 @@ int * checked_func_uc1_pragma(int *p, int *q) { // expected-error {{return canno
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
#pragma BOUNDS_CHECKED ON
b[i][j] = -1; // expected-error {{cannot use a variable with an unchecked type}}
b[i][j] = -1; // expected-error {{local variable used in a checked scope must have a checked type}}
}
}
#pragma BOUNDS_CHECKED ON
return upa; // expected-error {{cannot use a variable with an unchecked type}}
return upa; // expected-error {{local variable used in a checked scope must have a checked type}}
}
ptr<int> checked_func_u1(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s : count(2)) { // expected-error {{parameter cannot have an unchecked pointer type}}
ptr<int> checked_func_u1(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s : count(2)) { // expected-error {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
int a = 5;
*p = 1;
*q = 2;
@ -220,7 +218,7 @@ ptr<int> checked_func_u1(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s
return q;
}
ptr<int> checked_func_u1_pragma(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s : count(2)) {// expected-error {{parameter cannot have an unchecked pointer type}}
ptr<int> checked_func_u1_pragma(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s : count(2)) {// expected-error {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
int a = 5;
*p = 1;
*q = 2;
@ -249,7 +247,7 @@ int * checked_func_uc(void) : itype(array_ptr<int>) unchecked {
int c checked[5][5];
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
b[i][j] += c[i][j]; // expected-error {{cannot use a variable with an unchecked type}}
b[i][j] += c[i][j]; // expected-error {{local variable used in a checked scope must have a checked type}}
}
}
for (int i = 0; i < 5; i++) {
@ -270,7 +268,7 @@ int * checked_func_uc_pragma(void) : itype(array_ptr<int>) {
int c checked[5][5];
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
b[i][j] += c[i][j]; // expected-error {{cannot use a variable with an unchecked type}}
b[i][j] += c[i][j]; // expected-error {{local variable used in a checked scope must have a checked type}}
}
}
for (int i = 0; i < 5; i++) {
@ -283,13 +281,13 @@ int * checked_func_uc_pragma(void) : itype(array_ptr<int>) {
return upa;
}
int checked_func_ucu1(int *p, int *q, int *r : itype(ptr<int>), int *s : itype(array_ptr<int>)) unchecked { // expected-error 2 {{parameter cannot have an unchecked pointer type}}
int checked_func_ucu1(int *p, int *q, int *r : itype(ptr<int>), int *s : itype(array_ptr<int>)) unchecked { // expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
int sum = 0;
int a = 5;
int *upa = &a;
int b[5][5];
for (int i = 0; i < 5; i++) checked {
sum += b[i][0] + *upa; // expected-error 2 {{cannot use a variable with an unchecked type}}
sum += b[i][0] + *upa; // expected-error 2 {{local variable used in a checked scope must have a checked type}}
for (int j = 1; j < 5; j++) unchecked {
sum += b[i][j];
}
@ -297,7 +295,7 @@ int checked_func_ucu1(int *p, int *q, int *r : itype(ptr<int>), int *s : itype(a
return sum;
}
int checked_func_ucu1_pragma(int *p, int *q, int *r : itype(ptr<int>), int *s : itype(array_ptr<int>)) { // expected-error 2 {{parameter cannot have an unchecked pointer type}}
int checked_func_ucu1_pragma(int *p, int *q, int *r : itype(ptr<int>), int *s : itype(array_ptr<int>)) { // expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
int sum = 0;
int a = 5;
@ -305,7 +303,7 @@ int checked_func_ucu1_pragma(int *p, int *q, int *r : itype(ptr<int>), int *s :
int b[5][5];
for (int i = 0; i < 5; i++) {
#pragma BOUNDS_CHECKED ON
sum += b[i][0] + *upa; // expected-error 2 {{cannot use a variable with an unchecked type}}
sum += b[i][0] + *upa; // expected-error 2 {{local variable used in a checked scope must have a checked type}}
for (int j = 1; j < 5; j++) {
#pragma BOUNDS_CHECKED OFF
sum += b[i][j];
@ -314,19 +312,19 @@ int checked_func_ucu1_pragma(int *p, int *q, int *r : itype(ptr<int>), int *s :
return sum;
}
int checked_func_ucu2(ptr<int> p, int *q) unchecked { // expected-error {{parameter cannot have an unchecked pointer type}}
int checked_func_ucu2(ptr<int> p, int *q) unchecked { // expected-error {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
int a = 5;
int *upa;
array_ptr<int> pc;
upa = pc; // expected-error {{assigning to 'int *' from incompatible type '_Array_ptr<int>'}}
checked {
upa = &a; // expected-error {{cannot use a variable with an unchecked type}}
upa = &a; // expected-error {{local variable used in a checked scope must have a checked type}}
pc = &a;
unchecked {
upa = &a;
pc = &a;
}
upa = &a; // expected-error {{cannot use a variable with an unchecked type}}
upa = &a; // expected-error {{local variable used in a checked scope must have a checked type}}
pc = &a;
}
ptr<int> pb = p;
@ -335,20 +333,20 @@ int checked_func_ucu2(ptr<int> p, int *q) unchecked { // expected-error {{param
return *pb;
}
int checked_func_ucu2_pragma(ptr<int> p, int *q) {// expected-error {{parameter cannot have an unchecked pointer type}}
int checked_func_ucu2_pragma(ptr<int> p, int *q) {// expected-error {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
int a = 5;
int *upa;
array_ptr<int> pc;
upa = pc; // expected-error {{assigning to 'int *' from incompatible type '_Array_ptr<int>'}}
#pragma BOUNDS_CHECKED ON
upa = &a; // expected-error {{cannot use a variable with an unchecked type}}
upa = &a; // expected-error {{local variable used in a checked scope must have a checked type}}
pc = &a;
#pragma BOUNDS_CHECKED OFF
upa = &a;
pc = &a;
#pragma BOUNDS_CHECKED ON
upa = &a; // expected-error {{cannot use a variable with an unchecked type}}
upa = &a; // expected-error {{local variable used in a checked scope must have a checked type}}
pc = &a;
#pragma BOUNDS_CHECKED OFF
ptr<int> pb = p;
@ -374,9 +372,9 @@ unchecked int * unchecked_func3_unchecked_body(int *p, int q[]) {
unchecked int * unchecked_func3_checked_body(int *p, int q[]) {
#pragma BOUNDS_CHECKED ON
int a = 5;
*p = *q = 0; // expected-error 2 {{cannot use a parameter with an unchecked type}}
*p = *q = 0; // expected-error 2 {{parameter used in a checked scope must have a checked type or a bounds-safe interface}}
ptr<int> pa = &a;
int b[5][5]; // expected-error {{variable cannot have an unchecked array type}}
int b[5][5]; // expected-error {{local variable in a checked scope must have a checked type}}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
b[i][j] = -1;
@ -399,8 +397,8 @@ unchecked array_ptr<int> unchecked_func4_unchecked_body(int p[], int q[10], int
unchecked array_ptr<int> unchecked_func4_checked_body(int p[], int q[10], int r[][10]) {
#pragma BOUNDS_CHECKED ON
int *upa; // expected-error {{variable cannot have an unchecked pointer type}}
int *upb; // expected-error {{variable cannot have an unchecked pointer type}}
int *upa; // expected-error {{local variable in a checked scope must have a checked type}}
int *upb; // expected-error {{local variable in a checked scope must have a checked type}}
array_ptr<int> pb;
ptr<int> pc = 0;
upa = pb;
@ -413,7 +411,7 @@ unchecked array_ptr<int> unchecked_func4_checked_body(int p[], int q[10], int r[
unchecked int * unchecked_func_cu(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s : count(2)) {
#pragma BOUNDS_CHECKED ON
int a = 5;
*p = 1; // expected-error {{cannot use a parameter with an unchecked type}}
*p = 1; // expected-error {{parameter used in a checked scope must have a checked type or a bounds-safe interface}}
*q = 2;
*r = 3; // expected-error {{expression has no bounds}}
*s = 4;
@ -436,7 +434,7 @@ unchecked int unchecked_func_cu2(int *p, int *q, int *r : itype(ptr<int>), int *
int b[5][5];
for (int i = 0; i < 5; i++) {
#pragma BOUNDS_CHECKED ON
sum += b[i][0] + *upa; // expected-error 2 {{cannot use a variable with an unchecked type}}
sum += b[i][0] + *upa; // expected-error 2 {{local variable used in a checked scope must have a checked type}}
for (int j = 1; j < 5; j++) {
#pragma BOUNDS_CHECKED OFF
sum += b[i][j];
@ -461,18 +459,18 @@ extern int a9[] : itype(int checked[]);
#pragma BOUNDS_CHECKED OFF
int *a10;
#pragma BOUNDS_CHECKED ON
int **a11; // expected-error {{variable cannot have an unchecked pointer type}}
int **a11; // expected-error {{global variable in a checked scope must have a checked type or a bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
int ***a12;
#pragma BOUNDS_CHECKED ON
int a13[10]; // expected-error {{variable cannot have an unchecked array type}}
int a13[10]; // expected-error {{global variable in a checked scope must have a checked type or a bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
extern int a14[];
#pragma BOUNDS_CHECKED ON
int global[10]; // expected-error {{variable cannot have an unchecked array type}}
int global[10]; // expected-error {{global variable in a checked scope must have a checked type or a bounds-safe interface}}
int checked_global checked[10];
int global_arr1[10]; // expected-error {{variable cannot have an unchecked array type}}
int global_arr1[10]; // expected-error {{global variable in a checked scope must have a checked type or a bounds-safe interface}}
// Test for structure members in top-level checked scope
struct S0 {
@ -484,27 +482,26 @@ struct S0 {
float ***data6 : itype(ptr<ptr<ptr<float>>>);
float data7[4] : itype(float checked[4]);
float data8[] : itype(float checked[]); // expected-error {{field has incomplete type}}
float data9[]; // expected-error {{member cannot have an unchecked array type}}
float data10[4];// expected-error {{member cannot have an unchecked array type}}
float *data11; // expected-error {{member cannot have an unchecked pointer type}}
float **data12; // expected-error {{member cannot have an unchecked pointer type}}
float ***data13;// expected-error {{member cannot have an unchecked pointer type}}
float *data14 : itype(float *); // expected-error {{type must be a checked type}} \
// expected-error {{member cannot have an unchecked pointer type}}
float data9[]; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
float data10[4];// expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
float *data11; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
float **data12; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
float ***data13;// expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
float *data14 : itype(float *); // expected-error {{type must be a checked type}}
};
typedef struct _S1 {
#pragma BOUNDS_CHECKED ON
int *a; // expected-error {{member cannot have an unchecked pointer type}}
int *a; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
#pragma BOUNDS_CHECKED ON
char *b; // expected-error {{member cannot have an unchecked pointer type}}
char *b; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
ptr<int> pc;
array_ptr<int> pd : count(len);
#pragma BOUNDS_CHECKED OFF
#pragma BOUNDS_CHECKED ON
short e[10]; // expected-error {{member cannot have an unchecked array type}}
char f[10]; // expected-error {{member cannot have an unchecked array type}}
short e[10]; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
char f[10]; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
int len;
} S1;
@ -525,12 +522,12 @@ int checked_func_with_checked_struct(void) {
struct local_checked_s {
#pragma BOUNDS_CHECKED OFF
#pragma BOUNDS_CHECKED ON
int *a; // expected-error {{member cannot have an unchecked pointer type}}
char *b; // expected-error {{member cannot have an unchecked pointer type}}
int *a; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
char *b; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
ptr<int> pc;
array_ptr<int> pd : count(len);
short e[10]; // expected-error {{member cannot have an unchecked array type}}
char f[10]; // expected-error {{member cannot have an unchecked array type}}
short e[10]; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
char f[10]; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
int len;
} a;
return 0;
@ -549,14 +546,14 @@ int checked_func_with_unchecked_struct(void) {
} a;
typedef struct _S {
#pragma BOUNDS_CHECKED ON
int *a; // expected-error {{member cannot have an unchecked pointer type}}
int *a; // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}}
} S;
typedef struct _SS {
#pragma BOUNDS_CHECKED OFF
int *a;
} *SS;
S b;
SS c; // expected-error {{variable cannot have an unchecked pointer type}}
SS c; // expected-error {{local variable in a checked scope must have a checked type}}
return 0;
}
@ -599,20 +596,23 @@ void checked_func_call_variadic(void) {
}
#pragma BOUNDS_CHECKED ON
ptr<void(int , ...)> fptr0; // expected-error {{variable cannot have variable arguments}}
ptr<void(int , ptr<int>, array_ptr<int> , ...)> fptr1; // expected-error {{variable cannot have variable arguments}}
void (*fptr2)(int , ...); // expected-error {{variable cannot have an unchecked pointer type}}
ptr<void(int , ...)> fptr0; // expected-error {{variable in a checked scope cannot have variable arguments}}
ptr<void(int , ptr<int>, array_ptr<int> , ...)> fptr1; // expected-error {{variable in a checked scope cannot have variable arguments}}
void (*fptr2)(int , ...); // expected-error {{global variable in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error {{global variable in a checked scope cannot have variable arguments}}
#pragma BOUNDS_CHECKED OFF
typedef struct _S3 {
#pragma BOUNDS_CHECKED ON
#pragma BOUNDS_CHECKED OFF
#pragma BOUNDS_CHECKED ON
int ((*gptr0)(int, ...)); // expected-error {{member cannot have an unchecked pointer type}}
ptr<int*(int, ptr<int>, array_ptr<int>, ...)> gptr1; // expected-error {{member cannot have an unchecked pointer type}}
ptr<int(int, ptr<int>, ...)> gptr2; // expected-error {{member cannot have variable arguments in a checked scope}}
ptr<int(int, ...)> gptr3; // expected-error {{member cannot have variable arguments in a checked scope}}
ptr<int(int, ptr<int(int, ptr<int(int, ...)>)>)> gptr4; // expected-error {{member cannot have variable arguments in a checked scope}}
int ((*gptr0)(int, ...)); // expected-error {{member in a checked scope must have a checked type or a bounds-safe interface}} \
// expected-error {{member in a checked scope cannot have variable arguments}}
ptr<int*(int, ptr<int>, array_ptr<int>, ...)> gptr1; // expected-error {{member in a checked scope must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interfaces}} \
// expected-error {{member in a checked scope cannot have variable arguments}}
ptr<int(int, ptr<int>, ...)> gptr2; // expected-error {{member in a checked scope cannot have variable arguments}}
ptr<int(int, ...)> gptr3; // expected-error {{member in a checked scope cannot have variable arguments}}
ptr<int(int, ptr<int(int, ptr<int(int, ...)>)>)> gptr4; // expected-error {{member in a checked scope cannot have variable arguments}}
} S3;
#pragma BOUNDS_CHECKED ON
@ -634,12 +634,13 @@ void check_checked_constructed_type_variadic(void) {
ptr<void(int,int)> a = 0;
ptr<int(int,int)> b = 0;
ptr<int(int, ptr<int>, ...)> c = 0; // expected-error {{variable cannot have variable arguments}}
ptr<int(int, ptr<int(int, ...)>)> d = 0; // expected-error {{variable cannot have variable arguments}}
ptr<int(int, ptr<int(int,int)>, ...)> e = 0; // expected-error {{variable cannot have variable arguments}}
ptr<int(int, ptr<int(int,...)>, ...)> f = 0; // expected-error {{variable cannot have variable arguments}}
int (*g)(int, ...); // expected-error {{variable cannot have an unchecked}}
ptr<int*(int, int)> h = 0; // expected-error {{variable cannot have an unchecked}}
ptr<int(int, ptr<int>, ...)> c = 0; // expected-error {{variable in a checked scope cannot have variable arguments}}
ptr<int(int, ptr<int(int, ...)>)> d = 0; // expected-error {{variable in a checked scope cannot have variable arguments}}
ptr<int(int, ptr<int(int,int)>, ...)> e = 0; // expected-error {{variable in a checked scope cannot have variable arguments}}
ptr<int(int, ptr<int(int,...)>, ...)> f = 0; // expected-error {{variable in a checked scope cannot have variable arguments}}
int (*g)(int, ...); // expected-error {{local variable in a checked scope must have a checked type}} \\
// expected-error {{local variable in a checked scope cannot have variable arguments}}
ptr<int*(int, int)> h = 0; // expected-error {{local variable in a checked scope must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interface}}
#pragma BOUNDS_CHECKED OFF
{
@ -656,10 +657,12 @@ void check_checked_constructed_type_variadic(void) {
(*var_f)(6, var_d, var_e, a, b, g, h);
(*h)(10,10);
#pragma BOUNDS_CHECKED ON
(*var_c)(2, pa, pa); // expected-error {{cannot use a variable having variable arguments}}
(*var_d)(3, var_b); // expected-error 2 {{cannot use a variable having variable arguments}}
(*var_e)(4, var_c, var_d); // expected-error 3 {{cannot use a variable having variable arguments}}
(*var_f)(6, var_d, var_e, a, b, g, h); // expected-error 3 {{cannot use a variable having variable arguments}} \
// expected-error 2 {{cannot use a variable with an unchecked type}}
(*var_c)(2, pa, pa); // expected-error {{variable used in a checked scope cannot have variable arguments}}
(*var_d)(3, var_b); // expected-error 2 {{variable used in a checked scope cannot have variable arguments}}
(*var_e)(4, var_c, var_d); // expected-error 3 {{variable used in a checked scope cannot have variable arguments}}
(*var_f)(6, var_d, var_e, a, b, g, h); // expected-error 4 {{variable used in a checked scope cannot have variable arguments}} \
// expected-error {{local variable used in a checked scope must have a checked type}} \
// expected-error {{must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interfaces}}
}
}

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

@ -170,7 +170,6 @@ void g2_md(array_ptr<int checked[10]> ap : count(len), int len) {
f2_incomplete_md_arr(ap, len);
f3_incomplete_md_arr(ap, len);
f4_incomplete_md_arr(ap, len);
}
void g2_incomplete_md_array_param(int ap checked[][10] : count(len), int len) {
@ -555,3 +554,53 @@ void g49(ptr<union U1> p, array_ptr<float> p1 : count(10)) {
p->arr2 = p1; // expected-error {{incompatible type}}
p->arr3 = p1; // expected-error {{incompatible type}}
}
//
// Test function pointers
//
//
// Function pointers with parameters with bounds-safe interfaces.
//
// Bounds-safe interface type is an array_ptr.
typedef int(*callback_fn1) (int *a : count(n), int n);
void g60(callback_fn1 fn, array_ptr<int> arr : count(k), int k) {
(*fn)(arr, k);
}
void g61(callback_fn1 fn, array_ptr<float> arr : count(k), int k) {
(*fn)(arr, k); // expected-error {{incompatible type}}
}
// Bounds-safe interface type is 1-D checked array.
typedef int(*callback_fn2) (int *a : itype(int checked[10]));
void g70(callback_fn2 fn, int arr checked[10]) {
(*fn)(arr);
}
void g71(callback_fn2 fn, int arr checked[11]) {
(*fn)(arr);
}
void g72(callback_fn2 fn) {
int arr checked[10];
(*fn)(arr);
}
// Bounds-safe interface type is 2-D checked array.
typedef int(*callback_fn3) (int(*a)[10] : itype(int checked[10][10]));
void g80(callback_fn3 fn, int arr checked[10][10]) {
(*fn)(arr);
}
void g81(callback_fn3 fn, int arr checked[10][11]) {
(*fn)(arr); // expected-error {{incompatible type}}
}
void g82(callback_fn3 fn) {
int arr checked[10][10];
(*fn)(arr);
}