The Checked C compiler now supports an alternate syntax and macros for backward compatibility.  The technical details of the syntax and macros are documented at https://github.com/secure-sw-dev/checkedc/wiki/Proposed-extension-changes-to-improve-backward-compatibility.

This change modifies some of the tests in existing files to use the new syntax.  It only modifies a small fraction of the tests because of the syntactic nature of the changes.  This avoids duplicating test files, making it easier to modify tests later.
This commit is contained in:
Arunkumar Bhattar 2023-05-06 15:40:58 -04:00 коммит произвёл GitHub
Родитель 24a60e59df
Коммит 44b52ca721
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
43 изменённых файлов: 1384 добавлений и 1339 удалений

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

@ -13,5 +13,8 @@
#define dynamic_bounds_cast _Dynamic_bounds_cast
#define assume_bounds_cast _Assume_bounds_cast
#define return_value _Return_value
#define _Dynamic_bounds_cast_M(T, e1, ... ) _Dynamic_bounds_cast<T>(e1, __VA_ARGS__)
#define _Dynamic_bounds_cast_M_N(T, e1 ) _Dynamic_bounds_cast<T>(e1)
#define _Assume_bounds_cast_M(T, e1, ... ) _Assume_bounds_cast<T>(e1, __VA_ARGS__)
#define _Assume_bounds_cast_M_N(T, e1 ) _Assume_bounds_cast<T>(e1)
#endif /* __STDCHECKED_H */

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

@ -16,9 +16,9 @@
// A function with an interface similar to snprintf but without the variable
// number of arguments. The purpose is to test such a call interface in checked
// scope.
void iface(char * restrict s : itype(restrict _Nt_array_ptr<char>) count(n-1),
size_t n _Where n > 0,
const char * restrict src : itype(restrict _Nt_array_ptr<const char>)) {
void iface(char * restrict s _Itype( char* _Nt_array restrict) count(n-1),
size_t n _Where( n > 0),
const char * restrict src _Itype( const char* _Nt_array restrict)) {
return;
}
@ -36,7 +36,7 @@ void iface_array_ptr(char * restrict s : itype(restrict _Array_ptr<char>) count(
void iface_test1(_Array_ptr<char> p : count(len), size_t len) {
void iface_test1(char* _Array p _Count(len), size_t len) {
char buf _Checked[50];
iface_array_ptr(buf, 50, "Hello world");
@ -53,7 +53,7 @@ void iface_test2(_Nt_array_ptr<char> p : count(len), size_t len) {
iface(p, len + 1, "Hello world");
}
void test3(_Array_ptr<char> buf : count(len), size_t len) {
void test3(char* _Array buf _Count(len), size_t len) {
_Unchecked{ snprintf_array_ptr(buf, len, "Hello world - 3"); }
}

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

@ -29,7 +29,7 @@ void failing_test_2(void);
void failing_test_3(void);
void failing_test_4(int k);
void failing_test_5(array_ptr<char> pc : count(len), unsigned len);
void failing_test_6(array_ptr<char> pc : count(len), unsigned len);
void failing_test_6(char* _Array pc _Count(len), unsigned len);
void failing_test_7(array_ptr<char> pc : count(len), unsigned len);
void failing_test_8(unsigned len);
@ -41,7 +41,7 @@ void handle_error(int err) {
// This signature for main is exactly what we want here,
// it also means any uses of argv[i] are checked too!
int main(int argc, array_ptr<char*> argv : count(argc)) {
int main(int argc, char**_Array argv _Count(argc)) {
// Set up the handler for a failing bounds check. Currently the Checked C
// clang implementation raises a SIGILL when a bounds check fails. This
@ -115,7 +115,7 @@ int main(int argc, array_ptr<char*> argv : count(argc)) {
// CHECK-FAIL-4-NOT: Unexpected Success
failing_test_4(5);
} else if (strcmp(argv[1], "fail5") == 0) {
array_ptr<char> p : count(12) = "\0\0\0\0\0\0\0\0abcd";
char* _Array p _Count(12) = "\0\0\0\0\0\0\0\0abcd";
// CHECK-FAIL-5: Successful pointer conversion
// CHECK-FAIL-5-NOT: Unexpected Success
_Static_assert(sizeof(int) <= 8, "update test for integers larger than 64 bits.");
@ -128,7 +128,7 @@ int main(int argc, array_ptr<char*> argv : count(argc)) {
failing_test_6(p, 1);
failing_test_6(p, 0);
} else if (strcmp(argv[1], "fail7") == 0) {
array_ptr<char> p : count(4) = "abcd";
char* _Array p _Count(4) = "abcd";
// CHECK-FAIL-7: Successful conversion to void *
// CHECK-FAIL-7-NOT: Unexpected Success
failing_test_7(p, 1);
@ -157,24 +157,24 @@ int main(int argc, array_ptr<char*> argv : count(argc)) {
// dynamic_check((r+3) != NULL) && dynamic_check(r <= r && r+15 <= r+10) - > OK
// dynamic_check("abcdef", count(2)) -> OK.
void passing_test_1(void) {
ptr<int> q = 0;
int* _Single q = 0;
int r checked[10] = {0,1,2,3,4,5,6,7,8,9};
array_ptr<int> s : count(5) = r;
int* _Array s _Count(5) = r;
q = _Dynamic_bounds_cast<ptr<int>>(r);
printf("Printable0\n");
q = _Dynamic_bounds_cast<array_ptr<int>>(r, count(3));
q = _Dynamic_bounds_cast_M(int* _Array, r, _Count(3));
printf("Printable1\n");
q = _Dynamic_bounds_cast<array_ptr<int>>(r+3, count(3));
printf("Printable2\n");
q = _Dynamic_bounds_cast<array_ptr<int>>(r, bounds(s, s+3));
q = _Dynamic_bounds_cast_M(int* _Array, r, _Bounds(s, s+3));
printf("Printable3\n");
nt_array_ptr<const char> p : count(2) =
_Dynamic_bounds_cast<nt_array_ptr<const char>>("abcdef", count(2));
const char* _Nt_array p _Count(2) =
_Dynamic_bounds_cast<nt_array_ptr<const char>>("abcdef", _Count(2));
printf("Printable4\n");
puts("Expected Success");
@ -191,14 +191,14 @@ void passing_test_2(void) {
q = _Dynamic_bounds_cast<ptr<int>>(NULL);
printf("Printable0\n");
q = _Dynamic_bounds_cast<array_ptr<int>>(NULL, bounds(r, r+5));
q = _Dynamic_bounds_cast_M(int*_Array, NULL, _Bounds(r, r+5));
printf("Printable1\n");
s = NULL;
q = _Dynamic_bounds_cast<ptr<int>>(s);
printf("Printable2\n");
q = _Dynamic_bounds_cast<array_ptr<int>>(s, bounds(r, r+5));
q = _Dynamic_bounds_cast_M(int* _Array, s, _Bounds(r, r+5));
printf("Printable3\n");
puts("Expected Success");
@ -210,7 +210,7 @@ void passing_test_3(void) {
ptr<int> pi = &i;
ptr<void> pv = pi;
void *unchecked_pv = 0;
ptr<void> p1 = _Dynamic_bounds_cast<ptr<void>>(pi);
void* _Single p1 = _Dynamic_bounds_cast_M_N(void* _Single, pi);
printf("Passed p1");
ptr<void> p2 = _Dynamic_bounds_cast<ptr<void>>(pv);
printf("Passed p2");
@ -218,7 +218,7 @@ void passing_test_3(void) {
printf("Passed unchecked_pv");
ptr<void> p3 = _Assume_bounds_cast<ptr<void>>(unchecked_pv);
printf("Passed p3");
void *p4 = _Assume_bounds_cast<void *>(unchecked_pv);
void *p4 = _Assume_bounds_cast_M_N(void *, unchecked_pv);
printf("Passed p4");
puts("Expected Success");
}
@ -227,7 +227,7 @@ void passing_test_3(void) {
void failing_test_1(void) {
ptr<int> q = 0;
int r checked[10] = {0,1,2,3,4,5,6,7,8,9};
q = _Dynamic_bounds_cast<array_ptr<int>>(r, count(15));
q = _Dynamic_bounds_cast_M(int* _Array, r, _Count(15));
printf("Unprintable\n");
@ -238,7 +238,7 @@ void failing_test_1(void) {
void failing_test_2(void) {
ptr<int> q = 0;
int r checked[10] = {0,1,2,3,4,5,6,7,8,9};
q = _Dynamic_bounds_cast<array_ptr<int>>(r+8, count(3));
q = _Dynamic_bounds_cast_M(int* _Array, r+8, _Count(3));
printf("Unprintable\n");
@ -251,13 +251,13 @@ void failing_test_3(void) {
int r checked[10] = {0,1,2,3,4,5,6,7,8,9};
array_ptr<int> s : count(5) = r;
q = _Dynamic_bounds_cast<ptr<int>>(r);
q = _Dynamic_bounds_cast_M_N(int* _Single, r);
printf("Printable0\n");
q = _Dynamic_bounds_cast<array_ptr<int>>(r, count(5));
printf("Printable1\n");
q = _Dynamic_bounds_cast<array_ptr<int>>(r, bounds(s, s+3));
q = _Dynamic_bounds_cast_M(int* _Array, r, _Bounds(s, s+3));
printf("Printable2\n");
s = 0;
@ -273,7 +273,7 @@ void failing_test_3(void) {
// k = 5
void failing_test_4(int k) {
int r checked[10] = {0,1,2,3,4,5,6,7,8,9};
array_ptr<int> s : count(3) = _Dynamic_bounds_cast<array_ptr<int>>(r, count(5));
int* _Array s _Count(3) = _Dynamic_bounds_cast_M(array_ptr<int>, r, _Count(5));
printf("Printable1\n");
printf("Unprintable2: %d\n", *(s+k));
@ -283,7 +283,7 @@ void failing_test_4(int k) {
// TEst dynamic checks involving possibly failig conversions to ptr<int>.
void failing_test_5(array_ptr<char> pc : count(len), unsigned len) {
ptr<int> pi = _Dynamic_bounds_cast<ptr<int>>(pc);
int* _Single pi = _Dynamic_bounds_cast_M_N(int* _Single, pc);
if (len < sizeof(int))
puts("Unexpected Success");
else if (*pi == 0)
@ -311,8 +311,8 @@ void failing_test_7(array_ptr<char> pc : count(len), unsigned len) {
// Test dynamic checks involving possibly failing conversions from
// string literals.
void failing_test_8(unsigned len) {
nt_array_ptr<const char> p : count(len) =
_Dynamic_bounds_cast<nt_array_ptr<const char>>("123456", count(len));
const char* _Nt_array p _Count(len) =
_Dynamic_bounds_cast_M(const char *_Nt_array, "123456", _Count(len));
if (len > 6)
puts("Unexpected Success");
else if ((len == 0 && p != 0) || *p == '1')

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

@ -1,110 +1,110 @@
// This test shows how existential types can be used in combination
// with generic functions and structs to create type-safe callback library
// and client code.
//
// RUN: %clang %s -o %t1 %checkedc_target_flags
// RUN: %checkedc_rununder %t1 -DARR | FileCheck %s --check-prefix TEST
#include <stdlib.h>
#include <stdio.h>
// Library code
#define MAX_CB 100
typedef int event_id;
#define EVENT_START 0
#define EVENT_PAUSE 1
#define EVENT_STOP 2
struct cb_info _For_any(T) {
T *data;
void (*cb)(event_id id, T *data);
};
struct map_entry {
event_id id;
_Exists(T, struct cb_info<T>) info;
};
int num_entries = 0;
struct map_entry cb_map[MAX_CB];
_For_any(T) void reg_cb(event_id id, struct cb_info<T> info) {
_Exists(A, struct cb_info<A>) opaque_info = _Pack(info, _Exists(A, struct cb_info<A>), T);
struct map_entry entry;
entry.id = id;
entry.info = opaque_info;
cb_map[num_entries] = entry;
num_entries += 1;
}
void handle(event_id id) {
for (int i = 0; i < num_entries; i++) {
if (cb_map[i].id == id) {
_Unpack (T) struct cb_info<T> cb_inf = cb_map[i].info;
cb_inf.cb(id, cb_inf.data);
}
}
}
// User code
void cb_start(event_id id, char *task_name) {
printf("cb_start: id = %d, task_name = %s\n", id, task_name);
}
void cb_pause(event_id id, int *resume_in) {
printf("cb_pause: id = %d, resume_in = %ds\n", id, *resume_in);
}
struct continue_info {
int follow_by;
};
void cb_stop(event_id id, struct continue_info *info) {
printf("cb_stop: id = %d, follow_by = %d\n", id, info->follow_by);
}
void client_register() {
struct cb_info<char> start_info = { "task1", &cb_start };
struct cb_info<char> start_info2 = { "task2", &cb_start };
// Unfortunately, we need to malloc the client-passed arguments to the callback.
// This is because type parameters can only appear as pointers inside generic structs.
// Eventually, we relax this constraint.
int *resume_in = (int *) malloc(sizeof(int));
*resume_in = 42;
struct cb_info<int> pause_info = { resume_in, &cb_pause };
struct continue_info *cont_info = (struct continue_info *) malloc(sizeof(struct continue_info));
cont_info->follow_by = 100;
struct cb_info<struct continue_info> stop_info = { cont_info, &cb_stop };
reg_cb<char>(EVENT_START, start_info);
reg_cb<char>(EVENT_START, start_info2);
reg_cb<int>(EVENT_PAUSE, pause_info);
reg_cb<struct continue_info>(EVENT_STOP, stop_info);
}
int main(int argc, char *argv[]) {
client_register();
handle(EVENT_START);
// TEST: cb_start: id = 0, task_name = task1
// TEST: cb_start: id = 0, task_name = task2
handle(EVENT_PAUSE);
// TEST: cb_pause: id = 1, resume_in = 42s
handle(EVENT_STOP);
// TEST: cb_stop: id = 2, follow_by = 100
handle(EVENT_PAUSE);
// TEST: cb_pause: id = 1, resume_in = 42s
handle(EVENT_PAUSE);
// TEST: cb_pause: id = 1, resume_in = 42s
}
// This test shows how existential types can be used in combination
// with generic functions and structs to create type-safe callback library
// and client code.
//
// RUN: %clang %s -o %t1 %checkedc_target_flags
// RUN: %checkedc_rununder %t1 -DARR | FileCheck %s --check-prefix TEST
#include <stdlib.h>
#include <stdio.h>
// Library code
#define MAX_CB 100
typedef int event_id;
#define EVENT_START 0
#define EVENT_PAUSE 1
#define EVENT_STOP 2
struct cb_info _For_any(T) {
T *data;
void (*cb)(event_id id, T *data);
};
struct map_entry {
event_id id;
_Exists(T, struct cb_info<T>) info;
};
int num_entries = 0;
struct map_entry cb_map[MAX_CB];
_For_any(T) void reg_cb(event_id id, struct cb_info<T> info) {
_Exists(A, struct cb_info<A>) opaque_info = _Pack(info, _Exists(A, struct cb_info<A>), T);
struct map_entry entry;
entry.id = id;
entry.info = opaque_info;
cb_map[num_entries] = entry;
num_entries += 1;
}
void handle(event_id id) {
for (int i = 0; i < num_entries; i++) {
if (cb_map[i].id == id) {
_Unpack (T) struct cb_info<T> cb_inf = cb_map[i].info;
cb_inf.cb(id, cb_inf.data);
}
}
}
// User code
void cb_start(event_id id, char *task_name) {
printf("cb_start: id = %d, task_name = %s\n", id, task_name);
}
void cb_pause(event_id id, int *resume_in) {
printf("cb_pause: id = %d, resume_in = %ds\n", id, *resume_in);
}
struct continue_info {
int follow_by;
};
void cb_stop(event_id id, struct continue_info *info) {
printf("cb_stop: id = %d, follow_by = %d\n", id, info->follow_by);
}
void client_register() {
struct cb_info<char> start_info = { "task1", &cb_start };
struct cb_info<char> start_info2 = { "task2", &cb_start };
// Unfortunately, we need to malloc the client-passed arguments to the callback.
// This is because type parameters can only appear as pointers inside generic structs.
// Eventually, we relax this constraint.
int *resume_in = (int *) malloc(sizeof(int));
*resume_in = 42;
struct cb_info<int> pause_info = { resume_in, &cb_pause };
struct continue_info *cont_info = (struct continue_info *) malloc(sizeof(struct continue_info));
cont_info->follow_by = 100;
struct cb_info<struct continue_info> stop_info = { cont_info, &cb_stop };
reg_cb<char>(EVENT_START, start_info);
reg_cb<char>(EVENT_START, start_info2);
reg_cb<int>(EVENT_PAUSE, pause_info);
reg_cb<struct continue_info>(EVENT_STOP, stop_info);
}
int main(int argc, char *argv[]) {
client_register();
handle(EVENT_START);
// TEST: cb_start: id = 0, task_name = task1
// TEST: cb_start: id = 0, task_name = task2
handle(EVENT_PAUSE);
// TEST: cb_pause: id = 1, resume_in = 42s
handle(EVENT_STOP);
// TEST: cb_stop: id = 2, follow_by = 100
handle(EVENT_PAUSE);
// TEST: cb_pause: id = 1, resume_in = 42s
handle(EVENT_PAUSE);
// TEST: cb_pause: id = 1, resume_in = 42s
}

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

@ -1,107 +1,107 @@
// Run-time test for existential types
// There are no expected failures in the execution of this test.
// We're just checking that using _Pack, _Unpack and existentials
// works as inteded.
// The test itself implement a simple counter interface in two different ways:
// with a regular counter and a mod 2 counter.
// We run the two counters in a loop, and then check that the output matches
// what we expect.
//
// RUN: %clang %s -o %t1 %checkedc_target_flags
// RUN: %checkedc_rununder %t1 -DARR | FileCheck %s --check-prefix TEST
#include <stdlib.h>
#include <stdio.h>
struct Counter _For_any(T) {
T *state;
void (*inc)(T *st);
void (*dec)(T *st);
int (*getVal)();
};
// Regular counter
void incIntCounter(int *x) {
*x = (*x) + 1;
}
void decIntCounter(int *x) {
*x = (*x) - 1;
}
int getValIntCounter(int *x) {
return *x;
}
_Exists(T, struct Counter<T>) getCounter() {
struct Counter<int> ct;
int *x = malloc(sizeof(int));
*x = 0;
ct.state = x;
ct.inc = incIntCounter;
ct.dec = decIntCounter;
ct.getVal = getValIntCounter;
return _Pack(ct, _Exists(T, struct Counter<T>), int);
}
// Mod2 counter
void toggleMod2Counter(char *x) {
*x = !(*x);
}
int getValMod2Counter(char *x) {
return *x;
}
_Exists(T, struct Counter<T>) getMod2Counter() {
struct Counter<char> ct;
char *x = malloc(sizeof(char));
*x = 0;
ct.state = x;
ct.inc = toggleMod2Counter;
ct.dec = toggleMod2Counter;
ct.getVal = getValMod2Counter;
return _Pack(ct, _Exists(T, struct Counter<T>), char);
}
int main(int argc, char *argv[]) {
_Exists(T, struct Counter<T>) counters[2];
counters[0] = getCounter();
counters[1] = getMod2Counter();
for (int i = 0; i < 2; i++) {
_Unpack (U) struct Counter<U> unpackCt = counters[i];
for (int j = 0; j < 10; j++) {
printf("counter = %d\n", unpackCt.getVal(unpackCt.state));
unpackCt.inc(unpackCt.state);
}
printf("---\n");
}
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 2
// TEST: counter = 3
// TEST: counter = 4
// TEST: counter = 5
// TEST: counter = 6
// TEST: counter = 7
// TEST: counter = 8
// TEST: counter = 9
// TEST: ---
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 0
// TEST: counter = 1
return 0;
}
// Run-time test for existential types
// There are no expected failures in the execution of this test.
// We're just checking that using _Pack, _Unpack and existentials
// works as inteded.
// The test itself implement a simple counter interface in two different ways:
// with a regular counter and a mod 2 counter.
// We run the two counters in a loop, and then check that the output matches
// what we expect.
//
// RUN: %clang %s -o %t1 %checkedc_target_flags
// RUN: %checkedc_rununder %t1 -DARR | FileCheck %s --check-prefix TEST
#include <stdlib.h>
#include <stdio.h>
struct Counter _For_any(T) {
T *state;
void (*inc)(T *st);
void (*dec)(T *st);
int (*getVal)();
};
// Regular counter
void incIntCounter(int *x) {
*x = (*x) + 1;
}
void decIntCounter(int *x) {
*x = (*x) - 1;
}
int getValIntCounter(int *x) {
return *x;
}
_Exists(T, struct Counter<T>) getCounter() {
struct Counter<int> ct;
int *x = malloc(sizeof(int));
*x = 0;
ct.state = x;
ct.inc = incIntCounter;
ct.dec = decIntCounter;
ct.getVal = getValIntCounter;
return _Pack(ct, _Exists(T, struct Counter<T>), int);
}
// Mod2 counter
void toggleMod2Counter(char *x) {
*x = !(*x);
}
int getValMod2Counter(char *x) {
return *x;
}
_Exists(T, struct Counter<T>) getMod2Counter() {
struct Counter<char> ct;
char *x = malloc(sizeof(char));
*x = 0;
ct.state = x;
ct.inc = toggleMod2Counter;
ct.dec = toggleMod2Counter;
ct.getVal = getValMod2Counter;
return _Pack(ct, _Exists(T, struct Counter<T>), char);
}
int main(int argc, char *argv[]) {
_Exists(T, struct Counter<T>) counters[2];
counters[0] = getCounter();
counters[1] = getMod2Counter();
for (int i = 0; i < 2; i++) {
_Unpack (U) struct Counter<U> unpackCt = counters[i];
for (int j = 0; j < 10; j++) {
printf("counter = %d\n", unpackCt.getVal(unpackCt.state));
unpackCt.inc(unpackCt.state);
}
printf("---\n");
}
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 2
// TEST: counter = 3
// TEST: counter = 4
// TEST: counter = 5
// TEST: counter = 6
// TEST: counter = 7
// TEST: counter = 8
// TEST: counter = 9
// TEST: ---
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 0
// TEST: counter = 1
// TEST: counter = 0
// TEST: counter = 1
return 0;
}

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

@ -141,9 +141,9 @@ extern int Multiply(struct Vector vec1, struct Vector vec2) {
return 0;
}
extern int Multiply2(ptr<struct Vector> vec1p, ptr<struct Vector> vec2p) {
extern int Multiply2(struct Vector *_Single vec1p, struct Vector *_Single vec2p) {
if (vec1p->len != vec2p->len) {
return 1;
return 1;
}
for (int i = 0; i < vec1p->len; i++) {
vec1p->data[i] *= vec2p->data[i];
@ -151,6 +151,7 @@ extern int Multiply2(ptr<struct Vector> vec1p, ptr<struct Vector> vec2p) {
return 0;
}
//
// Declaring checked arrays of function pointers
//
@ -167,6 +168,10 @@ ptr<int(int x, int y)> array_of_ptr_to_func checked[10];
extern ptr<int(int x, int y)> array_of_ptr_to_func checked[];
ptr<int(int x checked[10], int y)> aptr2 checked[10];
ptr<int(int x nt_checked[10], int y)> aptr3 nt_checked[10];
int (*_Single m_array_of_ptr_to_func checked[10])(int x, int y);
extern int (*_Single m_array_of_ptr_to_func checked[]) (int x, int y) ;
int (*_Single m_aptr2 checked[10])(int x checked[10], int y) ;
int (*_Single m_aptr3 nt_checked[10])(int x nt_checked[10], int y);
//
// Declaring pointers to arrays and arrays of pointers
@ -176,12 +181,19 @@ ptr<int checked[5]> ptr_to_array;
ptr<int nt_checked[5]> ptr_to_nullterm_array;
array_ptr<int checked[5]> array_ptr_to_array;
array_ptr<int nt_checked[5]> array_ptr_to_nullterm_array;
int (*_Single m_ptr_to_array) checked[5] ;
int (*_Single m_ptr_to_nullterm_array) nt_checked[5] ;
int (*_Array m_array_ptr_to_array) checked[5] ;
int (*_Array m_array_ptr_to_nullterm_array) nt_checked[5] ;
int(*unchecked_ptr_to_incomplete_array)checked[];
ptr<int checked[]> ptr_to_incomplete_array;
ptr<int nt_checked[]> ptr_to_nullterm_incomplete_array;
array_ptr<int checked[]> array_ptr_to_incomplete_array;
array_ptr<int nt_checked[]> array_ptr_to_nullterm_incomplete_array;
int (*_Array m_array_ptr_to_incomplete_array) checked[] ;
int (*_Array m_array_ptr_to_nullterm_incomplete_array) nt_checked[] ;
// Declaring checked arrays of pointers
int *array_of_unchecked_ptrs checked[5];
@ -192,12 +204,18 @@ array_ptr<int> array_of_array_ptrs checked[5];
array_ptr<int> nullterm_array_of_array_ptrs nt_checked[5];
nt_array_ptr<int> array_of_nullterm_array_ptrs checked[5];
nt_array_ptr<int> nullterm_array_of_nullterm_array_ptrs nt_checked[5];
int *_Array m_nullterm_array_of_array_ptrs nt_checked[5];
int *_Nt_array m_array_of_nullterm_array_ptrs checked[5];
int *_Nt_array m_nullterm_array_of_nullterm_array_ptrs nt_checked[5];
// Declare an unchecked pointer to checked arrays of pointers
int *(*uncheckedptr_to_array_of_unchecked_ptrs) checked[5];
ptr<int>(*unchecked_ptr_to_array_of_ptrs) checked[5];
array_ptr<int>(*unchecked_ptr_to_array_of_array_ptrs) checked[5];
array_ptr<int>(*unchecked_ptr_to_null_term_array_of_array_ptrs) nt_checked[5];
int *_Array (*m_unchecked_ptr_to_array_of_array_ptrs) checked[5];
int *_Array (*m_unchecked_ptr_to_null_term_array_of_array_ptrs) nt_checked[5];
// Declare ptr to checked arrays of pointers
ptr<int *checked[5]> ptr_to_array_of_unchecked_ptrs;
@ -205,6 +223,8 @@ ptr<ptr<int> checked[5]> ptr_to_array_of_ptrs;
ptr<array_ptr<int> checked[5]> ptr_to_array_of_array_ptrs;
ptr<array_ptr<int> nt_checked[5]> ptr_to_nullterm_array_of_array_ptrs;
ptr<nt_array_ptr<int> nt_checked[5]> ptr_to_nullterm_array_of_nullterm_array_ptrs;
int (*_Array *_Single m_ptr_to_nullterm_array_of_array_ptrs) nt_checked[5];
int *_Nt_array (*_Single m_ptr_to_nullterm_array_of_nullterm_array_ptrs) nt_checked[5];
// Declare ptr to a checked array of function pointers
ptr<int (*checked[5])(int x, int y)> ptr_to_array_of_unchecked_func_ptrs;
@ -215,6 +235,10 @@ ptr<ptr<ptr<int>(ptr<int> x, ptr<int> y)>checked[5]>
ptr_to_array_of_checked_func_ptrs_with_ptr_parameters;
ptr<ptr<ptr<int> (ptr<int> x, ptr<int> y)>nt_checked[5]>
ptr_to_nullterm_array_of_checked_func_ptrs_with_ptr_parameters;
int (*_Single *_Single *_Single
m_ptr_to_array_of_checked_func_ptrs_with_ptr_parameters checked[5])(int *_Single x, int *_Single y);
int (*_Single *_Single *_Single
m_ptr_to_nullterm_array_of_checked_func_ptrs_with_ptr_parameters nt_checked[5])(int* _Single x, int* _Single y);
//
@ -236,37 +260,37 @@ void parse_operators_with_types(void) {
int s1 = sizeof(int checked[10]);
int s2 = sizeof(ptr<int checked[5]>);
int s3 = sizeof(array_ptr<int checked[5]>);
int s4 = sizeof(ptr<int>checked[5]);
int s5 = sizeof(array_ptr<int> checked[5]);
int s4 = sizeof(int (*_Single)checked[5]);
int s5 = sizeof(int (*_Single)checked[5]);
// null-terminated versions.
int s6 = sizeof(int nt_checked[10]);
int s7 = sizeof(ptr<int nt_checked[5]>);
int s8 = sizeof(array_ptr<int nt_checked[5]>);
int s9 = sizeof(ptr<int> nt_checked[5]);
int s10 = sizeof(array_ptr<int> nt_checked[5]);
int s9 = sizeof(int (*_Single) nt_checked[5]);
int s10 = sizeof(int (*_Array) nt_checked[5]);
int s20 = _Alignof(int checked[10]);
int s21 = _Alignof(ptr<int checked[5]>);
int s22 = _Alignof(array_ptr<int checked[5]>);
int s23 = _Alignof(ptr<int> checked[5]);
int s24 = _Alignof(array_ptr<int>checked[5]);
int s25 = _Alignof(nt_array_ptr<int>checked[5]);
int s24 = _Alignof(int (*_Array)checked[5]);
int s25 = _Alignof(int *_Nt_array checked[5]);
// null-terminated versions.
int s26 = _Alignof(int nt_checked[10]);
int s27 = _Alignof(ptr<int nt_checked[5]>);
int s28 = _Alignof(array_ptr<int nt_checked[5]>);
int s29 = _Alignof(ptr<int> nt_checked[5]);
int s30 = _Alignof(array_ptr<int> nt_checked[5]);
int s31 = _Alignof(nt_array_ptr<int> nt_checked[5]);
int s30 = _Alignof(int *_Array nt_checked[5]);
int s31 = _Alignof(int *_Nt_array nt_checked[5]);
// Test parsing of some cast operations that should pass checking
// of bounds declarations
int x = 0;
int arr checked[5];
ptr<int> px = (ptr<int>) &x;
array_ptr<int> pax = (array_ptr<int>) &x;
int* _Array pax = (int* _Array) &x;
pax = arr;
// ptr to array type
ptr<int checked[5]> parr = 0;

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

@ -8,25 +8,25 @@
// Top level declarations with different storage classes and
// storage classes omitted.
extern array_ptr<int> a : count(5);
extern array_ptr<int> b : count(3 + 2);
extern int* _Array a : count(5);
extern int* _Array b _Count(3 + 2);
extern int cLen;
extern array_ptr<int> c : count(cLen);
extern array_ptr<int> d : byte_count(20);
extern int* _Array c : count(cLen);
extern int* _Array d _Byte_count(20);
extern array_ptr<int> e : byte_count(5 * sizeof(int));
extern array_ptr<int> f : byte_count(cLen * sizeof(int));
extern array_ptr<int> g : bounds(unknown);
extern array_ptr<int> h : bounds(f - 2, f + 3);
extern array_ptr<int> i : count(5), j : bounds(i - 2, i + 3),
k : bounds(j + 2, j + 5);
extern int* _Array i : count(5),* _Array j _Bounds(i - 2, i + 3),
* _Array k _Bounds(j + 2, j + 5);
static float vals[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 };
static array_ptr<float> l : count(5) = vals;
static _Thread_local array_ptr<int> m : count(5);
array_ptr<int> b : count(3 + 2) = 0;
array_ptr<int> d : byte_count(20) = 0;
array_ptr<int> g : bounds(unknown) = 0;
int* _Array d : byte_count(20) = 0;
int* _Array g _Bounds(unknown) = 0;
// Declare a bounds for a checked array. This is legal, but
// unnecessary.
@ -42,25 +42,26 @@ extern void f1(array_ptr<int> arr : count(5)) {
array_ptr<int> s : byte_count(20) = arr;
array_ptr<int> t : byte_count(5 * sizeof(int)) = arr;
array_ptr<int> u : byte_count(len * sizeof(int)) = arr;
array_ptr<int> v : bounds(v, v + 5) = arr;
array_ptr<int> w : bounds(unknown) = arr;
array_ptr<int> x : bounds(unknown);
array_ptr<int> midarr : bounds(midarr - 1, midarr - 1 + 2) = arr + 2;
int* _Array v _Bounds(v, v + 5) = arr;
int* _Array w _Bounds(unknown) = arr;
int* _Array x _Bounds(unknown);
int* _Array midarr _Bounds(midarr - 1, midarr - 1 + 2) = arr + 2;
static array_ptr<int> cache1 : count(5);
static array_ptr<int> cache1_ptr : bounds(cache1 - 2, cache1 + 3);
}
// Multiple declarators in one declaration
extern void f2(array_ptr<int> arr : count(5)) {
array_ptr<int> p : count(5) = 0, q : count(3 + 2) = arr;
extern void f2(int* _Array arr _Count(5)) {
int* _Array p _Count(5) = 0, * _Array q _Count(3 + 2) = arr;
int len = 5;
array_ptr<int> r : count(len) = arr, s : byte_count(20) = arr;
array_ptr<int> t : byte_count(5 * sizeof(int)) = arr,
u : bounds(u, u + 5) = arr,
v : bounds(unknown) = arr;
int* _Array r _Count(len) = arr, * _Array s _Byte_count(20) = arr;
int* _Array t : byte_count(5 * sizeof(int)) = arr,
* _Array u _Bounds(u, u + 5) = arr,
* _Array v _Bounds(unknown) = arr;
}
// Parenthesized subexpressions
extern void f3(array_ptr<int> arr : count(5)) {
array_ptr<int> p : count((5)) = arr;
@ -70,9 +71,9 @@ extern void f3(array_ptr<int> arr : count(5)) {
array_ptr<int> s : byte_count((20)) = arr;
array_ptr<int> t : byte_count(5 * (sizeof(int))) = arr;
array_ptr<int> u : byte_count((len) * sizeof(int)) = arr;
array_ptr<int> v : bounds(v, (v + 5) + len - len) = arr;
array_ptr<int> w: bounds((w + len - (len)), (w + len)) = arr;
array_ptr<int> midarr : bounds(midarr - 1, (midarr - 1) + 2) = arr + 2;
int* _Array v _Bounds(v, (v + 5) + len - len) = arr;
int* _Array w _Bounds((w + len - (len)), (w + len)) = arr;
int* _Array midarr _Bounds(midarr - 1, (midarr - 1) + 2) = arr + 2;
}
@ -84,10 +85,10 @@ extern void f4(array_ptr<int> arr : count(len), int len) {
// unknown is a contextual a keyword if it follows 'bounds' '('
array_ptr<int> q : bounds(unknown) = arr;
array_ptr<int> r : bounds(unknown + arr, arr + len) = arr; // expected-error {{expected ')'}} expected-note {{to match this '('}}
array_ptr<int> s : bounds(arr + unknown, arr + len) = arr;
array_ptr<int> t : bounds(t, t + count) = arr;
int* _Array s _Bounds(arr + unknown, arr + len) = arr;
int* _Array t _Bounds(t, t + count) = arr;
int bounds = len;
array_ptr<int> u : bounds(u, u + bounds) = arr;
int* _Array u _Bounds(u, u + bounds) = arr;
}
// Checked array declarations
@ -99,11 +100,11 @@ extern void f5(void) {
int arr4 checked[5] : count(len);
int arr7 checked[5] : byte_count(5 * sizeof(int));
int arr8 checked[5] : byte_count(len * sizeof(int));
auto int arr5 checked[5] : bounds(arr5, arr5 + 5);
auto int arr6 checked[5] : bounds(arr5, arr5 + len);
auto int arr5 checked[5] _Bounds(arr5, arr5 + 5);
auto int arr6 checked[5] _Bounds(arr5, arr5 + len);
static int cache checked[5] : count(5);
static array_ptr<int> cache_ptr : bounds(cache - 2, cache + 3);
static int cache checked[5] _Count(5);
static int* _Array cache_ptr _Bounds(cache - 2, cache + 3);
}
// Parsing of more complicated declarations with bounds declarations
@ -114,7 +115,7 @@ extern void f6(int *arr checked[] : count(5)) {
int len = 5;
array_ptr<int *> r : count(len) = arr;
array_ptr<int *> s : byte_count(5 * sizeof(int)) = arr;
array_ptr<int *> t : byte_count(len * sizeof(int)) = arr;
array_ptr<int *> t _Byte_count(len * sizeof(int)) = arr;
// redundant but legal bounds expressions on arrays.
int *arr1 checked[5] : count(5);
int *arr2 checked[5] : count(3 + 2);
@ -122,29 +123,30 @@ extern void f6(int *arr checked[] : count(5)) {
// Checked array of unchecked pointers to functions. We have to parenthesize
// the inner declarator to avoid : count(len) being parsed as part of the
// type of arr, not a bounds expression.
int ((*arr4 checked[5])(int, int)) : count(5);
int ((*arr5 checked[5])(int, int)) : count(len);
int ((*arr6 checked[5])(int, int)) : bounds(arr5, arr5 + len);
int ((*arr4 checked[5])(int, int)) _Count(5);
int ((*arr5 checked[5])(int, int)) _Count(len);
int ((*arr6 checked[5])(int, int)) _Bounds(arr5, arr5 + len);
// Checked array of checked pointers to functions
ptr<int(int, int)> arr7 checked[5] : count(5) = {0};
ptr<int(int, int)> arr8 checked[5] : bounds(arr8, arr8 + 5) = {0};
// Array_ptrs to checked pointers to functions.
array_ptr<ptr<int (int, int)>> u : count(5) = 0;
typedef int (*_Single func_u)(int, int);
func_u* _Array u : count(5) = 0;
array_ptr<ptr<int (int, int)>> v : bounds(v, v + 5) = 0;
array_ptr<ptr<int (int, int)>> w : bounds(v, v + 5) = 0;
array_ptr<ptr<int (int len, array_ptr<int> arr : count(len))>> x : bounds(x, x + 5) = 0;
}
// Bounds expressions with incorrect syntax or semantics
extern void f7(array_ptr<int> arr : count(5)) {
array_ptr<int> p : bounds(start, end + 5) = 0; // expected-error {{undeclared identifier 'start'}} expected-error {{undeclared identifier 'end'}}
array_ptr<int> q : count(len) = 0; // expected-error {{undeclared identifier 'len'}}
array_ptr<int> r : byte_count(len) = 0; // expected-error {{undeclared identifier 'len'}}
array_ptr<int> s : 6 + 6 = 0; // expected-error {{expected bounds expression}}
array_ptr<int> t : 6 + 6, u : count(5) = arr; // expected-error {{expected bounds expression}}
array_ptr<int> v : boounds(a, b + 5) = 0; // expected-error {{expected bounds expression}}
array_ptr<int> w : coount(5) = 0; // expected-error {{expected bounds expression}}
array_ptr<ptr<int (int len, array_ptr<int> arr : count(badvar))>> x // expected-error {{undeclared identifier 'badvar'}}
: bounds(x, x + 5) = 0;
extern void f7(int* _Array arr _Count(5)) {
int* _Array p _Bounds(start, end + 5) = 0; // expected-error {{undeclared identifier 'start'}} expected-error {{undeclared identifier 'end'}}
int* _Array q : count(len) = 0; // expected-error {{undeclared identifier 'len'}}
int* _Array r : byte_count(len) = 0; // expected-error {{undeclared identifier 'len'}}
int* _Array s : 6 + 6 = 0; // expected-error {{expected bounds expression}}
int* _Array t : 6 + 6, * _Array u _Count(5) = arr; // expected-error {{expected bounds expression}}
int* _Array v _Boounds(a, b + 5) = 0; // expected-error {{expected ';' at end of declaration}}
int* _Array w _Coount(5) = 0; // expected-error {{expected ';' at end of declaration}}
typedef int (*_Single func_xx)(int len, int* _Array _Count(badvar)); // expected-error {{undeclared identifier 'badvar'}}
func_xx *_Array x
_Bounds(x, x + 5) = 0;
}

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

@ -35,13 +35,13 @@ extern void f6(int **p : itype(array_ptr<ptr<int>>) byte_count(y), int y) {
extern void f10(int **p : count(y) itype(ptr<int> checked[]), int y) {
}
extern void f11(int **p : itype(ptr<int> checked[]) count(y), int y) {
extern void f11(int **p _Itype(int* _Single checked[]) count(y), int y) {
}
extern void f12(int **p : itype(ptr<int> checked[10]) count(10), int y) {
extern void f12(int **p _Itype(int* _Single checked[10]) count(10), int y) {
}
extern void f13(int **p : count(10) itype(ptr<int> checked[10]), int y) {
extern void f13(int **p _Count(10) _Itype(int* _Single checked[10]), int y) {
}
// Second parameter has interop type annotation
@ -57,23 +57,23 @@ extern void g3(int y, int **p : bounds(p, p + y) itype(array_ptr<ptr<int>>)) {
extern void g4(int y, int **p : itype(array_ptr<ptr<int>>) bounds(p, p + y)) {
}
extern void g5(int y, int **p : byte_count(y) itype(array_ptr<ptr<int>>)) {
extern void g5(int y, int **p _Byte_count(y) _Itype(int* _Single *_Array)) {
}
extern void g6(int y, int **p : itype(array_ptr<ptr<int>>) byte_count(y)) {
extern void g6(int y, int **p : itype(int* _Single *_Array) byte_count(y)) {
}
extern void g10(int y, int **p : count(y) itype(ptr<int> checked[])) {
}
extern void g11(int y, int **p : itype(ptr<int> checked[]) count(y)) {
extern void g11(int y, int **p _Itype(int* _Single checked[]) count(y)) {
}
extern void g12(int y, int **p : itype(ptr<int> checked[10]) count(10)) {
extern void g12(int y, int **p _Itype(int* _Single checked[10]) count(10)) {
}
extern void g13(int y, int **p : count(10) itype(ptr<int> checked[10])) {
extern void g13(int y, int **p _Count(10) itype(int* _Single checked[10])) {
}
//
@ -86,12 +86,11 @@ extern int **h1(int y, ptr<int> p) : itype(array_ptr<ptr<int>>) byte_count(y) {
return 0;
}
extern int **h2(int y, ptr<int> p) : count(y) itype(array_ptr<ptr<int>>) {
extern int **h2(int y, int* _Single p) _Count(y) _Itype(int* _Single *_Array) {
*p = y;
return 0;
}
//
// Global variables with interop type and bounds annotations
//
@ -99,8 +98,8 @@ extern int **h2(int y, ptr<int> p) : count(y) itype(array_ptr<ptr<int>>) {
int size;
int **a1 : itype(array_ptr<ptr<int>>) count(size) = 0;
int **a2 : count(size) itype(array_ptr<array_ptr<int>>) = 0;
int a3[10] : itype(int checked[10]) byte_count(10 * sizeof(int));
extern int a4[] : count(size) itype(int checked[]);
int a3[10] _Itype(int checked[10]) byte_count(10 * sizeof(int));
extern int a4[] _Count(size) _Itype(int checked[]);
//
// Structure members with interop pointer type annotations
@ -113,8 +112,8 @@ struct S1 {
float **data3 : bounds(data3, data3 + len) itype(array_ptr<ptr<float>>);
float **data4 : itype(array_ptr<ptr<float>>) bounds(data3, data3 + len);
float data5[4] : itype(float checked[4]) count(3);
float data6[4] : count(3) itype(float checked[4]);
float *data7[] : itype(ptr<float> checked[]) count(len);
float data6[4] _Count(3) _Itype(float checked[4]);
float *data7[] _Itype(ptr<float> checked[]) count(len);
};
struct S2 {
@ -133,7 +132,7 @@ typedef ptr<const int> pcint;
extern void f40(int **x : itype(ppint) bounds(x, x + len), int len) {
}
extern void f41(int **x : count(len) itype(ppint), int len) {
extern void f41(int **x _Count(len) itype(ppint), int len) {
}
/// Test some error condtions
@ -142,6 +141,6 @@ extern void f50(int **x : itype(ppint) itype(ppint)); // expected-error {{only
extern void f51(int **x : count(5) count(6)); // expected-error {{only one bounds expression allowed}}
extern void f53(int ** x : itype(ppint) count(5) itype(ppint)); // expected-error {{only one itype expression allowed}}
extern void f53(int ** x _Itype(ppint) count(5) _Itype(ppint)); // expected-error {{only one itype expression allowed}}
extern void f53(int ** x : count(5) itype(ppint) count(5)); // expected-error {{only one bounds expression allowed}}
extern void f53(int ** x _Count(5) itype(ppint) count(5)); // expected-error {{only one bounds expression allowed}}

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

@ -26,8 +26,8 @@ extern void f3(int *p : itype(int checked[]), int y) {
extern void f4(int *p : itype(int checked[10]), int y) {
}
extern void f5(int **p : itype(ptr<ptr<int>>), int y) {
**p = y;
extern void f5(int **p _Itype(int* _Single *_Single), int y) {
**p = y;
}
extern void f6(int **p : itype(array_ptr<ptr<int>>), int y) {
@ -36,7 +36,7 @@ extern void f6(int **p : itype(array_ptr<ptr<int>>), int y) {
extern void f7(int **p : itype(ptr<int> checked[]), int y) {
}
extern void f8(int **p : itype(int * checked[10]), int y) {
extern void f8(int **p _Itype(int * checked[10]), int y) {
}
// Second parameter has interop type annotation
@ -60,10 +60,10 @@ extern void g5(int y, int **p : itype(ptr<ptr<int>>)) {
extern void g6(int y, int **p : itype(ptr<array_ptr<int>>)) {
}
extern void g7(int y, int **p : itype(array_ptr<ptr<int>>)) {
extern void g7(int y, int **p _Itype(int *_Single *_Array)) {
}
extern void g8(int y, int **p : itype(ptr<int> checked[])) {
extern void g8(int y, int **p _Itype(int* _Single checked[])) {
}
extern void g9(int y, int **p : itype(int * checked[10])) {
@ -86,7 +86,7 @@ extern int **h3(void) : itype(ptr<ptr<int>>) {
return 0;
}
extern int **h4(void) : itype(array_ptr<ptr<int>>) {
extern int **h4(void) _Itype(int *_Single *_Array) {
return 0;
}
@ -100,9 +100,9 @@ int **a3 : itype(ptr<ptr<int>>) = 0;
int **a4 : itype(ptr<array_ptr<int>>) = 0;
int **a5 : itype(array_ptr<ptr<int>>) = 0;
int **a6 : itype(array_ptr<array_ptr<int>>) = 0;
int ***a7 : itype(ptr<ptr<ptr<int>>>) = 0;
int a8[10] : itype(int checked[10]);
extern int a9[] : itype(int checked[]);
int ***a7 _Itype(ptr<ptr<ptr<int>>>) = 0;
int a8[10] _Itype(int checked[10]);
extern int a9[] _Itype(int checked[]);
//
// Structure members with interop pointer type annotations
//
@ -114,8 +114,8 @@ struct S1 {
float **data4 : itype(ptr<array_ptr<float>>);
float **data5 : itype(array_ptr<ptr<float>>);
float ***data6 : itype(ptr<ptr<ptr<float>>>);
float data7[4] : itype(float checked[4]);
float data8[] : itype(float checked[]);
float data7[4] _Itype(float checked[4]);
float data8[] _Itype(float checked[]);
};
///
@ -133,12 +133,12 @@ extern void f32(const int a[10] : itype(const int checked[10])) {
extern void f33(const int *x : itype(ptr<const int>)) {
}
extern const int *f34(void) : itype(ptr<const int>) {
extern const int *f34(void) _Itype(const int * _Single ) {
return 0;
}
const int *a10 : itype(ptr<const int>) = 0;
int *const a11 : itype(const ptr<int>) = 0;
const int *a10 _Itype(const int * _Single ) = 0;
int *const a11 _Itype(int* const _Single) = 0;
// First dimension of an array interop type for a parameter can
// have modifiers or the static keyword
@ -152,7 +152,7 @@ extern void f36(int a[static const 10] : itype(int checked[static const 10])) {
extern void f37(int a[volatile 10] : itype(int checked[volatile 10])) {
}
extern void f38(const int *const x : itype(const int checked[const])) {
extern void f38(const int *const x _Itype(const int checked[const])) {
}
///
@ -160,14 +160,16 @@ extern void f38(const int *const x : itype(const int checked[const])) {
///
typedef ptr<int> pint;
typedef ptr<const int> pcint;
typedef const int * _Single pcint;
extern void f40(int *x : itype(pint)) {
}
extern void f41(const int *x : itype(pcint)) {
extern void f41(const int *x _Itype(pcint)) {
}
// Identifier not allowed in a type name
void f50(int *p : itype(ptr<int> a)) { // expected-error {{type name cannot have identifier in it}}

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

@ -7,7 +7,7 @@
#include <stdchecked.h>
struct S1 {
array_ptr<int> arr : count(5);
int* _Array arr _Count(5);
};
struct S2 {
@ -33,7 +33,7 @@ struct S6 {
};
struct S7 {
array_ptr<int> arr : bounds(arr, arr + 5);
int* _Array arr _Bounds(arr, arr + 5);
};
// Structure with a variable length array at the end
@ -45,7 +45,7 @@ struct S8 {
// Pointer into the middle of an array
struct S9 {
int start;
array_ptr<int> arr : bounds(arr - start, arr - start + 5);
int* _Array arr _Bounds(arr - start, arr - start + 5);
};
struct S10 {
@ -62,7 +62,7 @@ struct S11 {
struct S12 {
int count;
array_ptr<int> arr : count(count);
int* _Array arr _Count(count);
};
struct S13 {
@ -78,7 +78,7 @@ struct S13 {
array_ptr<int> arr3 : bounds(unknown + arr2, unknown + arr2 + 5); // expected-error {{expected ')'}} \
// expected-note {{to match this '('}}
// not a keyword
array_ptr<int> arr4 : bounds(arr3, arr3 + unknown);
int* _Array arr4 _Bounds(arr3, arr3 + unknown);
};
struct S14 {
@ -94,7 +94,7 @@ struct S14 {
// not a keyword as an argument.
array_ptr<int> arr3 : bounds(bounds + arr2, bounds + arr2 + 5);
// not a keyword
array_ptr<int> arr4 : bounds(arr3, arr3 + bounds);
int* _Array arr4 _Bounds(arr3, arr3 + bounds);
};
//
@ -127,8 +127,8 @@ struct S15 {
// Members that are arrays and that have bounds specified for them.
// Legal but not too interestting.
int arr13[10] : count(9);
int arr14[10] : byte_count(9 * sizeof(int));
int arr15[10] : bounds(arr15, arr15 + 9);
int arr14[10] _Byte_count(9 * sizeof(int));
int arr15[10] _Bounds(arr15, arr15 + 9);
};
// Members that are pointers to functions that have bounds declarations on
@ -151,19 +151,19 @@ extern void S16(void) {
int(*s1)(array_ptr<int> : count(5));
int(*s2)(array_ptr<int> arg : count(5));
int(*s3)(int n, array_ptr<int> arg : count(n));
int(*s4)(array_ptr<int> arg : count(n), int n);
int(*s4)(int* _Array arg _Count(n), int n);
// Use 'byte_count' instead of 'count'.
int(*t1)(array_ptr<int> : byte_count(5 * sizeof(int)));
int(*t2)(array_ptr<int> arg : count(5 * sizeof(int)));
int(*t3)(int n, array_ptr<int> arg : count(n * sizeof(int)));
int(*t4)(array_ptr<int> arg : count(n * sizeof(int)), int n);
int(*t3)(int n, int* _Array arg _Count(n * sizeof(int)));
int(*t4)(int* _Array arg _Count(n * sizeof(int)), int n);
}
struct S17 {
// Members that are pointers to functions that have bounds on
// arguments or return values.
int (*f1)(int len, array_ptr<int> arr : count(len));
array_ptr<int> (*f2)(int len, array_ptr<int> arr : count(len)) : count(len);
int (*f1)(int len, int* _Array arr _Count(len));
int* _Array (*f2)(int len, int* _Array arr _Count(len)) _Count(len);
// same as f1, but checked ptr
ptr<int (int len, array_ptr<int> arr : count(len))> f3;
// same as f2, but checked ptr
@ -180,8 +180,8 @@ struct S17 {
// Bounds distributed across multiple nested members
struct S18 {
struct S19 {
array_ptr<int> lower;
array_ptr<int> upper;
int* _Array lower;
int* _Array upper;
} pair;
array_ptr<int> arr1 : bounds(pair.lower, pair.upper);
struct S20 {
@ -193,7 +193,7 @@ struct S18 {
struct S21 {
struct {
array_ptr<int> lower;
array_ptr<int> upper;
int* _Array upper;
} pair;
array_ptr<int> arr1 : bounds(pair.lower, pair.upper);
struct {
@ -210,7 +210,7 @@ struct S22 {
};
struct S23 {
array_ptr<int> arr : 6 + 6; // expected-error {{expected bounds expression}}
int* _Array arr : 6 + 6; // expected-error {{expected bounds expression}}
};
// Misspell bounds to cause an semantic checking error.
@ -227,7 +227,7 @@ struct S24 {
// and generate several errors.
struct S25 {
int len;
array_ptr<int> arr : coount(5); // expected-error {{expected bounds expression}} \
int* _Array arr : coount(5); // expected-error {{expected bounds expression}} \
// expected-warning {{implicit declaration of function 'coount'}}
};
@ -246,7 +246,7 @@ struct S27 {
// Omit the argument to count to cause a parsing error.
struct S28 {
int len;
array_ptr<int> arr : count(); //expected-error {{expected expression}}
int* _Array arr _Count(); //expected-error {{expected expression}}
};
//
@ -264,7 +264,7 @@ int f1(void) {
int buffer checked[100];
struct S30 {
int len;
array_ptr<int> arr : bounds(buffer, buffer + len); // expected-error 2 {{use of undeclared member 'buffer'}}
int* _Array arr _Bounds(buffer, buffer + len); // expected-error 2 {{use of undeclared member 'buffer'}}
};
}
@ -302,7 +302,7 @@ union U1 {
// with the same size that are arrays of scalars.
union U2 {
array_ptr<int> ip : count(4);
array_ptr<char> cp : count(4 * sizeof(int));
char* _Array cp _Count(4 * sizeof(int));
};
// Unions where dynamic tags are used to ensure correct use of members.
@ -328,7 +328,7 @@ struct S32 {
int tag : 1;
union {
array_ptr<char> cp : count(tag ? len : 0);
array_ptr<int> ip : count(!tag ? 0 : len);
int* _Array ip _Count(!tag ? 0 : len);
};
};
@ -336,7 +336,7 @@ struct S32 {
union U5 {
_Bool isInteger;
ptr<int> ip;
ptr<float> fp;
float* _Single fp;
};
union U6 {

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

@ -1,25 +1,25 @@
// Feature tests of parsing new Checked C member bounds declarations.
//
// The following lines are for the LLVM test harness:
//
// RUN: %clang_cc1 -verify %s
#include <stdchecked.h>
_Static_assert(sizeof(void*) > sizeof(int),
"Pointers must be larger than ints");
// Unions of pointers and integers, where the least significant
// bit is used as a tag.
// We tag integers with 1 instead of trying to tag pointers with 1.
// Null pointers tagged with 1 are not allowed by the current
// Checked C definition.
#define is_tagged_int(p) ((int)(p) & 1)
#define untag_int(p) ((p) & ~1)
union U4 {
array_ptr<int> ip : bounds(ip, is_tagged_int(ip) ? ip : ip + 5); // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
int i;
};
// Feature tests of parsing new Checked C member bounds declarations.
//
// The following lines are for the LLVM test harness:
//
// RUN: %clang_cc1 -verify %s
#include <stdchecked.h>
_Static_assert(sizeof(void*) > sizeof(int),
"Pointers must be larger than ints");
// Unions of pointers and integers, where the least significant
// bit is used as a tag.
// We tag integers with 1 instead of trying to tag pointers with 1.
// Null pointers tagged with 1 are not allowed by the current
// Checked C definition.
#define is_tagged_int(p) ((int)(p) & 1)
#define untag_int(p) ((p) & ~1)
union U4 {
array_ptr<int> ip : bounds(ip, is_tagged_int(ip) ? ip : ip + 5); // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
int i;
};

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

@ -39,11 +39,11 @@ extern void f5(ptr<ptr<ptr<int>>> p, int y) {
***p = y;
}
extern void f6(array_ptr<int> p : count(1), int y) {
*p = y;
extern void f6(int *_Array p _Count(1), int y) {
*p = y;
}
extern void f7(array_ptr<int> p : count(1), int y) {
extern void f7(int *_Array p _Count(1), int y) {
*p = y;
f6(p, y);
}
@ -57,8 +57,8 @@ extern void f9(nt_array_ptr<int> p : count(1), int y) {
f8(p, y);
}
extern void f10(nt_array_ptr<nt_array_ptr<int>> p : count(1),
nt_array_ptr<int> y) {
extern void f10(int *_Nt_array *_Nt_array p _Count(1),
int *_Nt_array y) {
*p = y;
}
@ -92,9 +92,9 @@ extern void g6(int y, array_ptr<int> p : count(1)) {
f7(p, y);
}
extern void g7(int y, nt_array_ptr<int> p : count(1)) {
*p = y;
f9(p, y);
extern void g7(int y, int *_Nt_array p _Count(1)) {
*p = y;
f9(p, y);
}
@ -131,17 +131,15 @@ extern array_ptr<int> h6(int y, array_ptr<int> p) {
return p;
}
extern array_ptr<ptr<int>> h7(int y, array_ptr<ptr<int>> p : count(1)) {
extern int *_Single *_Array h7(int y, int *_Single *_Array p _Count(1)) {
**p = y;
return p;
}
extern nt_array_ptr<int> h8(int y, nt_array_ptr<int> p) {
extern int *_Nt_array h8(int y, int *_Nt_array p) {
return p;
}
extern nt_array_ptr<ptr<int>> h9(int y, nt_array_ptr<ptr<int>> p : count(1)) {
**p = y;
return p;
@ -156,8 +154,8 @@ extern void k1(int y)
int v = y;
ptr<int> t1 = &v;
array_ptr<int> t2 : count(1) = &v;
array_ptr<ptr<int>> t3 : count(1) = &t1;
nt_array_ptr<int> t4 = 0;
int *_Single *_Array t3 _Count(1) = &t1;
int *_Nt_array t4 = 0;
*t1 = 0;
*t2 = 0;
*t3 = 0;
@ -182,9 +180,9 @@ extern int Multiply(struct Vector vec1, struct Vector vec2) {
return 0;
}
extern int Multiply2(ptr<struct Vector> vec1p, ptr<struct Vector> vec2p) {
extern int Multiply2(struct Vector* _Single vec1p, struct Vector* _Single vec2p) {
if (vec1p->len != vec2p->len) {
return 1;
return 1;
}
for (int i = 0; i < vec1p->len; i++) {
vec1p->data[i] *= vec2p->data[i];
@ -209,8 +207,8 @@ ptr<int (int x, int y)> ptrfunc;
// Function types have no size, so bounds checking does not make sense.
//
// Allowed: An array_ptr to an array of function pointers.
array_ptr<ptr<int(int x, int y)>> array_ptr_of_ptrfunc;
nt_array_ptr<ptr<int(int x, int y)>> nullterm_array_ptr_of_ptrfunc;
int (*_Single *_Array array_ptr_of_ptrfunc)(int x, int y) ;
int (*_Single *_Nt_array nullterm_array_ptr_of_ptrfunc)(int x, int y);
//
// Declaring pointers to arrays and arrays of pointers
@ -241,9 +239,9 @@ nt_array_ptr<int> nullterm_array_of_nullterm_pointers nt_checked[5];
// Declare an unchecked pointer to arrays of pointers
int *(*uncheckedptr_to_array_of_unchecked_ptrs)[5];
ptr<int>(*unchecked_ptr_to_array_of_ptrs)[5];
array_ptr<int>(*unchecked_ptr_to_array_of_array_ptrs)[5];
nt_array_ptr<int>(*unchecked_ptr_to_array_of_null_term_array_ptrs)[5];
int* _Single(*unchecked_ptr_to_array_of_ptrs)[5];
int *_Array(*unchecked_ptr_to_array_of_array_ptrs)[5];
int *_Nt_array(*unchecked_ptr_to_array_of_null_term_array_ptrs)[5];
int *(*uncheckedptr_to_nullterm_array_of_unchecked_ptrs) nt_checked[5];
ptr<int>(*unchecked_ptr_to_nullterm_array_of_ptrs) nt_checked[5];
@ -257,17 +255,18 @@ ptr<array_ptr<int>[5]> ptr_to_array_of_array_ptrs;
ptr<nt_array_ptr<int>[5]> ptr_to_array_of_nullterm_array_ptrs;
// Declare ptr to nullterm arrays of pointers
ptr<int *nt_checked[5]> ptr_to_nullterm_array_of_unchecked_ptrs;
ptr<ptr<int>nt_checked[5]> ptr_to_nullterm_array_of_ptrs;
ptr<array_ptr<int>nt_checked[5]> ptr_to_nullterm_array_of_array_ptrs;
ptr<nt_array_ptr<int>nt_checked[5]> ptr_to_nullterm_array_of_nullterm_array_ptrs;
int * *_Single ptr_to_nullterm_array_of_unchecked_ptrs nt_checked[5];
int *_Single ptr_to_nullterm_array_of_ptrs nt_checked[5];
int *_Array *_Single ptr_to_nullterm_array_of_array_ptrs nt_checked[5];
int *_Nt_array *_Single ptr_to_nullterm_array_of_nullterm_array_ptrs nt_checked[5];
// Declare ptr to an array of function pointers
ptr<int (*[5])(int x, int y)> ptr_to_array_of_unchecked_func_ptrs;
ptr<ptr<int (int x, int y)>[5]> ptr_to_array_of_checked_func_ptrs;
// Make parameter and return types be ptrs too.
ptr<ptr<ptr<int> (ptr<int> x, ptr<int> y)>[5]> ptr_to_array_of_checked_func_ptrs_with_ptr_parameters;
ptr<ptr<int* _Single (int* _Single x, int* _Single y)>[5]>
ptr_to_array_of_checked_func_ptrs_with_ptr_parameters;
//
// Typedefs using checked pointer types
@ -277,8 +276,8 @@ typedef ptr<int> t_ptr_int;
typedef ptr<int (int x, int y)> t_ptr_func;
typedef array_ptr<int> t_array_ptr_int;
typedef array_ptr<ptr<int>> t_array_ptr_ptr_int;
typedef nt_array_ptr<int> t_nullterm_array_ptr_int;
typedef nt_array_ptr<ptr<int>> t_nullterm_array_ptr_ptr_int;
typedef int *_Nt_array t_nullterm_array_ptr_int;
typedef int *_Single *_Nt_array t_nullterm_array_ptr_ptr_int;
//
// Operators that take types
@ -314,7 +313,7 @@ void parse_operators_with_types(void) {
int s28 = _Alignof(int(int x, int y));
int s29 = _Alignof(ptr<int>(int x, int y));
// These are OK
int s30 = _Alignof(ptr<int(int x, int y)>);
int s30 = _Alignof(int (*_Single)(int x, int y));
int s31 = _Alignof(int(*)(int x, int y));
// Test parsing of some cast operations that should pass checking
@ -331,4 +330,6 @@ void parse_operators_with_types(void) {
// ptr to function type
ptr<int (int x, int y)> pfunc = (ptr<int (int x, int y)>) 0;
ptr<ptr<int (int x, int y)>[5]> ptr_to_pfunc_arr = (ptr<ptr<int (int x, int y)>[5]>) 0;
int (*_Single (*_Single m_ptr_to_pfunc_arr)[5])(int x, int y)= (int (*_Single (*_Single)[5])(int x, int y)) 0;
}

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

@ -10,10 +10,10 @@ extern int cLen;
extern array_ptr<int> f : byte_count(cLen * sizeof(int));
extern array_ptr<int> g : bounds(f - 2, f + 3) rel_align(char);
extern array_ptr<int> h : bounds(f - 2, f + 3) rel_align_value(sizeof(char));
extern array_ptr<int> i : count(5), j : bounds(i - 2, i + 3) rel_align(char),
l : bounds(i - 2, i + 3) rel_align_value(sizeof(char)),
k : bounds(j + 2, j + 5) rel_align(char),
m : bounds(j + 2, j + 5) rel_align_value(sizeof(char));
extern int* _Array i _Count(5), * _Array j _Bounds(i - 2, i + 3) rel_align(char),
* _Array l _Bounds(i - 2, i + 3) rel_align_value(sizeof(char)),
* _Array k _Bounds(j + 2, j + 5) rel_align(char),
* _Array m _Bounds(j + 2, j + 5) rel_align_value(sizeof(char));
char buf checked[128] : count(128);
array_ptr<char> cursor : bounds(buf, buf + 128) rel_align(char) = buf + 64;
@ -28,8 +28,8 @@ extern void f1(array_ptr<int> arr : count(5)) {
array_ptr<int> midarr1 : bounds(midarr1 - 1, midarr1 - 1 + 2) rel_align_value(sizeof(char)) = arr + 2;
static array_ptr<int> cache1 : count(5);
static array_ptr<int> cache1_ptr : bounds(cache1 - 2, cache1 + 3) rel_align(char);
static array_ptr<int> cache1_ptr1 : bounds(cache1 - 2, cache1 + 3) rel_align_value(sizeof(char));
static int* _Array cache1_ptr _Bounds(cache1 - 2, cache1 + 3) rel_align(char);
static int* _Array cache1_ptr1 _Bounds(cache1 - 2, cache1 + 3) rel_align_value(sizeof(char));
}
extern void f2(array_ptr<int> arr : count(5)) {
@ -38,9 +38,9 @@ extern void f2(array_ptr<int> arr : count(5)) {
u : bounds(u, u + 5) rel_align(char) = arr,
v : bounds(unknown) = arr;
array_ptr<int> t1 : byte_count(5 * sizeof(int)) = arr,
u1 : bounds(u1, u1 + 5) rel_align_value(sizeof(int)) = arr,
v1 : bounds(unknown) = arr;
int* _Array t1 _Byte_count(5 * sizeof(int)) = arr,
* _Array u1 _Bounds(u1, u1 + 5) rel_align_value(sizeof(int)) = arr,
* _Array v1 _Bounds(unknown) = arr;
}
extern void f3(array_ptr<int> arr : count(5)) {
@ -51,7 +51,7 @@ extern void f3(array_ptr<int> arr : count(5)) {
array_ptr<int> v1 : bounds(v1, (v1 + 5) + len - len) rel_align_value(sizeof(char)) = arr;
array_ptr<int> w1 : bounds((w1 + len - (len)), (w1 + len)) rel_align_value(sizeof(char)) = arr;
array_ptr<int> midarr1 : bounds(midarr1 - 1, (midarr1 - 1) + 2) rel_align_value(1) = arr + 2;
int* _Array midarr1 _Bounds(midarr1 - 1, (midarr1 - 1) + 2) rel_align_value(1) = arr + 2;
}
extern void f4(array_ptr<int> arr : count(len), int len) {
@ -63,7 +63,7 @@ extern void f4(array_ptr<int> arr : count(len), int len) {
array_ptr<int> t1 : bounds(t, t + count) rel_align_value(sizeof(char)) = arr;
int bounds = len;
array_ptr<int> u : bounds(u, u + bounds) rel_align(char) = arr;
array_ptr<int> u1 : bounds(u1, u1 + bounds) rel_align_value(sizeof(char)) = arr;
int* _Array u1 _Bounds(u1, u1 + bounds) rel_align_value(sizeof(char)) = arr;
}
extern void f5(void) {
@ -76,7 +76,7 @@ extern void f5(void) {
static int cache checked[5] : count(5);
static array_ptr<int> cache_ptr : bounds(cache - 2, cache + 3) rel_align(char);
static array_ptr<int> cache_ptr1 : bounds(cache - 2, cache + 3) rel_align_value(sizeof(char));
static int* _Array cache_ptr1 _Bounds(cache - 2, cache + 3) rel_align_value(sizeof(char));
}
extern void f6(int *arr checked[] : count(5)) {
@ -127,11 +127,11 @@ extern array_ptr<int> f9s(int start, array_ptr<int> arr : bounds(arr - start, ar
extern array_ptr<int> f10(int bounds, array_ptr<int> arr : count(bounds))
: bounds(arr, arr + bounds) rel_align(char);
extern array_ptr<int> f10s(int bounds, array_ptr<int> arr : count(bounds))
: bounds(arr, arr + bounds) rel_align_value(sizeof(char));
extern int* _Array f10s(int bounds, int* _Array arr _Count(bounds))
_Bounds(arr, arr + bounds) rel_align_value(sizeof(char));
extern array_ptr<int> f11(array_ptr<int> arr : bounds(arr, arr + 5) rel_align(char))
: bounds(arr, arr + 5) rel_align(char) {
extern int* _Array f11(int* _Array arr _Bounds(arr, arr + 5) rel_align(char))
_Bounds(arr, arr + 5) rel_align(char) {
return arr;
}
@ -165,8 +165,8 @@ extern array_ptr<ptr<int>> f14(array_ptr<ptr<int>> arr : count(5))
return arr;
}
extern array_ptr<ptr<int>> f14s(array_ptr<ptr<int>> arr : count(5))
: bounds(arr, arr + 5) rel_align_value(5) {
extern array_ptr<ptr<int>> f14s(array_ptr<ptr<int>> arr _Count(5))
_Bounds(arr, arr + 5) rel_align_value(5) {
return arr;
}
@ -175,8 +175,8 @@ extern array_ptr<int[10]> f15(array_ptr<int[10]> arr : count(5))
return arr;
}
extern array_ptr<int[10]> f15s(array_ptr<int[10]> arr : count(5))
: bounds(arr, arr + 3) rel_align_value(sizeof(char)) {
extern array_ptr<int[10]> f15s(array_ptr<int[10]> arr _Count(5))
_Bounds(arr, arr + 3) rel_align_value(sizeof(char)) {
return arr;
}
@ -189,15 +189,15 @@ extern void f16(void) {
: bounds(arg2, arg2 + n) rel_align(char)> r3 = 0;
ptr<int(array_ptr<int> arg3 : count(n), int n)
: bounds(arg3, arg3 + n) rel_align_value(sizeof(char))> r4 = 0;
typedef int func2(array_ptr<int> arr : count(len), int len)
: bounds(arr, arr + len) rel_align(char);
typedef int func2(int* _Array arr _Count(len), int len)
_Bounds(arr, arr + len) rel_align(char);
}
extern array_ptr<int> f17(int len, array_ptr<int> arr : count(len)) : boounds(arr, arr + len) rel_align(1) { // expected-error {{expected bounds expression}}
}
extern array_ptr<int> f18(int len, array_ptr<int> arr : count(len)) : boounds(arr, arr + len) rel_align(char) { // expected-error {{expected bounds expression}}
}
extern array_ptr<int> f19(int len, array_ptr<int> arr : count(len)) : boounds(arr, arr + len) rel_align_value(len) { // expected-error {{expected bounds expression}}
extern int* _Array f19(int len, int* _Array arr _Count(len)) : boounds(arr, arr + len) rel_align_value(len) { // expected-error {{expected bounds expression}}
}
int f20(void) {
@ -205,7 +205,7 @@ int f20(void) {
struct S30 {
int len;
array_ptr<int> arr : bounds(buffer, buffer + len) rel_align(char); // expected-error 2 {{use of undeclared member 'buffer'}}
array_ptr<int> arr1: bounds(buffer, buffer + len) rel_align_value(sizeof(len));// expected-error 2 {{use of undeclared member 'buffer'}}
int* _Array arr1 _Bounds(buffer, buffer + len) rel_align_value(sizeof(len));// expected-error 2 {{use of undeclared member 'buffer'}}
array_ptr<int> arr2: bounds(buffer, buffer + len) rel_align_value(sizeof(char));// expected-error 2 {{use of undeclared member 'buffer'}}
};
}
@ -229,12 +229,13 @@ extern array_ptr<int> f25(int len, array_ptr<int> arr : count(len)) : boounds(ar
extern array_ptr<int> f26(int len, array_ptr<int> arr : count(len)) : boounds() rel_align(1) {} // expected-error {{expected bounds expression or bounds-safe interface type}}
extern array_ptr<int> f27(int len, array_ptr<int> arr : count(len)) : boounds() rel_alive(1) { // expected-error {{expected bounds expression or bounds-safe interface type}}
extern int* _Array f27(int len, int* _Array arr _Count(len)) : boounds() rel_alive(1) { // expected-error {{expected bounds expression or bounds-safe interface type}}
}
extern void f28(void) {
array_ptr<int> arg : bo0unds(arg, arg + 5) rel_alive(1) = 0; // expected-error {{expected bounds expression or bounds-safe interface type}}
array_ptr<int> arg1 : bo0unds rel_alive(1) = 0; // expected-error {{expected bounds expression or bounds-safe interface type}}
array_ptr<int> arg2 : bo0unds rel_align(1) = 0; // expected-error {{expected bounds expression or bounds-safe interface type}}
int* _Array arg _Bo0unds(arg, arg + 5) rel_alive(1) = 0; // expected-error {{expected ';' at end of declaration}}
int* _Array arg1 _Bo0unds rel_alive(1) = 0; // expected-error {{expected ';' at end of declaration}}
int* _Array arg2 _Bo0unds rel_align(1) = 0; // expected-error {{expected ';' at end of declaration}}
}
struct S1 {
@ -245,8 +246,8 @@ struct S1 {
struct S2 {
int start;
array_ptr<int> arr : bounds(arr - start, arr - start + 5) rel_align(char);
array_ptr<int> arr1 : bounds(arr1 - start, arr1 - start + 5)
rel_align_value(sizeof(char) + sizeof(char));
int* _Array arr1 _Bounds(arr1 - start, arr1 - start + 5)
rel_align_value(sizeof(char) + sizeof(char));
};
struct S3 {
@ -261,7 +262,7 @@ struct S3 {
array_ptr<int> arr5 : bounds(unknown + arr2, unknown + arr2 + 5) rel_align_value(sizeof(char));// expected-error {{expected ')'}} \
// expected-note {{to match this '('}} \
// expected-error {{expected range bounds expression}}
array_ptr<int> arr6 : bounds(arr2, arr2 + unknown) rel_align_value(1);
int* _Array arr6 _Bounds(arr2, arr2 + unknown) rel_align_value(1);
};
struct S4 {
@ -273,7 +274,7 @@ struct S4 {
array_ptr<int> arr5 : bounds(bounds + arr5, bounds + arr5 + 2) rel_align_value(sizeof(int));
array_ptr<int> arr6 : bounds(bounds + arr2, bounds + arr2 + 5) rel_align_value(sizeof(char));
array_ptr<int> arr7 : bounds(arr6, arr6 + bounds) rel_align_value(sizeof(char));
int* _Array arr7 _Bounds(arr6, arr6 + bounds) rel_align_value(sizeof(char));
};
struct S5 {
@ -289,7 +290,7 @@ struct S5 {
int *arr12 : bounds(arr12, arr12 + 9) rel_align(char);
int *arr13 : bounds(arr13, arr13 + 9) rel_align_value(sizeof(char));
int arr14[10] : bounds(arr14, arr14 + 9) rel_align(char);
int arr15[10] : bounds(arr15, arr15 + 9) rel_align_value(sizeof(char));
int arr15[10] _Bounds(arr15, arr15 + 9) rel_align_value(sizeof(char));
};
extern void S6(void) {
@ -299,8 +300,8 @@ extern void S6(void) {
: bounds(arg1, arg1 + 5) rel_align_value(sizeof(char))> r2 = 0;
ptr<int(array_ptr<int> arg2 : count(n), int n)
: bounds(arg2, arg2 + n) rel_align(char)> r3 = 0;
ptr<int(array_ptr<int> arg3 : count(n), int n)
: bounds(arg3, arg3 + n) rel_align_value(n)> r4 = 0; // expected-error {{expression is not an integer constant expression}}
ptr<int(int* _Array arg3 _Count(n), int n)
_Bounds(arg3, arg3 + n) rel_align_value(n)> r4 = 0; // expected-error {{expression is not an integer constant expression}}
}
struct S7 {
@ -312,7 +313,7 @@ struct S7 {
array_ptr<int> arr1 : bounds(pair.lower, pair.upper) rel_align_value(sizeof(pair));
struct S9 {
array_ptr<int> arr2 : bounds(pair.lower, pair.upper) rel_align(char);
array_ptr<int> arr3 : bounds(pair.lower, pair.upper) rel_align_value(sizeof(pair));
int* _Array arr3 _Bounds(pair.lower, pair.upper) rel_align_value(sizeof(pair));
} nested;
};
@ -325,14 +326,14 @@ struct S10 {
array_ptr<int> arr1 : bounds(pair.lower, pair.upper) rel_align_value(sizeof(char));
struct {
array_ptr<int> arr2 : bounds(pair.lower, pair.upper) rel_align(char);
array_ptr<int> arr3 : bounds(pair.lower, pair.upper) rel_align_value(sizeof(pair));
int* _Array arr3 _Bounds(pair.lower, pair.upper) rel_align_value(sizeof(pair));
} nested;
};
struct S11 {
array_ptr<int> arr : bounds(arr, unknown_id) rel_align(char); // expected-error {{use of undeclared member}}
array_ptr<int> arr1: bounds(arr1, unknown_id) rel_align_value(sizeof(char)); // expected-error {{use of undeclared member}}
int* _Array arr1 _Bounds(arr1, unknown_id) rel_align_value(sizeof(char)); // expected-error {{use of undeclared member}}
};
@ -350,16 +351,16 @@ struct S13 {
array_ptr<int> arr1: bounds() rel_align_value(len); // expected-error {{expected expression}} \
// expected-error {{expression is not an integer constant expression}}
array_ptr<int> arr3 : bounds() rel_align(); // expected-error {{expected expression}} expected-error {{expected a type}}
int* _Array arr3 _Bounds() rel_align(); // expected-error {{expected expression}} expected-error {{expected a type}}
array_ptr<int> arr4 : bounds() rel_align_value(); // expected-error 2 {{expected expression}}
int* _Array arr4 _Bounds() rel_align_value(); // expected-error 2 {{expected expression}}
};
array_ptr<int> global_bound;
struct S14 {
int len;
array_ptr<int> arr : bounds(global_bound, global_bound + len) rel_align(int); // expected-error 2 {{use of undeclared member 'global_bound'}}
int* _Array arr _Bounds(global_bound, global_bound + len) rel_align(int); // expected-error 2 {{use of undeclared member 'global_bound'}}
array_ptr<int> arr1
: bounds(global_bound, global_bound + len) rel_align_value(sizeof(int)); // expected-error 2 {{use of undeclared member 'global_bound'}}

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

@ -18,10 +18,10 @@ extern array_ptr<int> f5(array_ptr<int> arr : byte_count(5 * sizeof(int)))
: byte_count(5 * sizeof(int));
extern array_ptr<int> f6(array_ptr<int> arr : bounds(arr, arr + 5))
: bounds(arr, arr + 5);
extern array_ptr<int> f7(int start,
array_ptr<int> arr : bounds(arr - start, arr - start + 5))
: bounds(arr - start, arr - start + 5);
extern array_ptr<char> f8(void) : bounds(unknown);
extern int* _Array f7(int start,
int* _Array arr _Bounds(arr - start, arr - start + 5))
_Bounds(arr - start, arr - start + 5);
extern char* _Array f8(void) _Bounds(unknown);
// Parsing of return bounds expressions containing return_value. Test this by
// expanding count/byte_count expressions into bounds expressions.
@ -35,8 +35,8 @@ extern array_ptr<int> f3a(int len, array_ptr<int> arr : count(len))
// only when they immediately follow a ':';
extern array_ptr<char> f9(int count) : count(count);
extern array_ptr<char> f10(int unknown) : count(unknown);
extern array_ptr<int> f11(int bounds, array_ptr<int> arr : count(bounds))
: bounds(arr, arr + bounds);
extern int* _Array f11(int bounds, int* _Array arr _Count(bounds))
_Bounds(arr, arr + bounds);
// Parsing function definitions.
extern array_ptr<int> f1(array_ptr<int> arr : count(5)) : count(5) {
@ -53,11 +53,12 @@ extern array_ptr<int> f3(int len,
return arr;
}
extern array_ptr<int> f4(array_ptr<int> arr : byte_count(20))
: byte_count(20) {
extern int* _Array f4(int* _Array arr _Byte_count(20))
_Byte_count(20) {
return arr;
}
extern array_ptr<int> f5(array_ptr<int> arr : byte_count(5 * sizeof(int)))
: byte_count(5 * sizeof(int)) {
return arr;
@ -68,10 +69,10 @@ extern array_ptr<int> f6(array_ptr<int> arr : bounds(arr, arr + 5))
return arr;
}
extern array_ptr<int> f7(int start,
array_ptr<int> arr : bounds(arr - start, arr - start + 5))
: bounds(arr - start, arr - start + 5) {
return arr;
extern int* _Array f7(int start,
int* _Array arr _Bounds(arr - start, arr - start + 5))
_Bounds(arr - start, arr - start + 5) {
return arr;
}
extern array_ptr<char> f8(void) : bounds(unknown) {
@ -92,8 +93,8 @@ extern array_ptr<char> f10(int unknown) : count(unknown) {
// 'bounds' is a contextual keyword. It is only a keyword when it
// immediately follows the ':' in a bounds declaration.
extern array_ptr<int> f11(int bounds, array_ptr<int> arr : count(bounds))
: bounds(arr, arr + bounds) {
extern int* _Array f11(int bounds, int* _Array arr _Count(bounds))
_Bounds(arr, arr + bounds) {
return arr;
}
@ -128,8 +129,10 @@ extern array_ptr<int[10]> f16(array_ptr<int[10]> arr : count(5))
return arr;
}
extern array_ptr<int[10]> f17(array_ptr<int[10]> arr : count(5))
: bounds(arr, arr + 3) {
typedef int (* _Array arrayptr10)[10];
extern arrayptr10 f17(arrayptr10 arr _Count(5))
_Bounds(arr, arr + 3) {
return arr;
}
@ -151,8 +154,10 @@ extern ptr<array_ptr<int>(int len) : count(len)> f19(int len) {
}
// Check that return_value can be used. Expand count to a bounds expression.
extern ptr<array_ptr<int>(int len) : bounds(return_value, len + return_value)>
f19a(int len) { return 0; }
typedef int* _Array f19a_temp(int len) _Bounds(return_value, return_value + len);
extern f19a_temp* _Single f19a(int len) {
return 0;
}
// Like the prior function, but returns an unchecked pointer instead. The
// unchecked pointer points to a function that takes in a length and returns an
@ -170,8 +175,9 @@ extern array_ptr<int> (*f20(int arg))(int len) : count(len) {
// Function that returns an array pointer to ptrs to functions that take in a
// length and return array_ptr<int>s of that length.
extern array_ptr<ptr<array_ptr<int>(int len) : count(len)>> f21(int arg)
: count(arg) {
typedef int* _Array f21_temp(int len) _Count(len);
typedef f21_temp* _Single f21_temp2;
extern f21_temp2* _Array f21(int arg) _Count(arg) {
return 0;
}
@ -209,7 +215,7 @@ extern void f24(void) {
// Use 'bounds' instead of 'count'.
ptr<array_ptr<int>(array_ptr<int> arg : count(5)) : bounds(arg, arg + 5)>
r1 = 0;
ptr<int(array_ptr<int> arg : count(n), int n) : bounds(arg, arg + n)> r2 = 0;
int (*_Single r2)(int* _Array arg _Count(n), int n) _Bounds(arg, arg + n) = 0;
// Unchecked pointers to functions.
int(*s1)(array_ptr<int> : count(5)) = 0;
int(*s2)(array_ptr<int> arg : count(5)) = 0;
@ -218,8 +224,8 @@ extern void f24(void) {
// Use 'byte_count' instead of 'count'.
int(*t1)(array_ptr<int> : byte_count(5 * sizeof(int))) = 0;
int(*t2)(array_ptr<int> arg : count(5 * sizeof(int))) = 0;
int(*t3)(int n, array_ptr<int> arg : count(n * sizeof(int))) = 0;
int(*t4)(array_ptr<int> arg : count(n * sizeof(int)), int n) = 0;
int(*t3)(int n, int* _Array arg _Count(n * sizeof(int))) = 0;
int(*t4)(int* _Array arg _Count(n * sizeof(int)), int n) = 0;
}
typedef array_ptr<int> func1(int len) : count(len);
@ -237,7 +243,7 @@ extern array_ptr<char> f26(void) : count(len) { // expected-error {{use of undec
}
// Misspell bounds to cause a parsing error.
extern array_ptr<int> f27(int len, array_ptr<int> arr : count(len)) : boounds(arr, arr + len)) { // expected-error {{expected bounds expression}}
extern int* _Array f27(int len, int* _Array arr _Count(len)) : boounds(arr, arr + len)) { // expected-error {{expected bounds expression}}
return 0;
}
@ -252,7 +258,7 @@ extern array_ptr<int> f29(int len, array_ptr<int> arr : count(len)) : bounds(arr
}
// Omit both arguments to bounds to cause a parsing error
extern array_ptr<int> f30(int len, array_ptr<int> arr : count(len)) : bounds() { // expected-error {{expected expression}}
extern int* _Array f30(int len, int* _Array arr _Count(len)) _Bounds() { // expected-error {{expected expression}}
return 0;
}
@ -283,7 +289,7 @@ int *(f33(int i)) : count(10) { // expected-error {{unexpected bounds expression
// _Return value can only be used in a return bounds expression
//
int f40(array_ptr<int> a : bounds(return_value, return_value + 10)); // expected-error 2 {{_Return_value can be used only in a return bounds expression}}
int f40(int* _Array a _Bounds(return_value, return_value + 10)); // expected-error 2 {{_Return_value can be used only in a return bounds expression}}
int f41(void) {
return_value = 0; // expected-error {{_Return_value can be used only in a return bounds expression}}

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

@ -10,15 +10,15 @@
// expected-no-diagnostics
// Testing for function declaration with function body, with parameters
_For_any(T, S) _Ptr<T> TestDefinitionWithParameter(_Ptr<T> at, _Ptr<T> bt, _Ptr<S> cs) {
_For_any(T, S) T* _Single TestDefinitionWithParameter(T* _Single at, T* _Single bt, _Ptr<S> cs) {
_Ptr<T> newT = at;
return newT;
}
// Testing for function declaration without function body, without parameters.
_For_any(R) _Ptr<R> TestDeclarationWithNoParameter(void);
_For_any(R) R* _Single TestDeclarationWithNoParameter(void);
// Testing for function declaration without function body, with parameters
_For_any(Q) _Ptr<Q> TestDeclarationWithParameter(_Ptr<Q> aq, _Ptr<Q> bq, _Ptr<Q> cq);
_For_any(Q) Q* _Single TestDeclarationWithParameter(Q* _Single aq, _Ptr<Q> bq, _Ptr<Q> cq);
int callPolymorphicTypes() {
int num = 0;

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

@ -7,9 +7,9 @@
//
// RUN: %clang_cc1 -verify %s
_For_any(R) _Ptr<R> foo(void);
_For_any(R) R* _Single foo(void);
// Testing scope created by for any specifier is exited successfully.
R *thisShouldProduceError; //expected-error{{unknown type name 'R'}}
_For_any() void foo2(void); // expected-error{{expected type variable identifier}}
_For_any(R, ) _Ptr<R> foo3(void); // expected-error{{expected type variable identifier}}
_For_any(R T) _Ptr<R> foo4(void); // expected-error{{expected , or )}}
_For_any(R T) R* _Single foo4(void); // expected-error{{expected , or )}}

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

@ -10,7 +10,7 @@
// RUN: %clang_cc1 -verify %s
// expected-no-diagnostics
_For_any(T) _Ptr<T> foo(_Ptr<T> a, _Ptr<T> b) {
_For_any(T) T* _Single foo(T* _Single a, T* _Single b) {
return a;
}

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

@ -3,7 +3,7 @@
//
// RUN: %clang_cc1 -verify %s
_For_any(T) _Ptr<T> Foo(_Ptr<T> a, _Ptr<T> b) {
_For_any(T) T* _Single Foo(T* _Single a, T* _Single b) {
return a;
}

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

@ -9,7 +9,7 @@
static char *test : itype(ptr<char>);
char p = 5;
static char *init : itype(ptr<char>) = &p;
static char *init _Itype(char* _Single) = &p;
int testfn(char *buf : count(len), size_t len)
_Checked {
@ -18,7 +18,7 @@ _Checked {
}
int main(int argc, array_ptr<char*> argv : count(argc)) {
int main(int argc, char**_Array argv : count(argc)) {
// CHECK: Starting test
puts("Starting test");
testfn(init, 1);

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

@ -13,7 +13,7 @@
// Test taking addresses of members using in bounds expressions for checked members.
struct S1 {
_Array_ptr<int> p : count(len);
int* _Array p _Count(len);
int len;
};
@ -79,7 +79,7 @@ extern void f3(struct S1 *s1, struct S2 *s2, struct S1_Nested *s1_nested, struct
_Array_ptr<int> *p6 = &(s2->s).p; // expected-error {{cannot take address of member with bounds}}
_Array_ptr<int> *p7 = &s1_nested->p; // expected-error {{cannot take address of member with bounds}}
_Array_ptr<int> *p8 = &(s1_nested->p); // expected-error {{cannot take address of member with bounds}}
_Array_ptr<int> *p9 = &(s1_nested)->p; // expected-error {{cannot take address of member with bounds}}
int* _Array *p9 = &(s1_nested)->p; // expected-error {{cannot take address of member with bounds}}
}
// Test taking addresses of members with bounds-safe interfaces.
@ -128,7 +128,7 @@ extern checked void f5(struct S3 s3, struct S4 s4, struct S3_Nested s3_nested) {
_Ptr<int> p9 = &(s3_nested.child).len; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<struct Nested_Len> p10 = &s3_nested.child; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<struct Nested_Len> p11 = &(s3_nested).child; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<struct Nested_Len> p12 = &(s3_nested.child); // expected-error {{cannot take address of member used in member bounds}}
struct Nested_Len* _Single p12 = &(s3_nested.child); // expected-error {{cannot take address of member used in member bounds}}
}
extern void f6(struct S3 *s3, struct S4 *s4, struct S3_Nested *s3_nested) {
@ -159,7 +159,7 @@ extern checked void f7(_Ptr<struct S3> s3, _Ptr<struct S4> s4, _Ptr<struct S3_Ne
_Ptr<int> p9 = &(s3_nested->child).len; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<struct Nested_Len> p10 = &s3_nested->child; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<struct Nested_Len> p11 = &(s3_nested)->child; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<struct Nested_Len> p12 = &(s3_nested->child); // expected-error {{cannot take address of member used in member bounds}}
struct Nested_Len* _Single p12 = &(s3_nested->child); // expected-error {{cannot take address of member used in member bounds}}
}
extern void f8(struct S3 s3, struct S4 s4, struct S3_Nested s3_nested) {
@ -195,7 +195,7 @@ extern checked void f10(struct S3 s3, struct S4 s4, struct S3_Nested s3_nested)
_Ptr<_Array_ptr<int>> p6 = &(s4.s).p; // expected-error {{cannot take address of member with bounds}}
_Ptr<_Array_ptr<int>> p7 = &s3_nested.p; // expected-error {{cannot take address of member with bounds}}
_Ptr<_Array_ptr<int>> p8 = &(s3_nested.p); // expected-error {{cannot take address of member with bounds}}
_Ptr<_Array_ptr<int>> p9 = &(s3_nested).p; // expected-error {{cannot take address of member with bounds}}
int* _Array *_Single p9 = &(s3_nested).p; // expected-error {{cannot take address of member with bounds}}
}
extern checked void f11(_Ptr<struct S3> s3, _Ptr<struct S4> s4, _Ptr<struct S3_Nested> s3_nested) {
@ -207,7 +207,7 @@ extern checked void f11(_Ptr<struct S3> s3, _Ptr<struct S4> s4, _Ptr<struct S3_N
_Ptr<_Array_ptr<int>> p6 = &(s4->s).p; // expected-error {{cannot take address of member with bounds}}
_Ptr<_Array_ptr<int>> p7 = &s3_nested->p; // expected-error {{cannot take address of member with bounds}}
_Ptr<_Array_ptr<int>> p8 = &(s3_nested->p); // expected-error {{cannot take address of member with bounds}}
_Ptr<_Array_ptr<int>> p9 = &(s3_nested)->p; // expected-error {{cannot take address of member with bounds}}
int* _Array *_Single p9 = &(s3_nested)->p; // expected-error {{cannot take address of member with bounds}}
}
//
@ -234,7 +234,7 @@ struct S8 {
extern void f30(struct S5 *s5) {
_Ptr<int _Checked[10]> p1 = &s5->arr; // this is OK because arr can't be modified.
int(* _Single p1) _Checked[10] = &s5->arr; // this is OK because arr can't be modified.
}
extern void f31(struct S6 *s6) {
@ -252,7 +252,7 @@ extern checked void f33(_Ptr<struct S7> s7) {
}
extern checked void f33a(struct S7 *s7 : itype(_Ptr<struct S7>)) {
_Ptr<int _Checked[10]> p1 = &s7->arr; // this is OK because arr can't be modified.
int(* _Single p1) _Checked[10]= &s7->arr; // this is OK because arr can't be modified.
}
@ -268,7 +268,7 @@ extern checked void f35(_Ptr<struct S8> s8) {
extern checked void f35a(struct S8 *s8 : itype(_Ptr<struct S8>)) {
_Ptr<int> p1 = &s8->len; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<int _Checked[10]> p2 = &s8->arr; // this is OK because arr can't be modified.
int (* _Single p2) _Checked[10]= &s8->arr; // this is OK because arr can't be modified.
}
// Spot check bounds for a flexible array member.
@ -300,7 +300,7 @@ extern void f40(struct S9 *s9) {
extern void f41(struct S10 *s10) {
_Ptr<int> p1 = &s10->len; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<int _Checked[]> p2 = &s10->arr; // this is OK because arr can't be modified.
int (*_Single p2) _Checked[] = &s10->arr; // this is OK because arr can't be modified.
}
extern void f42(struct S11 *s11) {
@ -318,7 +318,7 @@ extern void f44(struct S12 *s12) {
extern checked void f45(_Ptr<struct S12> s12) {
_Ptr<int> p1 = &s12->len; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<int _Checked[]> p2 = &s12->arr; // this is OK because arr can't be modified.
int (*_Single p2) _Checked[] = &s12->arr; // this is OK because arr can't be modified.
}
//
@ -339,7 +339,7 @@ void f46(struct S20 s) {
_Ptr<_Array_ptr<int>> p3 = &s.upper; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<_Array_ptr<int>> p4 = &s.upper; // expected-error {{cannot take address of member used in member bounds}}
_Ptr<_Array_ptr<int>> p5 = &s.q; // expected-error {{cannot take address of member with bounds}}
_Ptr<int> p6 = &s.len; // expected-error {{cannot take address of member used in member bounds}}
int* _Single p6 = &s.len; // expected-error {{cannot take address of member used in member bounds}}
}
@ -362,7 +362,8 @@ extern void f60(_Array_ptr<int> x : count(len), int len) {
_Ptr<_Array_ptr<int>> py = &y; // expected-error {{cannot take address of variable 'y' with bounds}}
_Ptr<_Array_ptr<int>> pg = &global_var1; // expected-error {{cannot take address of variable 'global_var1' with bounds}}
_Ptr<int _Checked[]> parr1 = &global_arr1;
_Ptr<int _Checked[]> parr2 = &(global_arr1);
int (*_Single parr2) _Checked[]= &(global_arr1);
if (len >= 0 && len < 10) {
int arr _Checked[10] : count(len);
@ -387,7 +388,7 @@ extern _Checked void f62(int *x : count(len), int len) {
_Ptr<_Array_ptr<int>> px1 = &x; // expected-error {{cannot take address of variable 'x' with bounds}}
_Ptr<_Array_ptr<int>> px2 = &(x); // expected-error {{cannot take address of variable 'x' with bounds}}
_Ptr<_Array_ptr<int>> px3 = (&x); // expected-error {{cannot take address of variable 'x' with bounds}}
_Ptr<_Array_ptr<int>> pg = &global_var2; // expected-error {{cannot take address of variable 'global_var2' with bounds}}
int* _Array *_Single pg = &global_var2; // expected-error {{cannot take address of variable 'global_var2' with bounds}}
_Ptr<int _Checked[]> parr1 = &global_arr2;
_Ptr<int _Checked[]> parr2 = &(global_arr2);

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

@ -13,7 +13,7 @@ int gtmp;
int *g1 = &gtmp;
ptr<int> g2 = &gtmp;
array_ptr<int> g3 = &gtmp;
array_ptr<int> g4 : count(1) = &gtmp;
int* _Array g4 _Count(1) = &gtmp;
extern void check_exprs(int *arg1, ptr<int> arg2, array_ptr<int> arg3,
@ -31,7 +31,7 @@ extern void check_exprs(int *arg1, ptr<int> arg2, array_ptr<int> arg3,
array_ptr<int> arr1 : count(3) = (int checked[3]){0, 1, 2};
array_ptr<int> arr2 : count(4) = (int checked[3]){0, 1, 2}; // expected-error {{declared bounds for 'arr2' are invalid after initialization}}
array_ptr<struct S1> arr_struct1 : count(1) = &(struct S1){0};
array_ptr<struct S1> arr_struct2 : count(2) = &(struct S1){0}; // expected-error {{declared bounds for 'arr_struct2' are invalid after initialization}}
struct S1* _Array arr_struct2 _Count(2) = &(struct S1){0}; // expected-error {{declared bounds for 'arr_struct2' are invalid after initialization}}
// TODO: assignments of variables with array types
// to pointer variables, and reads/writes of struct members.
@ -119,7 +119,7 @@ extern void check_exprs(int *arg1, ptr<int> arg2, array_ptr<int> arg3,
int *t1 = &tmp1;
ptr<int> t2 = &tmp1;
array_ptr<int> t3 = &tmp1;
array_ptr<int> t4 : count(1) = &tmp1;
int* _Array t4 : count(1) = &tmp1;
t1 = arg1;
t2 = arg1; // expected-error {{expression has unknown bounds}}
@ -212,12 +212,12 @@ extern void check_exprs(int *arg1, ptr<int> arg2, array_ptr<int> arg3,
nt_array_ptr<int> g11 : bounds(unknown) = 0;
nt_array_ptr<int> g12 = (int nt_checked[]) { 1, 0 }; // default bounds of count(0);
nt_array_ptr<int> g13 : count(1) = (int nt_checked[]) { 1, 0 };
int* _Nt_array g13 _Count(1) = (int nt_checked[]) { 1, 0 };
struct S2 {
nt_array_ptr<int> f1 : bounds(unknown);
nt_array_ptr<int> f2;
nt_array_ptr<int> f3 : count(1);
int* _Nt_array f3 _Count(1);
};
extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
@ -231,7 +231,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
arg3 = 0;
arg1 = (nt_array_ptr<int>)0xabcd;
arg2 = (nt_array_ptr<int>)0xabcd; // expected-error {{inferred bounds for 'arg2' are unknown after assignment}}
arg3 = (nt_array_ptr<int>)0xabcd; // expected-error {{inferred bounds for 'arg3' are unknown after assignment}}
arg3 = (int* _Nt_array)0xabcd; // expected-error {{inferred bounds for 'arg3' are unknown after assignment}}
// address-of
arg1 = &*arg1;
@ -291,7 +291,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
// locals assigned from parameters
nt_array_ptr<int> t1 : bounds(unknown);
nt_array_ptr<int> t2 = 0;
nt_array_ptr<int> t3 : count(1) = 0;
int* _Nt_array t3 _Count(1) = 0;
t1 = arg1;
t2 = arg1; // expected-error {{inferred bounds for 't2' are unknown after assignment}}
@ -311,7 +311,7 @@ extern void check_exprs_nullterm(nt_array_ptr<int> arg1 : bounds(unknown),
int i1;
nt_array_ptr<int> c2 : count(u1) = 0;
nt_array_ptr<int> c3 : count(u1 * u2 + 2 * i1) = 0;
nt_array_ptr<int> c4 : count(i1) = 0;
int* _Nt_array c4 _Count(i1) = 0;
c1 = c2;
c2 = c1; // expected-error {{it is not possible to prove that the inferred bounds of 'c2' imply the declared bounds of 'c2' after assignment}}
@ -425,7 +425,7 @@ extern void test_f6(array_ptr<int> p : count(0));
extern void check_call_args(int *arg1, ptr<int> arg2, array_ptr<int> arg3,
array_ptr<int> arg4 : count(1),
array_ptr<int> arg5 : count(arglen), int arglen,
int* _Array arg5 _Count(arglen), int arglen,
array_ptr<int> arg6 : count(arglen_u), unsigned int arglen_u) {
test_f1(arg1);
test_f2(arg1); // expected-error {{expression has unknown bounds}}
@ -480,7 +480,7 @@ extern void check_nullterm_call_args(
nt_array_ptr<char> arg2,
nt_array_ptr<char> arg3 : count(1),
nt_array_ptr<char> arg4 : count(arglen), int arglen,
nt_array_ptr<char> arg5 : count(arglen_u), unsigned int arglen_u) {
char* _Nt_array arg5 _Count(arglen_u), unsigned int arglen_u) {
test_nullterm_f1(arg1);
test_nullterm_f2(arg1); // expected-error {{argument has unknown bounds}}
test_nullterm_f3(arg1); // expected-error {{argument has unknown bounds}}
@ -520,14 +520,14 @@ extern void test_bsi_f1(int *p);
extern void test_bsi_f2(int *p : itype(ptr<int>));
extern void test_bsi_f3(int *p : itype(array_ptr<int>));
extern void test_bsi_f4(int *p : count(1));
extern void test_bsi_f5(int *p : count(len), int len);
extern void test_bsi_f5(int *p _Count(len), int len);
extern void test_bsi_f6(int((*compar)(const int *, const int *)) :
itype(_Ptr<int(_Ptr<const int>, _Ptr<const int>)>));
extern int test_cmp(_Ptr<const int> a, _Ptr<const int> b);
extern void check_call_bsi(int *arg1, ptr<int> arg2, array_ptr<int> arg3,
array_ptr<int> arg4 : count(1),
array_ptr<int> arg5 : count(arglen), int arglen) {
int* _Array arg5 : count(arglen), int arglen) {
test_bsi_f1(arg1); // no checking expected when passing unchecked pointers.
test_bsi_f2(arg1);
test_bsi_f3(arg1);
@ -583,7 +583,7 @@ extern int test_nullterm_cmp(nt_array_ptr<const int> a, nt_array_ptr<const int>
extern void check_nullterm_call_bsi(int *arg1 : itype(nt_array_ptr<int>),
nt_array_ptr<int> arg2 : bounds(unknown),
nt_array_ptr<int> arg3,
nt_array_ptr<int> arg4 : count(1),
int* _Nt_array arg4 _Count(1),
nt_array_ptr<int> arg5 : count(arglen),
int arglen,
int **arg6,
@ -631,7 +631,7 @@ extern void check_nullterm_call_bsi(int *arg1 : itype(nt_array_ptr<int>),
}
}
nt_array_ptr<char> nullterm_return1(void);
char* _Nt_array nullterm_return1(void);
nt_array_ptr<char> nullterm_return2(void) : bounds(unknown);
void check_nullterm_return_use(void) {
@ -639,7 +639,7 @@ void check_nullterm_return_use(void) {
p = nullterm_return2(); // expected-error {{inferred bounds for 'p' are unknown after assignment}}
}
nt_array_ptr<char> check_nullterm_return1(void) {
char* _Nt_array check_nullterm_return1(void) {
nt_array_ptr<char> p : bounds(unknown) = 0;
return p; // expected-error {{return value has unknown bounds, bounds expected because the function 'check_nullterm_return1' has bounds}}
}

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

@ -7,10 +7,10 @@
void f1()
_Checked{
_Array_ptr<int> p : count(2) = 0;
_Array_ptr<int> p _Count(2) = 0;
int val = 5;
int val1 _Checked[3];
_Array_ptr<int> q : count(1) = &val;
_Array_ptr<int> q _Count(1) = &val;
_Bundled {
p = q;
*(p+1) = 4; // expected-error {{out-of-bounds memory access}}
@ -26,7 +26,7 @@ _Checked{
_Array_ptr<int> p : count(2) = 0;
int val = 5;
int val1 _Checked[3];
_Array_ptr<int> q : count(1) = &val;
int* _Array q _Count(1) = &val;
_Bundled {
p = val1; // expected-warning {{cannot prove declared bounds for 'p' are valid after assignment}}
p++;
@ -44,7 +44,7 @@ _Checked{
_Array_ptr<int> p : count(2) = 0;
int val = 5;
int val1 _Checked[3];
_Array_ptr<int> q : count(1) = &val;
int* _Array q _Count(1) = &val;
_Bundled {
p = q,
*(p+1) = 4, // expected-error {{out-of-bounds memory access}}
@ -63,7 +63,7 @@ _Checked{
_Array_ptr<int> p : count(2) = 0;
int val = 5;
int val1 _Checked[8];
_Array_ptr<int> q : count(1) = &val;
int* _Array q : count(1) = &val;
_Bundled {
p = val1; // expected-warning {{cannot prove declared bounds for 'p' are valid after assignment}}
p++;
@ -81,7 +81,7 @@ _Checked{
_Array_ptr<int> p : count(2) = 0;
int val = 5;
int val1 _Checked[3];
_Array_ptr<int> q : count(1) = &val;
int* _Array q : count(1) = &val;
_Bundled {
p = flag ? q : val1;
*(p+1) = 4; // expected-error {{expression has unknown bounds}}
@ -94,7 +94,7 @@ _Checked{
void f6(int flag)
_Checked{
_Array_ptr<int> p : count(2) = 0;
int* _Array p _Count(2) = 0;
int val = 5;
int val1 _Checked[3];
_Array_ptr<int> q : count(1) = &val;
@ -138,7 +138,7 @@ _Checked{
_Array_ptr<int> p : count(2) = 0;
int val = 5;
int val1 _Checked[3];
_Array_ptr<int> q : count(1) = &val;
_Array_ptr<int> q _Count(1) = &val;
p = val1;
p++;
p++;
@ -150,10 +150,10 @@ _Checked{
void f9(int flag)
_Checked{
_Array_ptr<int> p : count(2) = 0;
_Array_ptr<int> p _Count(2) = 0;
int val = 5;
int val1 _Checked[3];
_Array_ptr<int> q : count(1) = &val;
int* _Array q _Count(1) = &val;
p = val1,
p++,
p++,
@ -166,7 +166,7 @@ _Checked{
int val = 5;
_Array_ptr<int> q : count(2) = &val; // expected-error {{declared bounds for 'q' are invalid after initialization}}
_Bundled {
_Array_ptr<int> r : count(2) = &val; // expected-error {{declared bounds for 'r' are invalid after initialization}}
int* _Array r _Count(2) = &val; // expected-error {{declared bounds for 'r' are invalid after initialization}}
}
}
@ -174,7 +174,7 @@ void f11()
_Checked{
int val = 5;
int valarr _Checked[4];
_Array_ptr<int> q : count(2) = &val; // expected-error {{declared bounds for 'q' are invalid after initialization}}
int* _Array q _Count(2) = &val; // expected-error {{declared bounds for 'q' are invalid after initialization}}
_Bundled {
_Array_ptr<int> r : count(2) = &val;
r = valarr;
@ -186,7 +186,7 @@ _Checked{
_Array_ptr<int> p : count(2) = 0;
int val = 5;
int val1 _Checked[3];
_Array_ptr<int> q : count(1) = &val;
int* _Array q _Count(1) = &val;
L1:
_Bundled {
p = val1;
@ -202,8 +202,7 @@ _Checked{
extern _Array_ptr<int> my_malloc(int len) : count(len);
extern void copy1(_Array_ptr<int> to, _Array_ptr<int> from : count(n), int n);
extern _Array_ptr<int> copy2(_Array_ptr<int> to, _Array_ptr<int> from : count(n), int n, int new_n) : count(new_n);
extern int* _Array copy2(int* _Array to, int* _Array from _Count(n), int n, int new_n) _Count(new_n);
_Array_ptr<int> resize1(_Array_ptr<int> buf : count(buflen), int buflen, int len) : count(len) {
_Array_ptr<int> tmp : count(len) = my_malloc(len);
@ -216,7 +215,7 @@ _Array_ptr<int> resize1(_Array_ptr<int> buf : count(buflen), int buflen, int len
}
int buflen = 0;
_Array_ptr<int> buf : count(buflen) = 0;
_Array_ptr<int> buf _Count(buflen) = 0;
void resize2(int newlen) {
_Array_ptr<int> tmp : count(newlen) = my_malloc(newlen);
@ -235,7 +234,7 @@ _Array_ptr<int> g4 : count(1) = &gtmp;
int *h1 = &gtmp;
_Ptr<int> h2 = &gtmp;
_Array_ptr<int> h3 = &gtmp;
_Array_ptr<int> h4 : count(1) = &gtmp;
int* _Array h4 _Count(1) = &gtmp;
void gf0(void) {
@ -314,8 +313,8 @@ extern void test_bsi_f6(int((*compar)(const int *, const int *)) :
extern int test_cmp(_Ptr<const int> a, _Ptr<const int> b);
extern void check_call_bsi(int *arg1, _Ptr<int> arg2, _Array_ptr<int> arg3,
_Array_ptr<int> arg4 : count(1),
_Array_ptr<int> arg5 : count(arglen), int arglen) {
int* _Array arg4 _Count(1),
int* _Array arg5 _Count(arglen), int arglen) {
_Bundled {
test_bsi_f1(arg1); // no checking expected when passing unchecked pointers.
@ -388,14 +387,14 @@ struct Node {
};
struct Group {
_Array_ptr<struct Node> list : count (n);
struct Node* _Array list _Count(n);
unsigned int n;
};
extern unsigned int my_strlen(_Nt_array_ptr<char>);
// get the first name that starts with the letters 'Ar'
_Nt_array_ptr<char> get_name(_Array_ptr<struct Group> groups : count(gcnt), unsigned int gcnt)
char* _Nt_array get_name(_Array_ptr<struct Group> groups : count(gcnt), unsigned int gcnt)
_Checked {
unsigned int n = 0;
_Array_ptr<struct Node> group : count(n) = 0;
@ -407,7 +406,7 @@ _Checked {
}
for (int j = 0; j < n; j++) {
_Nt_array_ptr<char> name = group[j].name;
unsigned int m = my_strlen(name) _Where name : count(m);
unsigned int m = my_strlen(name) _Where (name : count(m));
if (m >= 2 && name[0] == 'A' && name[1] == 'r')
return name;
}

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

@ -18,7 +18,7 @@ extern void f1() {
array_ptr<int> v7 : byte_count(5 * sizeof(int)) = 0;
array_ptr<int> v8 : byte_count(5 * sizeof(int)); // expected-error {{automatic variable 'v8' with bounds must have initializer}}
array_ptr<int> v9 : bounds(v9, v9 + 5) = 0;
array_ptr<int> v10 : bounds(v10, v10 + 5); // expected-error {{automatic variable 'v10' with bounds must have initializer}}
int* _Array v10 _Bounds(v10, v10 + 5); // expected-error {{automatic variable 'v10' with bounds must have initializer}}
ptr<int> v20 = 0;
ptr<int> v21; // expected-error {{automatic variable 'v21' with _Ptr type must have initializer}}
@ -50,7 +50,7 @@ nt_array_ptr<int> g31 : count(0) = (int checked[]) { 0, [2] = 2, 3, 5, 0 };
nt_array_ptr<char> g32 : count(5) = "abcde";
array_ptr<char> g33 : count(5) = "abcde";
array_ptr<char> g34 : count(5) = (char[5]) { 'a', 'b', 'c', 'd', 'e' };
array_ptr<char> g35 : count(5) = (char checked[5]) { 'a', 'b', 'c', 'd', 'e' };
char* _Array g35 _Count(5) = (char checked[5]) { 'a', 'b', 'c', 'd', 'e' };
//
// Checked arrays of checked pointers
@ -61,7 +61,7 @@ nt_array_ptr<char> g37 nt_checked[] = { "the", "brown", "fox", "jumped",
void callback1(int a);
void callback2(int a);
nt_array_ptr<ptr<void(int)>> callback_table = (ptr<void(int)>[]) { callback1, callback2, 0 };
void(*_Single *_Nt_array callback_table)(int) = (ptr<void(int)>[]) { callback1, callback2, 0 };
void f3(char *escape) {
}
@ -122,8 +122,8 @@ void f5(void) checked {
nt_array_ptr<char> t32 : count(5) = "abcde";
array_ptr<char> t33 : count(5) = "abcde";
array_ptr<char> t34 = (char[5]) { 'a', 'b', 'c', 'd', 'e' };
array_ptr<char> t35 : count(5) = (char checked[5]) { 'a', 'b', 'c', 'd', 'e' };
char* _Array t34 = (char[5]) { 'a', 'b', 'c', 'd', 'e' };
char* _Array t35 _Count(5) = (char checked[5]) { 'a', 'b', 'c', 'd', 'e' };
//
// Make sure parentheses are ignored.
@ -135,8 +135,8 @@ void f5(void) checked {
// Checked arrays of checked pointers.
//
nt_array_ptr<char> t38 checked[3][2] = { [1] = "ab", "cd", "ef", "jk" };
nt_array_ptr<char> t39 nt_checked[] = { "the", "brown", "fox", "jumped",
"over", "the", "fence", 0 };
char* _Nt_array t39 nt_checked[] = { "the", "brown", "fox", "jumped",
"over", "the", "fence", 0 };
char c = ((char *[2]) { "abc", "def" })[0][0]; // expected-error {{type in a checked\
scope must use only checked types or parameter/return types with bounds-safe interfaces}}
@ -147,7 +147,7 @@ void f5(void) checked {
void f6(void) {
ptr<int> p = 0; // initializer required.
array_ptr<int> q : count(5) = 0; // has bounds; initializer required.
array_ptr<int> lower, upper; // no bounds; initializer not required.
int* _Array lower,* _Array upper; // no bounds; initializer not required.
lower = q;
upper = q + 5;
@ -172,7 +172,7 @@ void f6(void) {
// Check { 0 } initialization idiom where first member is a floating point number.
struct FloatWithVariableBuffer {
float weight;
array_ptr<int> buf : count(len);
int* _Array buf _Count(len);
int len;
};
@ -193,8 +193,8 @@ void f6(void) {
struct checked_value_no_bounds {
int x;
array_ptr<int> lower;
array_ptr<int> upper;
int* _Array lower;
int* _Array upper;
float y;
};
@ -206,8 +206,8 @@ void f6(void) {
struct checked_value_has_bounds {
int x;
array_ptr<char> lower : count(5);
array_ptr<char> upper : count(5);
array_ptr<char> lower _Count(5);
array_ptr<char> upper _Count(5);
float y;
};
@ -232,8 +232,8 @@ void f6(void) {
union u_checked_value_has_bounds {
int x;
array_ptr<char> lower : count(5);
array_ptr<char> upper : count(5);
char* _Array lower : count(5);
char* _Array upper : count(5);
float y;
};
union u_checked_value_has_bounds init_U2 = { 0 }; // has bounds; initializer required and we did, should pass
@ -250,7 +250,7 @@ void f6(void) {
typedef struct {
int data;
array_ptr<char> name : count(20);
array_ptr<char> name _Count(20);
struct Node* next;
} Node;
@ -354,7 +354,7 @@ void f11 (void) checked {
//a struct with unchecked pointers with bounds exprs in a checked scope
typedef struct {
int x;
int* p : count(1);
int* p _Count(1);
char* cp : count(5);
} S;
S s1; // expected-error {{containing an unchecked pointer with a bounds expression in a checked scope must have an initializer}}

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

@ -11,6 +11,10 @@
// expression first. Then we check against prior kinds of expressions. //
//--------------------------------------------------------------------------//
#define _Dynamic_bounds_cast_M(T, e1, ... ) _Dynamic_bounds_cast<T>(e1, __VA_ARGS__)
#define _Dynamic_bounds_cast_M_N(T, e1 ) _Dynamic_bounds_cast<T>(e1)
#define _Assume_bounds_cast_M(T, e1, ... ) _Assume_bounds_cast<T>(e1, __VA_ARGS__)
#define _Assume_bounds_cast_M_N(T, e1 ) _Assume_bounds_cast<T>(e1)
//--------------------------------------------------------------------------//
// Constants //
@ -25,13 +29,13 @@ extern int f1_1(_Array_ptr<int> p : count(0));
extern int f1_2(_Array_ptr<int> p : count(1));
extern int f1_2(_Array_ptr<int> p : count(1));
extern int f1_3(_Array_ptr<int> p : count(5));
extern int f1_3(_Array_ptr<int> p : count(5));
extern int f1_3(int* _Array p _Count(5));
// Integer constant inequality
extern int f1_4(_Array_ptr<int> p : count(0));
extern int f1_4(_Array_ptr<int> p : count(1)); // expected-error {{conflicting parameter bounds}}
extern int f1_5(_Array_ptr<int> p : count(0));
extern int f1_5(_Array_ptr<int> p : count(5)); // expected-error {{conflicting parameter bounds}}
extern int f1_5(int* _Array p _Count(5)); // expected-error {{conflicting parameter bounds}}
// Character constant equality
extern int f1_6(_Array_ptr<int> p : count('a'));
@ -43,7 +47,7 @@ extern int f1_7(_Array_ptr<int> p : count('b')); // expected-error {{confl
// Character constant vs. integer constant inequality
extern int f1_8(_Array_ptr<int> p : count(0));
extern int f1_8(_Array_ptr<int> p : count('a')); // expected-error {{conflicting parameter bounds}}
extern int f1_8(int* _Array p _Count('a')); // expected-error {{conflicting parameter bounds}}
// Floating-point constants,
@ -76,7 +80,7 @@ extern int f3_1(_Array_ptr<int> p : count((int) 0.0F));
extern int f3_2(_Array_ptr<int> p : count((int) 5.0f));
extern int f3_2(_Array_ptr<int> p : count((int) 5.0f));
extern int f3_2(_Array_ptr<int> p : count((int) 5.0F));
extern int f3_2(_Array_ptr<int> p : count((int) 5.0F));
extern int f3_2(int* _Array p _Count((int) 5.0F));
// Inequality of floating point constants with type float.
extern int f4_1(_Array_ptr<int> p : count((int) 0.0f));
@ -84,14 +88,14 @@ extern int f4_1(_Array_ptr<int> p : count((int) 5.0f)); // expected-error {{con
extern int f4_2(_Array_ptr<int> p : count((int) 0.0F));
extern int f4_2(_Array_ptr<int> p : count((int) 5.0F)); // expected-error {{conflicting parameter bounds}}
extern int f4_3(_Array_ptr<int> p : count((int) 0.0f));
extern int f4_3(_Array_ptr<int> p : count((int) 5.0F)); // expected-error {{conflicting parameter bounds}}
extern int f4_3(int* _Array p _Count((int) 5.0F)); // expected-error {{conflicting parameter bounds}}
// Inequality of floating point constants with type float and type double.
extern int f5_1(_Array_ptr<int> p : count((int) 0.0));
extern int f5_1(_Array_ptr<int> p : count((int) 0.0f)); // expected-error {{conflicting parameter bounds}}
extern int f5_2(_Array_ptr<int> p : count((int) 0.0));
extern int f5_2(_Array_ptr<int> p : count((int) 0.0F)); // expected-error {{conflicting parameter bounds}}
extern int f5_2(int* _Array p _Count((int) 0.0F)); // expected-error {{conflicting parameter bounds}}
// Equality of floating point constants with type long double.
extern int f6_1(_Array_ptr<int> p : count((int) 0.0l));
@ -99,7 +103,7 @@ extern int f6_1(_Array_ptr<int> p : count((int) 1.0l)); // expected-error {{con
extern int f6_2(_Array_ptr<int> p : count((int) 0.0l));
extern int f6_2(_Array_ptr<int> p : count((int) 5.0L)); // expected-error {{conflicting parameter bounds}}
extern int f6_3(_Array_ptr<int> p : count((int) 0.0l));
extern int f6_3(_Array_ptr<int> p : count((int) 5.0l)); // expected-error {{conflicting parameter bounds}}
extern int f6_3(int* _Array p _Count((int) 5.0l)); // expected-error {{conflicting parameter bounds}}
// Inequality of floating point constants with type double and type
// long double.
@ -115,7 +119,7 @@ extern int f7_2(_Array_ptr<int> p : count((int) 0.0L)); // expected-error {{con
extern int f8_1(_Array_ptr<int> p : count((int) 0.0f));
extern int f8_1(_Array_ptr<int> p : count((int) 0.0l)); // expected-error {{conflicting parameter bounds}}
extern int f8_2(_Array_ptr<int> p : count((int) 0.0f));
extern int f8_2(_Array_ptr<int> p : count((int) 0.0L)); // expected-error {{conflicting parameter bounds}}
extern int f8_2(int* _Array p _Count((int) 0.0L)); // expected-error {{conflicting parameter bounds}}
// We omit inequality of floating point constants and integer constants. We
// insert an explicit cast for integers so that the enclosing expressions
@ -126,7 +130,7 @@ extern int f9_1(_Array_ptr<int> p : count((int) 0.0)); // expected-error {{conf
extern int f9_2(_Array_ptr<int> p : count((int) 5));
extern int f9_2(_Array_ptr<int> p : count((int) 5.0f)); // expected-error {{conflicting parameter bounds}}
extern int f9_3(_Array_ptr<int> p : count((int) 150));
extern int f9_3(_Array_ptr<int> p : count((int) 1.5e2L)); // expected-error {{conflicting parameter bounds}}
extern int f9_3(int* _Array p _Count((int) 1.5e2L)); // expected-error {{conflicting parameter bounds}}
//-----------------------------------------------------//
// Variables //
@ -141,7 +145,7 @@ extern _Array_ptr<int> arr1_1 : count(arr1_len);
// Global variable inequality.
extern _Array_ptr<int> arr1_2 : count(arr1_len);
extern _Array_ptr<int> arr1_2 : count(arr2_len); // expected-error {{variable redeclaration has conflicting bounds}}
extern int* _Array arr1_2 _Count(arr2_len); // expected-error {{variable redeclaration has conflicting bounds}}
// Parameter variable equality. Positions of arguments matter, not
// variable names.
@ -152,7 +156,7 @@ extern int f20_2(int d, _Array_ptr<int> arr1 : count(d));
// Parameter variable inequality.
extern int f20_3(_Array_ptr<int> arr1 : count(a), int a, int b);
extern int f20_3(_Array_ptr<int> arr1 : count(b), int a, int b); // expected-error {{conflicting parameter bounds}}
extern int f20_3(int* _Array arr1 _Count(b), int a, int b); // expected-error {{conflicting parameter bounds}}
// We can't check parameter variable vs. global variable inequality just
// using redeclarations of functions. Parameter bounds can only refer to
@ -165,7 +169,7 @@ extern _Array_ptr<int> arr1_3 : count(arr1_len); // expected-error {{variable re
// Parameter variable vs. constant inequality.
extern int f21_1(_Array_ptr<int> arr1 : count(len), int len);
extern int f21_1(_Array_ptr<int> arr1 : count(5), int len); // expected-error {{conflicting parameter bounds}}
extern int f21_1(int* _Array arr1 _Count(5), int len); // expected-error {{conflicting parameter bounds}}
//-----------------------------------------------------//
// Unary operator expressions. //
@ -189,8 +193,8 @@ extern int f30_6(int a, _Array_ptr<int> p : count(!a));
extern int f30_6(int a, _Array_ptr<int> p : count(!a));
extern int f30_7(int a, _Array_ptr<int> p : byte_count(sizeof(a)));
extern int f30_7(int a, _Array_ptr<int> p : byte_count(sizeof(a)));
extern int f30_8(int a, _Array_ptr<int> p : byte_count(sizeof(int[2])));
extern int f30_8(int a, _Array_ptr<int> p : byte_count(sizeof(int[2])));
extern int f30_8(int a, int* _Array p _Byte_count(sizeof(int[2])));
extern int f30_8(int a, int* _Array p _Byte_count(sizeof(int[2])));
// Inequality of integer unary operator expressions. The argument expression
// and enclosing expression are identical; only the operators
@ -222,8 +226,8 @@ extern int f31_8(_Array_ptr<int> p : count(sizeof(a)), int a);
extern int f31_8(_Array_ptr<int> p : count(+a), int a); // expected-error {{conflicting parameter bounds}}
extern int f31_9(_Array_ptr<int> p : count(sizeof(a)), int a);
extern int f31_9(_Array_ptr<int> p : count(~a), int a); // expected-error {{conflicting parameter bounds}}
extern int f31_10(_Array_ptr<int> p : count(sizeof(a)), int a);
extern int f31_10(_Array_ptr<int> p : count(!a), int a); // expected-error {{conflicting parameter bounds}}
extern int f31_10(int* _Array p _Count(sizeof(a)), int a);
extern int f31_10(int* _Array p _Count(!a), int a); // expected-error {{conflicting parameter bounds}}
// inequality of sizeof(expression) vs. size(type).
extern int f31_11(int a, _Array_ptr<int> p : byte_count(sizeof(a)));
@ -234,8 +238,8 @@ extern int f32_1(int a, _Array_ptr<int> p : bounds(&arr4[5], &arr4[50]));
extern int f32_1(int a, _Array_ptr<int> p : bounds(&arr4[6], &arr4[50])); // expected-error {{conflicting parameter bounds}}
// Inequality of dereference expressions
extern int f32_2(_Ptr<int> plen, _Array_ptr<int> p : count(*plen), _Ptr<int> slen);
extern int f32_2(_Ptr<int> plen, _Array_ptr<int> p : count(*slen), _Ptr<int> slen); // expected-error {{conflicting parameter bounds}}
extern int f32_2(int* _Single plen, int* _Array p _Count(*plen), int* _Single slen);
extern int f32_2(int* _Single plen, int* _Array p _Count(*slen), int* _Single slen); // expected-error {{conflicting parameter bounds}}
// Inequality of dereference expressions vs. other unary operators
extern int f32_3(_Ptr<int> plen, _Array_ptr<int> p : count(*plen), int slen);
@ -249,7 +253,7 @@ extern int f32_5(_Array_ptr<int> p : count((int) (5.0)), int a); // expected-er
// Inequality of unary operator expressions and variables.
extern int f32_6(_Array_ptr<int> p : count(!a), int a);
extern int f32_6(_Array_ptr<int> p : count(a), int a); // expected-error {{conflicting parameter bounds}}
extern int f32_6(int* _Array p _Count(a), int a); // expected-error {{conflicting parameter bounds}}
//-----------------------------------------------------//
// Binary operator expressions. //
@ -263,7 +267,7 @@ extern int f40_1(int a, int b, _Array_ptr<int> p : count(a * b));
extern int f40_2(int a, int b, _Array_ptr<int> p : count(a / b));
extern int f40_2(int a, int b, _Array_ptr<int> p : count(a / b));
extern int f40_3(int a, int b, _Array_ptr<int> p : count(a % b));
extern int f40_3(int a, int b, _Array_ptr<int> p : count(a % b));
extern int f40_3(int a, int b, int* _Array p _Count(a % b));
// Additive operators.
extern int f40_4(int a, int b, _Array_ptr<int> p : count(a + b));
@ -275,7 +279,7 @@ extern int f40_5(int a, int b, _Array_ptr<int> p : count(a - b));
extern int f40_6(int a, int b, _Array_ptr<int> p : count(a << b));
extern int f40_6(int a, int b, _Array_ptr<int> p : count(a << b));
extern int f40_7(int a, int b, _Array_ptr<int> p : count(a >> b));
extern int f40_7(int a, int b, _Array_ptr<int> p : count(a >> b));
extern int f40_7(int a, int b, int* _Array p _Count(a >> b));
// Relational operators.
extern int f41_1(int a, int b, _Array_ptr<int> p : count(a < b));
@ -285,13 +289,13 @@ extern int f41_2(int a, int b, _Array_ptr<int> p : count(a > b));
extern int f41_3(int a, int b, _Array_ptr<int> p : count(a <= b));
extern int f41_3(int a, int b, _Array_ptr<int> p : count(a <= b));
extern int f41_4(int a, int b, _Array_ptr<int> p : count(a >= b));
extern int f41_4(int a, int b, _Array_ptr<int> p : count(a >= b));
extern int f41_4(int a, int b, int* _Array p _Count(a >= b));
// Equality operators.
extern int f41_5(int a, int b, _Array_ptr<int> p : count(a == b));
extern int f41_5(int a, int b, _Array_ptr<int> p : count(a == b));
extern int f41_6(int a, int b, _Array_ptr<int> p : count(a != b));
extern int f41_6(int a, int b, _Array_ptr<int> p : count(a != b));
extern int f41_6(int a, int b, int* _Array p _Count(a != b));
// Bitwise operators.
extern int f41_7(int a, int b, _Array_ptr<int> p : count(a & b));
@ -312,8 +316,8 @@ extern int f43_1(int a, _Array_ptr<int> b, _Array_ptr<int> p : bounds(b, b + a))
extern int f43_1(int a, _Array_ptr<int> b, _Array_ptr<int> p : bounds(b, b + a));
extern int f43_2(int a, _Array_ptr<int> b, _Array_ptr<int> p : bounds(b - a, b));
extern int f43_2(int a, _Array_ptr<int> b, _Array_ptr<int> p : bounds(b - a, b));
extern int f43_3(_Array_ptr<int> a, _Array_ptr<int> b, _Array_ptr<int> p : count(b - a));
extern int f43_3(_Array_ptr<int> a, _Array_ptr<int> b, _Array_ptr<int> p : count(b - a));
extern int f43_3(int* _Array a, int* _Array b, int* _Array p _Count(b - a));
extern int f43_3(int* _Array a, int* _Array b, int* _Array p _Count(b - a));
// Inequality of binary operators on integers.
//
@ -324,7 +328,7 @@ extern int f43_3(_Array_ptr<int> a, _Array_ptr<int> b, _Array_ptr<int> p : count
#define TESTOP /
#define FUNC(index) NAME(50, index)
extern int FUNC(1)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(1)(int a, int b, int* _Array p _Count(a TESTOP b));
extern int FUNC(1)(int a, int b, _Array_ptr<int> p : count(a * b)); // expected-error {{conflicting parameter bounds}}
// Remainder vs. prior binary operators.
@ -351,7 +355,7 @@ extern int FUNC(1)(int a, int b, _Array_ptr<int> p : count(a * b)); // expected
extern int FUNC(2)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(2)(int a, int b, _Array_ptr<int> p : count(a / b)); // expected-error {{conflicting parameter bounds}}
extern int FUNC(3)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(3)(int a, int b, int* _Array p _Count(a TESTOP b));
extern int FUNC(3)(int a, int b, _Array_ptr<int> p : count(a % b)); // expected-error {{conflicting parameter bounds}}
// Minus vs. prior binary operators.
@ -369,7 +373,7 @@ extern int FUNC(2)(int a, int b, _Array_ptr<int> p : count(a / b)); // expected
extern int FUNC(3)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(3)(int a, int b, _Array_ptr<int> p : count(a % b)); // expected-error {{conflicting parameter bounds}}
extern int FUNC(4)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(4)(int a, int b, int* _Array p _Count(a TESTOP b));
extern int FUNC(4)(int a, int b, _Array_ptr<int> p : count(a + b)); // expected-error {{conflicting parameter bounds}}
// << vs. prior binary operators
@ -390,8 +394,8 @@ extern int FUNC(3)(int a, int b, _Array_ptr<int> p : count(a % b)); // expected
extern int FUNC(4)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(4)(int a, int b, _Array_ptr<int> p : count(a + b)); // expected-error {{conflicting parameter bounds}}
extern int FUNC(5)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(5)(int a, int b, _Array_ptr<int> p : count(a - b)); // expected-error {{conflicting parameter bounds}}
extern int FUNC(5)(int a, int b, int* _Array p _Count(a TESTOP b));
extern int FUNC(5)(int a, int b, int* _Array p _Count(a - b)); // expected-error {{conflicting parameter bounds}}
// >> vs. prior binary operators
#undef TESTOP
@ -414,8 +418,8 @@ extern int FUNC(4)(int a, int b, _Array_ptr<int> p : count(a + b)); // expected
extern int FUNC(5)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(5)(int a, int b, _Array_ptr<int> p : count(a - b)); // expected-error {{conflicting parameter bounds}}
extern int FUNC(6)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(6)(int a, int b, _Array_ptr<int> p : count(a << b)); // expected-error {{conflicting parameter bounds}}
extern int FUNC(6)(int a, int b, int* _Array p _Count(a TESTOP b));
extern int FUNC(6)(int a, int b, int* _Array p _Count(a << b)); // expected-error {{conflicting parameter bounds}}
// < vs. prior binary operators
#undef TESTOP
@ -875,8 +879,8 @@ extern int FUNC(14)(int a, int b, _Array_ptr<int> p : count(a ^ b)); // expecte
extern int FUNC(15)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(15)(int a, int b, _Array_ptr<int> p : count(a | b)); // expected-error {{conflicting parameter bounds}}
extern int FUNC(15)(int a, int b, _Array_ptr<int> p : count(a TESTOP b));
extern int FUNC(15)(int a, int b, _Array_ptr<int> p : count(a && b)); // expected-error {{conflicting parameter bounds}}
extern int FUNC(15)(int a, int b, int* _Array p _Count(a TESTOP b));
extern int FUNC(15)(int a, int b, int* _Array p _Count(a && b)); // expected-error {{conflicting parameter bounds}}
// Additive pointer operators.
extern int f67_1(int a, int b, _Array_ptr<int> p : bounds(p, p + a));
@ -906,7 +910,7 @@ extern int f80_1(int a, _Array_ptr<int> b, _Array_ptr<char> p : bounds(b, (_Arra
extern int f80_2(int a, _Array_ptr<int> b, _Array_ptr<char> p : bounds((apint) b, (apint) b + a));
extern int f80_2(int a, _Array_ptr<int> b, _Array_ptr<char> p : bounds((apint) b, (apint) b + a));
extern int f80_2(int a, _Array_ptr<int> b, _Array_ptr<char> p : bounds((_Array_ptr<int>) b, (_Array_ptr<int>) b + a));
extern int f80_2(int a, int* _Array b, char* _Array p _Bounds((int* _Array) b, (int* _Array) b + a));
// Inequality of C-style cast operators.
// We embed the expression being varied inside another
@ -929,8 +933,8 @@ extern int f80_5(int a, _Array_ptr<int> b,
extern int f80_5(int a, _Array_ptr<int> b,
_Array_ptr<char> p : bounds(b, (_Array_ptr<int>) ((apint) b + a)));
extern int f80_5(int a, _Array_ptr<int> b,
_Array_ptr<char> p : bounds(b, (_Array_ptr<int>) ((apchar) b + a))); // expected-error {{conflicting parameter bounds}}
extern int f80_5(int a, int* _Array b,
char* _Array p _Bounds(b, (int* _Array) ((apchar) b + a))); // expected-error {{conflicting parameter bounds}}
// Inequality of C-style cast operators vs. other expressions
@ -973,7 +977,7 @@ extern int f91_2(struct S *a, _Array_ptr<int> b : count(c->f1), struct S *c);
extern int f91_2(struct S *a, _Array_ptr<int> b : count(c->f1), struct S *c);
extern int f91_3(struct S *a, _Array_ptr<int> b : count(a->f2), struct S *c);
extern int f91_3(struct S *a, _Array_ptr<int> b : count(a->f2), struct S *c);
extern int f91_3(struct S *a, int* _Array b _Count(a->f2), struct S *c);
// Inequality of member accesses
extern int f92_1(struct S a, _Array_ptr<int> b : count(a.f1));
@ -992,7 +996,7 @@ extern int f93_2(struct S *a, _Array_ptr<int> b : count(a->f1), struct S *c);
extern int f93_2(struct S *a, _Array_ptr<int> b : count(c->f1), struct S *c); // expected-error {{conflicting parameter bounds}}
extern int f93_3(struct S *a, _Array_ptr<int> b : count(a->f1), struct S *c);
extern int f93_3(struct S *a, _Array_ptr<int> b : count(c->f2), struct S *c); // expected-error {{conflicting parameter bounds}}
extern int f93_3(struct S *a, int* _Array b _Count(c->f2), struct S *c); // expected-error {{conflicting parameter bounds}}
//
// Check equality of canonicalized expressions
@ -1019,8 +1023,8 @@ extern int f201_1(int a, _Array_ptr<int> b,
extern int f201_2(int a, _Array_ptr<int> b,
_Array_ptr<char> p : bounds(b, (_Array_ptr<int>) (void *) b + a));
extern int f201_2(int a, _Array_ptr<int> b,
_Array_ptr<char> p : bounds(b, (_Array_ptr<int>) (int *) b + a));
extern int f201_2(int a, int* _Array b,
char* _Array p _Bounds(b, (int* _Array) (int *) b + a));
// Casts between signed/unsigned integers that have the same bit size.
//
@ -1043,15 +1047,15 @@ extern int f202_1(int a, _Array_ptr<int> b,
extern int f202_2(unsigned int a,
_Array_ptr<int> b, _Array_ptr<char> p : bounds(b, b + a));
extern int f202_2(unsigned int a, _Array_ptr<int> b,
_Array_ptr<char> p : bounds(b, b + (unsigned) (int) a));
extern int f202_2(unsigned int a, int* _Array b,
char* _Array p _Bounds(b, b + (unsigned) (int) a));
// C-style casts and implicit casts to/from the same types.
extern int f203_1(short int a, _Array_ptr<int> b : count(a + 1));
extern int f203_1(short int a, _Array_ptr<int> b : count((int) a + 1));
extern int f203_2(short int a, _Array_ptr<int> b, _Array_ptr<char> p : bounds(b, b + a));
extern int f203_2(short int a, _Array_ptr<int> b, _Array_ptr<char> p : bounds(b, b + (int) a));
extern int f203_2(short int a, int* _Array b, char* _Array p _Bounds(b, b + (int) a));
//
// & and * operations that cancel are ignored.
@ -1073,9 +1077,9 @@ extern int f211_1(_Array_ptr<int> b : bounds(*(&arr), arr + 5));
// address-of an array does nothing at runtime However, we have to make sure
// the types are compatible.
extern int f211_2(_Array_ptr<int> b : bounds(&arr, &arr));
extern int f211_2(int* _Array b _Bounds(&arr, &arr));
extern int f211_2(_Array_ptr<int> b : bounds((int (*) _Checked[10]) arr, (int (*) _Checked[10]) arr));
extern int f211_2(_Array_ptr<int> b : bounds(&arr, (int (*) _Checked[10]) arr));
extern int f211_2(int* _Array b _Bounds(&arr, (int (*) _Checked[10]) arr));
//-----------------------------------------------------//
// Checked C bounds cast expressions. //
@ -1094,17 +1098,17 @@ extern void f212_2(_Array_ptr<char> a : bounds(_Assume_bounds_cast<_Array_ptr<in
extern void f212_3(_Array_ptr<char> a : bounds(_Assume_bounds_cast<_Array_ptr<int>>(a, count(1)), _Assume_bounds_cast<_Array_ptr<int>>(a, count(2)) + 3));
extern void f212_3(_Array_ptr<char> a : bounds(_Dynamic_bounds_cast<_Array_ptr<int>>(a, count(1)), _Assume_bounds_cast<_Array_ptr<int>>(a, count(2)) + 3)); // expected-error {{conflicting parameter bounds}}
extern void f212_4(_Array_ptr<char> a : bounds(_Dynamic_bounds_cast<_Array_ptr<int>>(a, count(1)), _Assume_bounds_cast<_Array_ptr<int>>(a, count(2)) + 3));
extern void f212_4(_Array_ptr<char> a : bounds(_Dynamic_bounds_cast<_Array_ptr<int>>(a, count(1)), _Dynamic_bounds_cast<_Array_ptr<int>>(a, count(2)) + 3)); // expected-error {{conflicting parameter bounds}}
extern void f212_4(char* _Array a _Bounds(_Dynamic_bounds_cast_M(int* _Array, a, count(1)), _Assume_bounds_cast_M(int* _Array, a, count(2)) + 3));
extern void f212_4(char* _Array a _Bounds(_Dynamic_bounds_cast_M(int* _Array, a, count(1)), _Dynamic_bounds_cast_M(int* _Array, a, count(2)) + 3)); // expected-error {{conflicting parameter bounds}}
extern void f212_5(_Array_ptr<char> a : bounds(_Dynamic_bounds_cast<_Array_ptr<int>>(a, count(1)), _Assume_bounds_cast<_Array_ptr<int>>(a, count(2)) + 3));
extern void f212_5(_Array_ptr<char> a : bounds(_Dynamic_bounds_cast<_Array_ptr<int>>(a, count(5)), _Assume_bounds_cast<_Array_ptr<int>>(a, count(2)) + 3)); // expected-error {{conflicting parameter bounds}}
extern void f212_5(char* _Array a _Bounds(_Dynamic_bounds_cast_M(int* _Array, a, count(1)), _Assume_bounds_cast_M(int* _Array, a, count(2)) + 3));
extern void f212_5(char* _Array a _Bounds(_Dynamic_bounds_cast_M(int* _Array, a, count(5)), _Assume_bounds_cast_M(int* _Array, a, count(2)) + 3)); // expected-error {{conflicting parameter bounds}}
extern void f212_6(_Array_ptr<char> a : bounds(_Dynamic_bounds_cast<_Array_ptr<int>>(a, count(1)), _Assume_bounds_cast<_Array_ptr<int>>(a, count(2)) + 3));
extern void f212_6(_Array_ptr<char> a : bounds(_Dynamic_bounds_cast<_Array_ptr<int>>(a, count(1)), _Assume_bounds_cast<_Array_ptr<int>>(a, bounds(a, a + 2)) + 3)); // expected-error {{conflicting parameter bounds}}
extern void f212_6(char* _Array a _Bounds(_Dynamic_bounds_cast_M(int* _Array, a, count(1)), _Assume_bounds_cast_M(int* _Array, a, count(2)) + 3));
extern void f212_6(char* _Array a _Bounds(_Dynamic_bounds_cast_M(int* _Array, a, count(1)), _Assume_bounds_cast_M(int* _Array, a, bounds(a, a + 2)) + 3)); // expected-error {{conflicting parameter bounds}}
extern void f212_7(_Array_ptr<char> a : bounds(_Dynamic_bounds_cast<_Array_ptr<int>>(b, count(1)), b + 3), _Array_ptr<int> b : count(1));
extern void f212_7(_Array_ptr<char> a : bounds(b, b + 3), _Array_ptr<int> b : count(1)); // expected-error {{conflicting parameter bounds}}
extern void f212_7(char* _Array a _Bounds(_Dynamic_bounds_cast_M(int* _Array, b, count(1)), b + 3), int* _Array b _Count(1));
extern void f212_7(char* _Array a _Bounds(b, b + 3), int* _Array b _Count(1)); // expected-error {{conflicting parameter bounds}}
extern void f212_8(_Array_ptr<char> a : bounds(b, _Assume_bounds_cast<_Array_ptr<int>>(b, count(1)) + 3), _Array_ptr<int> b : count(1));
extern void f212_8(_Array_ptr<char> a : bounds(b, b + 3), _Array_ptr<int> b : count(1)); // expected-error {{conflicting parameter bounds}}
extern void f212_8(char* _Array a _Bounds(b, _Assume_bounds_cast_M(int* _Array, b, count(1)) + 3), int* _Array b _Count(1));
extern void f212_8(char* _Array a _Bounds(b, b + 3), int* _Array b _Count(1)); // expected-error {{conflicting parameter bounds}}

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

@ -36,7 +36,7 @@ void f1(int i, int* loc) {
array_ptr<int> as2a : count(i -= 1) = 0; // expected-error {{assignment expression not allowed in count expression}}
array_ptr<int> as2b : byte_count(i -= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}}
array_ptr<int> as2c : bounds(loc -= 1, loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as2d : bounds(loc, loc -= 1) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
int* _Array as2d _Bounds(loc, loc -= 1) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as3a : count(i *= 1) = 0; // expected-error {{assignment expression not allowed in count expression}}
array_ptr<int> as3b : byte_count(i *= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}}
@ -46,7 +46,7 @@ void f1(int i, int* loc) {
array_ptr<int> as4a : count(i /= 1) = 0; // expected-error {{assignment expression not allowed in count expression}}
array_ptr<int> as4b : byte_count(i /= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}}
array_ptr<int> as4c : bounds(loc + (i /= 1), loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as4d : bounds(loc, loc + (i /= 1)) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
int* _Array as4d _Bounds(loc, loc + (i /= 1)) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as5a : count(i %= 1) = 0; // expected-error {{assignment expression not allowed in count expression}}
array_ptr<int> as5b : byte_count(i %= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}}
@ -56,7 +56,7 @@ void f1(int i, int* loc) {
array_ptr<int> as6a : count(i <<= 1) = 0; // expected-error {{assignment expression not allowed in count expression}}
array_ptr<int> as6b : byte_count(i <<= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}}
array_ptr<int> as6c : bounds(loc + (i <<= 1), loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as6d : bounds(loc, loc + (i <<= 1)) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
int* _Array as6d _Bounds(loc, loc + (i <<= 1)) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as7a : count(i >>= 1) = 0; // expected-error {{assignment expression not allowed in count expression}}
array_ptr<int> as7b : byte_count(i >>= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}}
@ -66,7 +66,7 @@ void f1(int i, int* loc) {
array_ptr<int> as8a : count(i &= 1) = 0; // expected-error {{assignment expression not allowed in count expression}}
array_ptr<int> as8b : byte_count(i &= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}}
array_ptr<int> as8c : bounds(loc + (i &= 1), loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as8d : bounds(loc, loc + (i &= 1)) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
int* _Array as8d _Bounds(loc, loc + (i &= 1)) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as9a : count(i ^= 1) = 0; // expected-error {{assignment expression not allowed in count expression}}
array_ptr<int> as9b : byte_count(i ^= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}}
@ -75,8 +75,8 @@ void f1(int i, int* loc) {
array_ptr<int> as10a : count(i |= 1) = 0; // expected-error {{assignment expression not allowed in count expression}}
array_ptr<int> as10b : byte_count(i |= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}}
array_ptr<int> as10c : bounds(loc + (i |= 1), loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as10d : bounds(loc, loc + (i|= 1)) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
int* _Array as10c _Bounds(loc + (i |= 1), loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
int* _Array as10d _Bounds(loc, loc + (i|= 1)) = 0; // expected-error {{assignment expression not allowed in bounds expression}}
array_ptr<int> as11a : count(i++) = 0; // expected-error {{increment expression not allowed in count expression}}
array_ptr<int> as11b : byte_count(i++) = 0; // expected-error {{increment expression not allowed in byte count expression}}
@ -85,8 +85,8 @@ void f1(int i, int* loc) {
array_ptr<int> as12a : count(++i) = 0; // expected-error {{increment expression not allowed in count expression}}
array_ptr<int> as12b : byte_count(++i) = 0; // expected-error {{increment expression not allowed in byte count expression}}
array_ptr<int> as12c : bounds(++loc, loc) = 0; // expected-error {{increment expression not allowed in bounds expression}}
array_ptr<int> as12d : bounds(loc, ++loc) = 0; // expected-error {{increment expression not allowed in bounds expression}}
int* _Array as12c _Bounds(++loc, loc) = 0; // expected-error {{increment expression not allowed in bounds expression}}
int* _Array as12d _Bounds(loc, ++loc) = 0; // expected-error {{increment expression not allowed in bounds expression}}
array_ptr<int> as13a : count(i--) = 0; // expected-error {{decrement expression not allowed in count expression}}
array_ptr<int> as13b : byte_count(i--) = 0; // expected-error {{decrement expression not allowed in byte count expression}}
@ -95,8 +95,8 @@ void f1(int i, int* loc) {
array_ptr<int> as14a : count(--i) = 0; // expected-error {{decrement expression not allowed in count expression}}
array_ptr<int> as14b : byte_count(--i) = 0; // expected-error {{decrement expression not allowed in byte count expression}}
array_ptr<int> as14c : bounds(--loc, loc) = 0; // expected-error {{decrement expression not allowed in bounds expression}}
array_ptr<int> as14d : bounds(loc, --loc) = 0; // expected-error {{decrement expression not allowed in bounds expression}}
int* _Array as14c _Bounds(--loc, loc) = 0; // expected-error {{decrement expression not allowed in bounds expression}}
int* _Array as14d _Bounds(loc, --loc) = 0; // expected-error {{decrement expression not allowed in bounds expression}}
array_ptr<int> as15a : count(f0int()) = 0; // expected-error {{call expression not allowed in count expression}}
array_ptr<int> as15b : byte_count(f0int()) = 0; // expected-error {{call expression not allowed in byte count expression}}
@ -105,8 +105,8 @@ void f1(int i, int* loc) {
array_ptr<int> as16a : count(f0int() + 1) = 0; // expected-error {{call expression not allowed in count expression}}
array_ptr<int> as16b : byte_count(f0int() + 1) = 0; // expected-error {{call expression not allowed in byte count expression}}
array_ptr<int> as16c : bounds(f0ptr() + 1, loc) = 0; // expected-error {{call expression not allowed in bounds expression}}
array_ptr<int> as16d : bounds(loc, f0ptr() + 1) = 0; // expected-error {{call expression not allowed in bounds expression}}
int* _Array as16c _Bounds(f0ptr() + 1, loc) = 0; // expected-error {{call expression not allowed in bounds expression}}
int* _Array as16d _Bounds(loc, f0ptr() + 1) = 0; // expected-error {{call expression not allowed in bounds expression}}
array_ptr<int> as17a : count(j) = 0; // expected-error {{volatile expression not allowed in count expression}}
array_ptr<int> as17b : byte_count(j) = 0; // expected-error {{volatile expression not allowed in byte count expression}}
@ -115,8 +115,8 @@ void f1(int i, int* loc) {
array_ptr<int> as18a : count(i + j) = 0; // expected-error {{volatile expression not allowed in count expression}}
array_ptr<int> as18b : byte_count(i + j) = 0; // expected-error {{volatile expression not allowed in byte count expression}}
array_ptr<int> as18c : bounds(loc + (i + j), loc) = 0; // expected-error {{volatile expression not allowed in bounds expression}}
array_ptr<int> as18d : bounds(loc, loc + (i + j)) = 0; // expected-error {{volatile expression not allowed in bounds expression}}
int* _Array as18c _Bounds(loc + (i + j), loc) = 0; // expected-error {{volatile expression not allowed in bounds expression}}
int* _Array as18d _Bounds(loc, loc + (i + j)) = 0; // expected-error {{volatile expression not allowed in bounds expression}}
}
// Expressions explicitly allowed by spec within Non-Modifying Expressions
@ -149,8 +149,8 @@ void f2(int i, int* loc) {
array_ptr<int> as4a : count(&i == &j) = 0;
array_ptr<int> as4b : byte_count(&i == &j) = 0;
array_ptr<int> as4c : bounds(&i, loc) = 0;
array_ptr<int> as4d : bounds(loc, &i) = 0;
int* _Array as4c _Bounds(&i, loc) = 0;
int* _Array as4d _Bounds(loc, &i) = 0;
array_ptr<int> as5a : count(*pi) = 0;
array_ptr<int> as5b : byte_count(*pi) = 0;
@ -159,33 +159,33 @@ void f2(int i, int* loc) {
array_ptr<int> as6a : count((int)'a') = 0;
array_ptr<int> as6b : byte_count((int)'a') = 0;
array_ptr<int> as6c : bounds((int*)0, loc) = 0;
array_ptr<int> as6d : bounds(loc, (int*)0) = 0;
int* _Array as6c _Bounds((int*)0, loc) = 0;
int* _Array as6d _Bounds(loc, (int*)0) = 0;
array_ptr<int> as7a : count(+i) = 0;
array_ptr<int> as7b : byte_count(+i) = 0;
array_ptr<int> as7c : bounds(loc + (+i), loc) = 0;
array_ptr<int> as7d : bounds(loc, loc + (+i)) = 0;
int* _Array as7d _Bounds(loc, loc + (+i)) = 0;
array_ptr<int> as8a : count(-i) = 0;
array_ptr<int> as8b : byte_count(-i) = 0;
array_ptr<int> as8c : bounds(loc + -i, loc) = 0;
array_ptr<int> as8d : bounds(loc, loc + -i) = 0;
int* _Array as8d _Bounds(loc, loc + -i) = 0;
array_ptr<int> as9a : count(~i) = 0;
array_ptr<int> as9b : byte_count(~i) = 0;
array_ptr<int> as9c : bounds(loc + ~i, loc) = 0;
array_ptr<int> as9d : bounds(loc, loc + ~i) = 0;
int* _Array as9d _Bounds(loc, loc + ~i) = 0;
array_ptr<int> as10a : count(!i) = 0;
array_ptr<int> as10b : byte_count(!i) = 0;
array_ptr<int> as10c : bounds(loc + !i, loc) = 0;
array_ptr<int> as10d : bounds(loc, loc + !i) = 0;
int* _Array as10c _Bounds(loc + !i, loc) = 0;
int* _Array as10d _Bounds(loc, loc + !i) = 0;
array_ptr<int> as11a : count(sizeof(i)) = 0;
array_ptr<int> as11b : byte_count(sizeof(i)) = 0;
array_ptr<int> as11c : bounds(loc + sizeof(loc), loc) = 0;
array_ptr<int> as11d : bounds(loc, loc + sizeof(loc)) = 0;
int* _Array as11d _Bounds(loc, loc + sizeof(loc)) = 0;
array_ptr<int> as12a : count(i * 1 / 1 % 1) = 0;
array_ptr<int> as12b : byte_count(i * 1 / 1 % 1) = 0;
@ -195,7 +195,7 @@ void f2(int i, int* loc) {
array_ptr<int> as13a : count(i + 1 - 1) = 0;
array_ptr<int> as13b : byte_count(i + 1 - 1) = 0;
array_ptr<int> as13c : bounds(loc + 1 - 1, loc) = 0;
array_ptr<int> as13d : bounds(loc, loc + 1 - 1) = 0;
int* _Array as13d _Bounds(loc, loc + 1 - 1) = 0;
array_ptr<int> as14a : count(i << 1 >> 1) = 0;
array_ptr<int> as14b : byte_count(i << 1 >> 1) = 0;
@ -203,7 +203,7 @@ void f2(int i, int* loc) {
array_ptr<int> as14d : bounds(loc, loc + (i << 1 >> 1)) = 0;
array_ptr<int> as15a : count(i < j) = 0;
array_ptr<int> as15b : byte_count(i < j) = 0;
int* _Array as15b _Byte_count(i < j) = 0;
array_ptr<int> as16a : count(i > j) = 0;
array_ptr<int> as16b : byte_count(i > j) = 0;
@ -212,12 +212,12 @@ void f2(int i, int* loc) {
array_ptr<int> as17b : byte_count(i <= j) = 0;
array_ptr<int> as18a : count(i >= j) = 0;
array_ptr<int> as18b : byte_count(i >= j) = 0;
int* _Array as18b _Byte_count(i >= j) = 0;
array_ptr<int> as19a : count(i == j) = 0;
array_ptr<int> as19b : byte_count(i == j) = 0;
array_ptr<int> as19c : bounds(loc + (loc == loc2), loc) = 0;
array_ptr<int> as19d : bounds(loc, loc + (loc == loc2)) = 0;
int* _Array as19d _Bounds(loc, loc + (loc == loc2)) = 0;
array_ptr<int> as20a : count(i & j) = 0;
array_ptr<int> as20b : byte_count(i & j) = 0;
@ -236,8 +236,8 @@ void f2(int i, int* loc) {
array_ptr<int> as25a : count(i ? j : 0) = 0;
array_ptr<int> as25b : byte_count(i ? j : 0) = 0;
array_ptr<int> as25c : bounds(i ? loc : loc2, loc) = 0;
array_ptr<int> as25d : bounds(loc, i ? loc : loc2) = 0;
int* _Array as25c _Bounds(i ? loc : loc2, loc) = 0;
int* _Array as25d _Bounds(loc, i ? loc : loc2) = 0;
array_ptr<int> as26a : count(u1.m1) = 0;
array_ptr<int> as26b : byte_count(u1.m1) = 0;
@ -247,12 +247,12 @@ void f2(int i, int* loc) {
array_ptr<int> as27a : count(s1.m1) = 0;
array_ptr<int> as27b : byte_count(s1.m1) = 0;
array_ptr<int> as27c : bounds(s1.m2, loc) = 0;
array_ptr<int> as27d : bounds(loc, s1.m2) = 0;
int* _Array as27d _Bounds(loc, s1.m2) = 0;
array_ptr<int> as28a : count(ps1->m1) = 0;
array_ptr<int> as28b : byte_count(ps1->m1) = 0;
array_ptr<int> as28c : bounds(ps1->m2, loc) = 0;
array_ptr<int> as28d : bounds(loc, ps1->m2) = 0;
int* _Array as28d _Bounds(loc, ps1->m2) = 0;
}
@ -270,7 +270,7 @@ void f3(void) {
// TODO: this will eventually be allowed when we add support for current_expr_value.
(arr[i++]).p = 0; // expected-error {{contain a modifying expression}}
// TODO: this will eventually be allowed when we add support for current_expr_value.
array_ptr<int> a : count(5) = arr[i++].p; // expected-error {{contain a modifying expression}}
int* _Array a _Count(5) = arr[i++].p; // expected-error {{contain a modifying expression}}
// TODO: this will eventually be allowed when we add support for current_expr_value.
f3_helper(arr[i++].p); // expected-error {{contain a modifying expression}}
}
@ -295,7 +295,7 @@ void f5(void) {
int i = 0;
ptr<int> p = &i;
array_ptr<ptr<int>> r : count(1) = &p;
array_ptr<ptr<int>> s : count(1) = &p;
int* _Single *_Array s _Count(1) = &p;
// TODO: this will eventually be allowed when we add support for current_expr_value.
_Array_ptr<int> t : count(1) = *(r = s); // expected-error {{contain a modifying expression}}
// TODO: this will eventually be allowed when we add support for current_expr_value.

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

@ -12,16 +12,16 @@ extern void f1() {
int b[10];
int *p = 0;
array_ptr<int> checkedc_p : bounds(checkedc_p, checkedc_p + 1) = 0;
int* _Array checkedc_p : bounds(checkedc_p, checkedc_p + 1) = 0;
c = _Dynamic_bounds_cast<ptr<int>>(p); // expected-error {{expression has unknown bounds}}
c = _Dynamic_bounds_cast<ptr<int>>(p); // expected-error {{expression has unknown bounds}}
a = _Assume_bounds_cast<array_ptr<int>>(p, count(4));
checkedc_p = _Assume_bounds_cast<array_ptr<int>>(p, bounds(p, p + 1));
checkedc_p = _Dynamic_bounds_cast<array_ptr<int>>(p, bounds(p, p + 1)); // expected-error {{expression has unknown bounds}}
a = _Assume_bounds_cast<array_ptr<int>>(p, count(1));
a = _Assume_bounds_cast<int* _Array>(p, count(1));
a = _Assume_bounds_cast<array_ptr<int>>(p, bounds(p, p + 1));
array_ptr<int> d = _Assume_bounds_cast<array_ptr<int>>(p, count(4));
c = _Dynamic_bounds_cast<ptr<int>>(p); // expected-error {{expression has unknown bounds}}
c = _Dynamic_bounds_cast<int* _Single>(p); // expected-error {{expression has unknown bounds}}
}
struct S1 {
@ -31,7 +31,7 @@ struct S1 {
} pair;
array_ptr<int> arr1 : bounds(pair.lower, pair.upper);
struct {
array_ptr<int> arr2 : bounds(pair.lower, pair.upper);
int* _Array arr2 : bounds(pair.lower, pair.upper);
} nested;
};
@ -52,8 +52,8 @@ extern void f3() {
p = _Dynamic_bounds_cast<int *>(r); // expected-error {{expression has unknown bounds}}
q = _Assume_bounds_cast<ptr<int>>(p);
q = _Dynamic_bounds_cast<ptr<int>>(p); // expected-error {{expression has unknown bounds}}
q = _Dynamic_bounds_cast<ptr<int>>(r); // expected-error {{expression has unknown bounds}}
q = _Dynamic_bounds_cast<ptr<int>>(r) + 3; // expected-error{{arithmetic on _Ptr type}}
q = _Dynamic_bounds_cast_M_N(int* _Single, r); // expected-error {{expression has unknown bounds}}
q = _Dynamic_bounds_cast_M_N(int* _Single, r) + 3; // expected-error{{arithmetic on _Ptr type}}
*(_Assume_bounds_cast<ptr<int>>(r) + 2) = 4; // expected-error{{arithmetic on _Ptr type}}
// For the statement below, the compiler figures out that r + 2 is out of bounds r : count(1).
@ -63,7 +63,7 @@ extern void f3() {
// t : count(3) normals to bounds(t, t + 3), and t[3] is out of that range.
int n = (_Dynamic_bounds_cast<array_ptr<int>>(t, count(3)))[3]; // expected-error {{out-of-bounds memory access}}
s1 = _Dynamic_bounds_cast<array_ptr<int>>(p, count(5)); // expected-error {{expression has unknown bounds}}
s2 = _Assume_bounds_cast<array_ptr<int>>(r, count(5));
s2 = _Assume_bounds_cast<int* _Array>(r, count(5));
}
extern ptr<int> f4(int arr checked[]) {
@ -83,7 +83,7 @@ checked int *f5(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s: count(2)
int b checked[5][5];
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
b[i][j] += *q + *(_Dynamic_bounds_cast<array_ptr<int>>(r, count(1))); // expected-error {{expression has unknown bounds}}
b[i][j] += *q + *(_Dynamic_bounds_cast<int* _Array>(r, count(1))); // expected-error {{expression has unknown bounds}}
}
}
}
@ -143,8 +143,8 @@ extern void f18(int i) {
r = _Dynamic_bounds_cast<array_ptr<int>>(p, count(1)); // expected-error {{expression has unknown bounds}} expected-error {{declared bounds for 'r' are invalid after assignment}}
r = _Dynamic_bounds_cast<array_ptr<int>>(p, bounds(p, p + 1)); // expected-error {{expression has unknown bounds}} expected-error {{declared bounds for 'r' are invalid after assignment}}
r = _Dynamic_bounds_cast<array_ptr<int>>(i, count(5)); // expected-error {{expression has unknown bounds}}
r = _Dynamic_bounds_cast<array_ptr<int>>(i, bounds(i, i + 1)); // expected-error 2 {{expected expression with pointer}}
r = _Dynamic_bounds_cast<int* _Array>(i, count(5)); // expected-error {{expression has unknown bounds}}
r = _Dynamic_bounds_cast<int* _Array>(i, bounds(i, i + 1)); // expected-error 2 {{expected expression with pointer}}
int len;
@ -185,7 +185,7 @@ extern void f19(){
x = _Dynamic_bounds_cast<array_ptr<int>>(b, bounds(p, p + 1)); // expected-error {{to have a pointer}}
x = _Dynamic_bounds_cast<array_ptr<int>>(p, count(b)); // expected-error {{invalid argument type}}
x = _Dynamic_bounds_cast<array_ptr<int>>(p, bounds(p, 1)); // expected-error {{expected expression with}}
x = _Dynamic_bounds_cast<int* _Array>(p, bounds(p, 1)); // expected-error {{expected expression with}}
x = _Dynamic_bounds_cast<array_ptr<int>>(p, bounds(p, p + 1)); // expected-error {{declared bounds for 'x' are invalid after assignment}}
}
@ -206,7 +206,7 @@ extern void f20(void *p) {
}
extern void f21(array_ptr<char> buf : count(len), int len) {
array_ptr<int> intbuf : count(12) = _Dynamic_bounds_cast<array_ptr<int>>(buf, bounds(intbuf, intbuf + 12));
int* _Array intbuf _Count(12) = _Dynamic_bounds_cast<int* _Array>(buf, bounds(intbuf, intbuf + 12));
int i = intbuf[12]; // expected-error {{out-of-bounds memory access}} \
// expected-note {{accesses memory at or above the upper bound}} \
// expected-note {{(expanded) inferred bounds are 'bounds(intbuf, intbuf + 12)'}}
@ -220,7 +220,7 @@ extern void f22() {
}
extern void f23() {
array_ptr<char> buf : count(10) = _Assume_bounds_cast<array_ptr<char>>(h7(), count(10));
array_ptr<char> buf _Count(10) = _Assume_bounds_cast<array_ptr<char>>(h7(), count(10));
char c = buf[10]; // expected-error {{out-of-bounds memory access}} \
// expected-note {{accesses memory at or above the upper bound}} \
// expected-note {{(expanded) inferred bounds are 'bounds(buf, buf + 10)'}}
@ -244,7 +244,7 @@ extern void f24() {
}
extern void f25(array_ptr<char> buf : count(len), int len) {
array_ptr<int> intbuf : count(6) = _Dynamic_bounds_cast<array_ptr<int>>(buf + 5, count(6));
int* _Array intbuf _Count(6) = _Dynamic_bounds_cast<int* _Array>(buf + 5, count(6));
int i = intbuf[6]; // expected-error {{out-of-bounds memory access}} \
// expected-note {{accesses memory at or above the upper bound}} \
// expected-note {{(expanded) inferred bounds are 'bounds(intbuf, intbuf + 6)'}}

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

@ -52,8 +52,8 @@ extern void count_exprs(void) {
array_ptr<int> t7 : count(c7) = 0;
array_ptr<int> t8 : count(c8) = 0;
array_ptr<int> t9 : count(c9) = 0;
array_ptr<int> t10 : count(c10) = 0;
array_ptr<int> t11 : count(c11) = 0;
int* _Array t10 _Count(c10) = 0;
int* _Array t11 _Count(c11) = 0;
// Spot-check type checking of count expressions involving file-scoped
// variables.
array_ptr<int> t12 : count(A) = 0;
@ -72,8 +72,8 @@ extern void count_exprs(void) {
array_ptr<int> t22 : byte_count(c7) = 0;
array_ptr<int> t23 : byte_count(c8) = 0;
array_ptr<int> t24 : byte_count(c9) = 0;
array_ptr<int> t25 : byte_count(c10) = 0;
array_ptr<int> t26 : byte_count(c11) = 0;
int* _Array t25 _Byte_count(c10) = 0;
int* _Array t26 _Byte_count(c11) = 0;
// Spot-check type checking of byte_count expressions involving file-scoped
// variables.
array_ptr<int> t27 : byte_count(A) = 0;
@ -93,8 +93,8 @@ extern void count_exprs(void) {
nt_array_ptr<char> t54 : byte_count(c7) = 0;
nt_array_ptr<char> t55 : byte_count(c8) = 0;
nt_array_ptr<char> t56 : byte_count(c9) = 0;
nt_array_ptr<char> t57 : byte_count(A) = 0;
char* _Nt_array t56 _Byte_count(c9) = 0;
char* _Nt_array t57 _Byte_count(A) = 0;
}
@ -114,7 +114,7 @@ extern void count_exprs_with_integral_operands(void) {
array_ptr<int> t1 : count(c1) = 0;
array_ptr<int> t2 : count(c2) = 0;
array_ptr<int> t3 : count(s.f) = 0;
nt_array_ptr<int> t4 : count(c2) = 0;
int* _Nt_array t4 _Count(c2) = 0;
}
float globalFloat = 8;
@ -153,8 +153,8 @@ extern void invalid_count_exprs(void) {
array_ptr<int> t9 : count(test_func) = 0; // expected-error {{invalid argument type}}
array_ptr<int> t10 : count(func_ptr) = 0; // expected-error {{invalid argument type}}
array_ptr<int> t11 : count("test") = 0; // expected-error {{invalid argument type}}
array_ptr<int> t12 : count(5.0f) = 0; // expected-error {{invalid argument type}}
array_ptr<int> t13 : count(globalFloat) = 0; // expected-error {{invalid argument type}}
int* _Array t12 _Count(5.0f) = 0; // expected-error {{invalid argument type}}
int* _Array t13 _Count(globalFloat) = 0; // expected-error {{invalid argument type}}
#ifndef __STDC_NO_COMPLEX__
array_ptr<int> t14 : count(c8) = 0; // expected-error {{invalid argument type}}
@ -170,8 +170,8 @@ extern void invalid_count_exprs(void) {
array_ptr<int> t22 : byte_count(s.f) = 0; // expected-error {{invalid argument type}}
array_ptr<int> t23 : byte_count(func_ptr) = 0; // expected-error {{invalid argument type}}
array_ptr<int> t24 : byte_count("test") = 0; // expected-error {{invalid argument type}}
array_ptr<int> t25 : byte_count(5.0f) = 0; // expected-error {{invalid argument type}}
array_ptr<int> t26 : byte_count(globalFloat) = 0; // expected-error {{invalid argument type}}
int* _Array t25 _Byte_count(5.0f) = 0; // expected-error {{invalid argument type}}
int* _Array t26 _Byte_count(globalFloat) = 0; // expected-error {{invalid argument type}}
#ifndef __STDC_NO_COMPLEX__
array_ptr<int> t27 : byte_count(c8) = 0; // expected-error {{invalid argument type}}
@ -200,8 +200,8 @@ extern void bounds_exprs(void) {
array_ptr<int> t5 : bounds(array_ptr_lb, unchecked_ptr_ub) = i;
array_ptr<int> t6 : bounds(ptr_lb, ptr_ub) = i;
array_ptr<int> t7 : bounds(unchecked_ptr_lb, ptr_ub) = i;
array_ptr<int> t8 : bounds(ptr_lb, unchecked_ptr_ub) = i;
array_ptr<int> t9 : bounds(unchecked_ptr_lb, unchecked_ptr_ub) = i;
int* _Array t8 _Bounds(ptr_lb, unchecked_ptr_ub) = i;
int* _Array t9 _Bounds(unchecked_ptr_lb, unchecked_ptr_ub) = i;
// spot check mixed uses of nt_array_ptr and other pointer types.
array_ptr<int> t9a : bounds(nt_array_ptr_lb, ptr_ub) = i;
@ -213,8 +213,8 @@ extern void bounds_exprs(void) {
array_ptr<int> t10 : bounds(i, i + 1) = i;
array_ptr<int> t11 : bounds(i, array_ptr_ub) = i;
array_ptr<int> t11a : bounds(i, nt_array_ptr_ub) = i;
array_ptr<int> t13 : bounds(i, ptr_ub) = i;
int* _Array t11a _Bounds(i, nt_array_ptr_ub) = i;
int* _Array t13 _Bounds(i, ptr_ub) = i;
array_ptr<void> void_array_ptr_lb = i, void_array_ptr_ub = i + 1;
ptr<void> void_ptr_lb = i, void_ptr_ub = i + 1;
@ -229,7 +229,7 @@ extern void bounds_exprs(void) {
array_ptr<int> t26 : bounds(void_ptr_lb, void_ptr_ub) = i;
array_ptr<int> t27 : bounds(void_unchecked_ptr_lb, void_ptr_ub) = i;
array_ptr<int> t28 : bounds(void_ptr_lb, void_unchecked_ptr_ub) = i;
array_ptr<int> t29 : bounds(void_unchecked_ptr_lb, void_unchecked_ptr_ub) = i;
int* _Array t29 _Bounds(void_unchecked_ptr_lb, void_unchecked_ptr_ub) = i;
// check combinations of pointers to void and pointers to non-void types
@ -240,8 +240,8 @@ extern void bounds_exprs(void) {
array_ptr<int> t46 : bounds(array_ptr_lb, void_ptr_ub) = i;
array_ptr<int> t47 : bounds(unchecked_ptr_lb, void_array_ptr_ub) = i;
array_ptr<int> t48 : bounds(void_unchecked_ptr_lb, array_ptr_ub) = i;
array_ptr<int> t49 : bounds(void_array_ptr_lb, unchecked_ptr_ub) = i;
array_ptr<int> t50 : bounds(array_ptr_lb, void_unchecked_ptr_ub) = i;
int* _Array t49 _Bounds(void_array_ptr_lb, unchecked_ptr_ub) = i;
int* _Array t50 _Bounds(array_ptr_lb, void_unchecked_ptr_ub) = i;
array_ptr<int> t51 : bounds(void_ptr_lb, ptr_ub) = i;
array_ptr<int> t52 : bounds(ptr_lb, void_ptr_ub) = i;
@ -261,8 +261,8 @@ extern void bounds_exprs(void) {
array_ptr<char> t73 : bounds(unchecked_ptr_lb, ptr_ub) = (array_ptr<char>) i;
array_ptr<char> t75 : bounds(void_array_ptr_lb, array_ptr_ub) = (array_ptr<char>) i;
array_ptr<char> t76 : bounds(void_unchecked_ptr_lb, array_ptr_ub) = (array_ptr<char>) i;
array_ptr<char> t77 : bounds(array_ptr_lb, void_unchecked_ptr_ub) = (array_ptr<char>) i;
array_ptr<char> t77a : bounds(nt_array_ptr_lb, void_unchecked_ptr_ub) = (array_ptr<char>) i;
char* _Array t77 _Bounds(array_ptr_lb, void_unchecked_ptr_ub) = (char* _Array) i;
char* _Array t77a _Bounds(nt_array_ptr_lb, void_unchecked_ptr_ub) = (char* _Array) i;
// use an array-typed value as the lower bound. This should be converted
// implicitly to be a pointer type.
@ -271,7 +271,7 @@ extern void bounds_exprs(void) {
array_ptr<char> t80 : bounds(i, nt_array_ptr_ub) = (array_ptr<char>) i;
// spot check that typechecking looks through typedefs
typedef array_ptr<int> int_array_ptr;
typedef int* _Array int_array_ptr;
typedef ptr<int> int_ptr;
typedef int *int_unchecked_ptr;
typedef nt_array_ptr<int> int_nt_array_ptr;
@ -292,7 +292,7 @@ extern void bounds_exprs(void) {
array_ptr<int> t98 : bounds(ptr_lb, typedef_unchecked_ptr_ub) = i;
array_ptr<int> t99 : bounds(typedef_unchecked_ptr_lb, unchecked_ptr_ub) = i;
array_ptr<int> t100 : bounds(typedef_nt_array_ptr_lb, unchecked_ptr_ub) = i;
array_ptr<int> t101 : bounds(typedef_array_ptr_lb, typedef_nt_array_ptr_ub) = i;
int* _Array t101 _Bounds(typedef_array_ptr_lb, typedef_nt_array_ptr_ub) = i;
// check that type qualifiers are discarded when comparing pointer types
// in bounds expressions
@ -323,7 +323,7 @@ extern void bounds_exprs(void) {
const int *unchecked_ptr_const_ub = i + 1;
const int *const const_unchecked_ptr_const_ub = i + 1;
array_ptr<int> t121 : bounds(array_ptr_const_lb, array_ptr_ub) = i;
int* _Array t121 _Bounds(array_ptr_const_lb, array_ptr_ub) = i;
array_ptr<int> t122 : bounds(const_array_ptr_lb, array_ptr_ub) = i;
array_ptr<int> t123 : bounds(const_array_ptr_const_lb, array_ptr_ub) = i;
@ -333,7 +333,7 @@ extern void bounds_exprs(void) {
array_ptr<int> t127 : bounds(const_array_ptr_lb, array_ptr_const_ub) = i;
array_ptr<int> t128 : bounds(array_ptr_const_lb, const_array_ptr_ub) = i;
array_ptr<int> t129 : bounds(const_array_ptr_const_lb, const_array_ptr_const_ub) = i;
int* _Array t129 _Bounds(const_array_ptr_const_lb, const_array_ptr_const_ub) = i;
array_ptr<int> t130 : bounds(ptr_lb, array_ptr_ub) = i;
array_ptr<int> t131 : bounds(array_ptr_lb, ptr_ub) = i;
@ -346,7 +346,7 @@ extern void bounds_exprs(void) {
// spot check const nt_array_ptr
array_ptr<int> t140 : bounds(nt_array_ptr_lb, const_nt_array_ptr_ub) = i;
array_ptr<int> t141 : bounds(const_nt_array_ptr_lb, nt_array_ptr_ub) = i;
int* _Array t141 _Bounds(const_nt_array_ptr_lb, nt_array_ptr_ub) = i;
}
extern void invalid_bounds_exprs(void) {
@ -392,7 +392,7 @@ extern void bounds_exprs(void) {
array_ptr<int> t13 : bounds(c13, c13) = 0; // expected-error 2 {{expected expression with pointer type}}
array_ptr<int> t14 : bounds(c14, c14) = 0; // expected-error 2 {{expected expression with pointer type}}
array_ptr<int> t15 : bounds(c15, c15) = 0; // expected-error 2 {{expected expression with pointer type}}
array_ptr<int> t16 : bounds(test_func, test_func) = 0; // expected-error 2 {{invalid argument type 'void (*)(void)' to bounds expression}}
int* _Array t16 _Bounds(test_func, test_func) = 0; // expected-error 2 {{invalid argument type 'void (*)(void)' to bounds expression}}
// have values with different levels of indirection
array_ptr<int> t17 : bounds(double_indir, c3) = 0; // expected-error {{expected expression with pointer type}}
@ -420,7 +420,7 @@ extern void bounds_exprs(void) {
array_ptr<int> t32 : bounds(int_unchecked_ptr_lb, char_ptr_ub) = i; // expected-error {{pointer type mismatch}}
array_ptr<char> t33 : bounds(char_array_ptr_lb, int_ptr_ub) = (array_ptr<char>) i; // expected-error {{pointer type mismatch}}
array_ptr<char> t34 : bounds(char_ptr_lb, int_ptr_ub) = (array_ptr<char>) i; // expected-error {{pointer type mismatch}}
array_ptr<char> t35 : bounds(char_unchecked_ptr_lb, int_ptr_ub) = (array_ptr<char>) i; // expected-error {{pointer type mismatch}}
char* _Array t35 _Bounds(char_unchecked_ptr_lb, int_ptr_ub) = (char* _Array) i; // expected-error {{pointer type mismatch}}
// spot check nt_array_ptr with invalid bounds expression
nt_array_ptr<char> t40 : bounds(int_array_ptr_lb, char_array_ptr_ub) = 0; // expected-error {{pointer type mismatch}}
@ -510,8 +510,8 @@ struct S1 g51 : count(5) = { 0 }; // expected-error {{expected 'g51' to have a
union U1 g52 : count(5) = { 0 }; // expected-error {{expected 'g52' to have a pointer or array type}}
enum E1 g53 : count(5) = EnumVal1; // expected-error {{expected 'g53' to have a pointer or array type}}
ptr<int> g54: count(1) = 0; // expected-error {{bounds declaration not allowed because 'g54' has a _Ptr type}}
array_ptr<void> g55 : count(1) = 0; // expected-error {{expected 'g55' to have a non-void pointer type}}
void((*g56)(void)) : count(1); // expected-error {{bounds declaration not allowed because 'g56' has a function pointer type}}
void* _Array g55 _Count(1) = 0; // expected-error {{expected 'g55' to have a non-void pointer type}}
void((*g56)(void)) _Count(1); // expected-error {{bounds declaration not allowed because 'g56' has a function pointer type}}
// byte_count
float g60 : byte_count(8); // expected-error {{expected 'g60' to have a pointer, array, or integer type}}
@ -526,8 +526,8 @@ float g70 : bounds(s1, s1 + 1); // expected-error {{expected 'g70' t
double g71 : bounds(s1, s1 + 1); // expected-error {{expected 'g71' to have a pointer, array, or integer type}}
struct S1 g72 : bounds(s1, s1 + 1) = { 0 }; // expected-error {{expected 'g72' to have a pointer, array, or integer type}}
union U1 g73 : bounds(s1, s1 + 1) = { 0 }; // expected-error {{expected 'g73' to have a pointer, array, or integer type}}
ptr<int> g74 : bounds(s1, s1 + 1) = 0; // expected-error {{bounds declaration not allowed because 'g74' has a _Ptr type}}
void((*g75)(void)) : bounds(s1, s1 + 1); // expected-error {{bounds declaration not allowed because 'g75' has a function pointer type}}
int* _Single g74 _Bounds(s1, s1 + 1) = 0; // expected-error {{bounds declaration not allowed because 'g74' has a _Ptr type}}
void((*g75)(void)) _Bounds(s1, s1 + 1); // expected-error {{bounds declaration not allowed because 'g75' has a function pointer type}}
//
// Test bounds declarations for local variables.
@ -554,7 +554,7 @@ void local_var_bounds_decl(void)
array_ptr<void> t11 : bounds(t3, t3 + 5) = t3;
int t13 checked[5] : bounds(t13, t13 + 5);
unsigned int t14 checked[5] : bounds(t14, t14 + 5);
unsigned int t14a nt_checked[5] : bounds(t14, t14 + 4);
unsigned int t14a nt_checked[5] _Bounds(t14, t14 + 4);
}
void int_local_var_bounds_decl(void) {
@ -587,8 +587,8 @@ void invalid_local_var_bounds_decl(void)
union U1 t52 : count(5) = { 0 }; // expected-error {{expected 't52' to have a pointer or array type}}
enum E1 t53 : count(5) = EnumVal1; // expected-error {{expected 't53' to have a pointer or array type}}
ptr<int> t54 : count(1) = 0; // expected-error {{bounds declaration not allowed because 't54' has a _Ptr type}}
array_ptr<void> t55 : count(1) = 0; // expected-error {{expected 't55' to have a non-void pointer type}}
array_ptr<void (void)> t56 : count(1); // expected-error {{declared as _Array_ptr to function of type 'void (void)'; use _Ptr to function instead}}
void* _Array t55 _Count(1) = 0; // expected-error {{expected 't55' to have a non-void pointer type}}
array_ptr<void (void)> t56 _Count(1); // expected-error {{declared as _Array_ptr to function of type 'void (void)'; use _Ptr to function instead}}
int *t57 : count(1) = 0; // expected-error {{bounds declaration not allowed for local variable with unchecked pointer type}}
int t58[5] : count(5); // expected-error {{bounds declaration not allowed for local variable with unchecked array type}}
@ -601,8 +601,8 @@ void invalid_local_var_bounds_decl(void)
ptr<int> t64 : byte_count(sizeof(int)) = 0; // expected-error {{bounds declaration not allowed because 't64' has a _Ptr type}}
array_ptr<void (void)> t65 : byte_count(1); // expected-error {{declared as _Array_ptr to function of type 'void (void)'; use _Ptr to function instead}}
int *t67 : byte_count(sizeof(int)) = 0; // expected-error {{bounds declaration not allowed for local variable with unchecked pointer type}}
int t68[5] : byte_count(5 * sizeof(int)); // expected-error {{bounds declaration not allowed for local variable with unchecked array type}}
int *t67 _Byte_count(sizeof(int)) = 0; // expected-error {{bounds declaration not allowed for local variable with unchecked pointer type}}
int t68[5] _Byte_count(5 * sizeof(int)); // expected-error {{bounds declaration not allowed for local variable with unchecked array type}}
// bounds
float t70 : bounds(arr, arr + 1); // expected-error {{expected 't70' to have a pointer, array, or integer type}}
@ -613,7 +613,7 @@ void invalid_local_var_bounds_decl(void)
array_ptr<void (void)> t75 : bounds(arr, arr + 1); // expected-error {{declared as _Array_ptr to function of type 'void (void)'; use _Ptr to function instead}}
int *t78 : bounds(arr, arr + 1) = 0; // expected-error {{bounds declaration not allowed for local variable with unchecked pointer type}}
int t79[5] : bounds(arr, arr + 1); // expected-error {{bounds declaration not allowed for local variable with unchecked array type}}
int t79[5] _Bounds(arr, arr + 1); // expected-error {{bounds declaration not allowed for local variable with unchecked array type}}
}
//
@ -634,8 +634,8 @@ void param_var_bounds_decl(
array_ptr<int> t4 : byte_count(5 * sizeof(int)),
array_ptr<void> t5 : byte_count(5 * sizeof(int)),
int *t6 : byte_count(5 * sizeof(int)),
int t7 checked[5] : byte_count(5 * sizeof(int)),
unsigned int t8 checked[5] : byte_count(5 * sizeof(int)),
int t7 checked[5] _Byte_count(5 * sizeof(int)),
unsigned int t8 checked[5] _Byte_count(5 * sizeof(int)),
unsigned int t9[5] : byte_count(5 * sizeof(int)),
// bounds
@ -719,8 +719,8 @@ void invalid_param_var_bounds_decl(
double t61 : byte_count(8), // expected-error {{expected 't61' to have a pointer, array, or integer type}}
struct S1 t62 : byte_count(8), // expected-error {{expected 't62' to have a pointer, array, or integer type}}
union U1 t63 : byte_count(8), // expected-error {{expected 't63' to have a pointer, array, or integer type}}
ptr<int> t64 : byte_count(8), // expected-error {{bounds declaration not allowed because 't64' has a _Ptr type}}
void((*t65)(void)) : byte_count(1),// expected-error {{bounds declaration not allowed because 't65' has a function pointer type}}
int* _Single t64 _Byte_count(8), // expected-error {{bounds declaration not allowed because 't64' has a _Ptr type}}
void((*t65)(void)) _Byte_count(1),// expected-error {{bounds declaration not allowed because 't65' has a function pointer type}}
// bounds
float t70 : bounds(s1, s1 + 1), // expected-error {{expected 't70' to have a pointer, array, or integer type}}
@ -742,8 +742,8 @@ extern void anonymous_invalid_param_var_bounds_decl(
int : count(5), // expected-error {{expected '' to have a pointer or array type}}
long int : count(5), // expected-error {{expected '' to have a pointer or array type}}
unsigned short int : count(5), // expected-error {{expected '' to have a pointer or array type}}
unsigned int : count(5), // expected-error {{expected '' to have a pointer or array type}}
unsigned long : count(5), // expected-error {{expected '' to have a pointer or array type}}
unsigned int _Count(5), // expected-error {{expected '' to have a pointer or array type}}
unsigned long _Count(5), // expected-error {{expected '' to have a pointer or array type}}
float : count(5), // expected-error {{expected '' to have a pointer or array type}}
double : count(5), // expected-error {{expected '' to have a pointer or array type}}
@ -755,12 +755,12 @@ extern void anonymous_invalid_param_var_bounds_decl(
void((*)(void)) : count(1), // expected-error {{bounds declaration not allowed because '' has a function pointer type}}
// byte_count
float : byte_count(8), // expected-error {{expected '' to have a pointer, array, or integer type}}
double : byte_count(8), // expected-error {{expected '' to have a pointer, array, or integer type}}
struct S1 : byte_count(8), // expected-error {{expected '' to have a pointer, array, or integer type}}
union U1 : byte_count(8), // expected-error {{expected '' to have a pointer, array, or integer type}}
ptr<int> : byte_count(8), // expected-error {{bounds declaration not allowed because '' has a _Ptr type}}
void((*)(void)) : byte_count(1),// expected-error {{bounds declaration not allowed because '' has a function pointer type}}
float _Byte_count(8), // expected-error {{expected '' to have a pointer, array, or integer type}}
double _Byte_count(8), // expected-error {{expected '' to have a pointer, array, or integer type}}
struct S1 _Byte_count(8), // expected-error {{expected '' to have a pointer, array, or integer type}}
union U1 _Byte_count(8), // expected-error {{expected '' to have a pointer, array, or integer type}}
int* _Single _Byte_count(8), // expected-error {{bounds declaration not allowed because '' has a _Ptr type}}
void((*)(void)) _Byte_count(1),// expected-error {{bounds declaration not allowed because '' has a function pointer type}}
// bounds
float : bounds(s1, s1 + 1), // expected-error {{expected '' to have a pointer, array, or integer type}}
@ -798,7 +798,7 @@ struct S4 {
int f7 checked[5] : byte_count(5 * sizeof(int));
int f7a nt_checked[5] : byte_count(4 * sizeof(int));
unsigned int f8 checked[5] : byte_count(5 * sizeof(int));
unsigned int f9[5] : byte_count(5 * sizeof(int));
unsigned int f9[5] _Byte_count(5 * sizeof(int));
};
// bounds
@ -810,9 +810,9 @@ struct S6 {
int *f12 : bounds(f12, f12 + 5);
int f13 checked[5] : bounds(f13, f13 + 5);
unsigned int f14 checked[5] : bounds(f14, f14 + 5);
unsigned int f14a nt_checked[5] : bounds(f14a, f14a + 5);
unsigned int f14a nt_checked[5] _Bounds(f14a, f14a + 5);
int f15[5] : bounds(f15, f15 + 5);
unsigned int f16[5] : bounds(f16, f16 + 5);
unsigned int f16[5] _Bounds(f16, f16 + 5);
};
//
@ -873,10 +873,11 @@ struct s8 {
double g71 : bounds(s1, s1 + 1); // expected-error {{expected 'g71' to have a pointer, array, or integer type}}
struct S1 g72 : bounds(s1, s1 + 1); // expected-error {{expected 'g72' to have a pointer, array, or integer type}}
union U1 g73 : bounds(s1, s1 + 1); // expected-error {{expected 'g73' to have a pointer, array, or integer type}}
ptr<int> g74 : bounds(s1, s1 + 1); // expected-error {{bounds declaration not allowed because 'g74' has a _Ptr type}}
void((*g75)(void)) : bounds(s1, s1 + 1); // expected-error {{bounds declaration not allowed because 'g75' has a function pointer type}}
int* _Single g74 _Bounds(s1, s1 + 1); // expected-error {{bounds declaration not allowed because 'g74' has a _Ptr type}}
void((*g75)(void)) _Bounds(s1, s1 + 1); // expected-error {{bounds declaration not allowed because 'g75' has a function pointer type}}
};
//
// Test function return bounds declarations.
//
@ -886,7 +887,7 @@ struct s8 {
//
// count
array_ptr<int> fn1(void) : count(5) { return 0; }
int* _Array fn1(void) _Count(5) { return 0; }
nt_array_ptr<int> fn1a(void) : count(0) { return 0; }
int *fn2(void) : count(5) { return 0; }
int *fn3(int len) : count(len) { return 0; }
@ -899,7 +900,7 @@ extern int *fn6(void) : byte_count(5 * sizeof(int));
// bounds
array_ptr<int> fn10(void) : bounds(s1, s1 + 5) { return 0; }
nt_array_ptr<int> fn10a(void) : bounds(s1, s1 + 5) { return 0; }
int* _Nt_array fn10a(void) _Bounds(s1, s1 + 5) { return 0; }
array_ptr<void> fn11(void) : bounds(s1, s1 + 5) { return 0; }
int *fn12(void) : bounds(s1, s1 + 5) { return 0; }
@ -1005,9 +1006,9 @@ void fn122(array_ptr<void> mid : bounds((char *)p1, (char *)p1 + (5 * sizeof(int
// function pointers.
// Unchecked function pointers
void fn200(void (*fnptr)(array_ptr<int> p1 : count(5)));
void fn201(void (*fnptr)(int p1 : count(5))); // expected-error {{expected 'p1' to have a pointer or array type}}
void fn202(void (*fnptr)(array_ptr<void> p1 : count(5))); // expected-error {{expected 'p1' to have a non-void pointer type}}
void fn200(void (*fnptr)(int* _Array p1 _Count(5)));
void fn201(void (*fnptr)(int p1 _Count(5))); // expected-error {{expected 'p1' to have a pointer or array type}}
void fn202(void (*fnptr)(void* _Array p1 _Count(5))); // expected-error {{expected 'p1' to have a non-void pointer type}}
void fn203(int (*fnptr)(array_ptr<int> p1 : byte_count(5 * sizeof(int))));
void fn204(int (*fnptr)(int * : byte_count(5 * sizeof(int))));
@ -1039,8 +1040,8 @@ void fn231(ptr<void (array_ptr<void> p1 : bounds((char *)p1, (char *)p1 + (5 * s
// Function pointers with multiple arguments.
void fn240(ptr<int (array_ptr<int> mid : bounds(p1, p1 + 5), array_ptr<int> p1)> fnptr);
void fn241(ptr<int (array_ptr<void> mid : bounds((char *)p1, (char *)p1 + (5 * sizeof(int))),
array_ptr<int> p1)> fnptr);
void fn241(ptr<int (void* _Array mid _Bounds((char *)p1, (char *)p1 + (5 * sizeof(int))),
int* _Array p1)> fnptr);
//
// Spot check bounds-safe interfaces on parameters of function pointer types
@ -1056,7 +1057,7 @@ void fn252(int(*fnptr)(int *p1 : bounds(p1, p1 + 5)));
void fn260(array_ptr<int> (*fnptr)(void) : count(5));
void fn261(array_ptr<int>(*fnptr)(int i) : count(i));
void fn262(int (*fnptr)(void) : count(5)); // expected-error {{count bounds expression only allowed for pointer return type}}
void fn263(array_ptr<void> (*fnptr)(void) : count(5)); // expected-error {{count bounds expression not allowed for a void pointer return type}}
void fn263(void* _Array (*fnptr)(void) _Count(5)); // expected-error {{count bounds expression not allowed for a void pointer return type}}
//
// Test bounds declarations for function pointers
@ -1065,7 +1066,7 @@ void fn263(array_ptr<void> (*fnptr)(void) : count(5)); // expected-error {{count
void function_pointers(void) {
// Assignments to function pointers with return bounds on array_ptr types
array_ptr<int>(*t1)(void) : count(5) = fn1;
nt_array_ptr<int>(*t1a)(void) : count(0) = fn1a;
int* _Nt_array(*t1a)(void) _Count(0) = fn1a;
// Assignment to function pointers with bounds-safe interfaces on
// unchecked pointer return types. Unchecked pointers are compatible with
// unchecked pointers with bounds-safe interfaces. This extends recursively
@ -1079,13 +1080,13 @@ void function_pointers(void) {
ptr<int *(int j) : count(j)> t7 = fn3;
array_ptr<int>(*t8)(void) : byte_count(5 * sizeof(int)) = fn4;
array_ptr<void>(*t9)(void) : byte_count(5 * sizeof(int)) = fn5;
void* _Array(*t9)(void) _Byte_count(5 * sizeof(int)) = fn5;
int *(*t10)(void) = fn6;
int *(*t11)(void) : byte_count(5*sizeof(int)) = fn6;
ptr<int *(void) : byte_count(5*sizeof(int))> t12 = fn6;
array_ptr<int>(*t13)(void) : bounds(s1, s1 + 5) = fn10;
nt_array_ptr<int>(*t13a)(void) : bounds(s1, s1 + 5) = fn10a;
int* _Nt_array(*t13a)(void) _Bounds(s1, s1 + 5) = fn10a;
int *(*t14)(void) = fn12;
int *(*t15)(void) : bounds(s1, s1 + 5) = fn12;
int *(*t16)(void) : bounds(s1, s1 + 6) = fn12; // expected-warning {{incompatible function pointer types}}
@ -1095,7 +1096,7 @@ void function_pointers(void) {
// function.
ptr<array_ptr<int>(void) : count(5)> t100 = fn1;
// The reverse is not allowed
array_ptr<int>(*t101)(void) : count(5) = t100; // expected-error {{incompatible type}}
int* _Array(*t101)(void) _Count(5) = t100; // expected-error {{incompatible type}}
// Calls that pass function pointers with bounds
fn200(fn100);
@ -1143,7 +1144,7 @@ void invalid_function_pointers(void) {
array_ptr<int>(*t1)(void) : count(4) = fn1; // expected-error {{incompatible type}}
ptr<array_ptr<int>(void) : count(4)> t1a = fn1; // expected-error {{incompatible type}}
array_ptr<int>(*t4)(void) : byte_count(6 * sizeof(int)) = fn4; // expected-error {{incompatible type}}
array_ptr<int>(*t10)(void) : bounds(s1, s1 + 4) = fn10; // expected-error {{incompatible type}}
int* _Array(*t10)(void) _Bounds(s1, s1 + 4) = fn10; // expected-error {{incompatible type}}
}
// Test type checking of return_value
@ -1154,4 +1155,4 @@ array_ptr<int> f301(void) : bounds(return_value, return_value + 10);
array_ptr<int> f302(void) : bounds(return_value - 5, return_value + 5);
array_ptr<int> f303(void) : count(return_value); // expected-error {{invalid argument type}}
array_ptr<int> f304(void) : bounds(arr, arr + (return_value << 5)); // expected-error {{invalid operands to binary expression}}
array_ptr<void> f305(void) : bounds(return_value, return_value + 5); // expected-error {{arithmetic on a pointer to void}}
void* _Array f305(void) _Bounds(return_value, return_value + 5); // expected-error {{arithmetic on a pointer to void}}

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

@ -147,8 +147,8 @@ extern void check_assign(int val, int p[10], int q[], int r checked[10], int s c
array_ptr<int> t10 = s;
array_ptr<int> t9b = w;
array_ptr<int> t11 = t;
array_ptr<int> t11a = u;
array_ptr<int> t12 = u;
int* _Array t11a = u;
int* _Array t12 = u;
nt_array_ptr<int> t12a = x;
nt_array_ptr<int> t12b = u; // expected-error {{expression of incompatible type 'int _Checked[10]'}}
array_ptr<int> t13 = s2d[0];
@ -158,8 +158,8 @@ extern void check_assign(int val, int p[10], int q[], int r checked[10], int s c
array_ptr<int> t14 = t2d[0];
array_ptr<int> t15 = u2d[0];
array_ptr<int> t15a = x2d[0];
nt_array_ptr<int> t15b : bounds(unknown) = x2d[0];
nt_array_ptr<int> t15c = u2d[0]; // expected-error {{expression of incompatible type 'int _Checked[10]'}}
int* _Nt_array t15b _Bounds(unknown) = x2d[0];
int* _Nt_array t15c = u2d[0]; // expected-error {{expression of incompatible type 'int _Checked[10]'}}
// Multi-dimensional array type conversions to pointer types.
int *t16 = s2d[0]; // expected-error {{expression of incompatible type 'int _Checked[10]'}}
@ -471,9 +471,9 @@ extern void check_condexpr(int val) {
// N and M are arbitrary positive integer constants below.
int *t1 = val ? p : p; // T[N] and T[M] OK;
array_ptr<int> t2 = val ? p : r; // T[N] and T checked[M] OK
array_ptr<int> t2a = val ? p : v; // T[N] and T nt_checked[M] OK.
nt_array_ptr<int> t2b = val ? p : v; // expected-error {{incompatible type}}
int* _Array t2 = val ? p : r; // T[N] and T checked[M] OK
int* _Array t2a = val ? p : v; // T[N] and T nt_checked[M] OK.
int* _Nt_array t2b = val ? p : v; // expected-error {{incompatible type}}
// T[N] and T nt_checked[M] produce
// only array_ptr.
array_ptr<int> t3 = val ? r : p; // T checked[N] and T[M] OK
@ -487,7 +487,7 @@ extern void check_condexpr(int val) {
// But they produce only array_ptr.
nt_array_ptr<int> t4d = val ? v : r; // expected-error {{incompatible type}}
// But they produce only array_ptr
nt_array_ptr<int> t4e = val ? v : v; // T nt_checked[M] and T nt_checked[N] OK.
int* _Nt_array t4e = val ? v : v; // T nt_checked[M] and T nt_checked[N] OK.
// omit assignment because type of expression is not valid when there is an error.
val ? s : r; // expected-error {{pointer type mismatch}}
@ -514,9 +514,9 @@ extern void check_condexpr(int val) {
array_ptr<int> t5 = val ? r : 0;
array_ptr<int> t5a = val ? v : 0;
array_ptr<int> t6 = val ? 0 : r;
nt_array_ptr<int> t6a = val ? 0 : v; // expected-warning {{cannot prove declared bounds for 't6a' are valid after initialization}}
int* _Nt_array t6a = val ? 0 : v; // expected-warning {{cannot prove declared bounds for 't6a' are valid after initialization}}
array_ptr<float> t7 = val ? u : 0;
array_ptr<float> t8 = val ? 0 : u;
float* _Array t8 = val ? 0 : u;
}
extern void check_condexpr_2d(int val) {
@ -621,7 +621,7 @@ extern void check_condexpr_cv(void)
array_ptr<const int> t32 = val ? r_const : r; // array_ptr<const int> and array_ptr<int> OK
array_ptr<const int> t33 = val ? r_const : r_const; // array_ptr<const int> and array_ptr<const int> OK
array_ptr<const int> t25a = val ? p : s_const; // int * and nt_array_ptr<const int> OK
const int* _Array t25a = val ? p : s_const; // int * and nt_array_ptr<const int> OK
array_ptr<const int> t26a = val ? s_const : p; // nt_array_ptr<const int> and int * OK
array_ptr<const int> t27a = val ? p_const : s; // const int * and nt_array_ptr<int> OK
array_ptr<const int> t28a = val ? s : p_const; // nt_array_ptr<int> and const int * OK
@ -633,7 +633,7 @@ extern void check_condexpr_cv(void)
array_ptr<const int> t33b = val ? r_const : s_const; // array_ptr<const int> and nt_array_ptr<const int> OK
array_ptr<const int> t33c = val ? s : s_const; // nt_array_ptr<int> and nt_array_ptr<const int> OK
array_ptr<const int> t33d = val ? s_const : s; // nt_array_ptr<const int> and nt_array_ptr<int> OK
array_ptr<const int> t33e = val ? s_const : s_const; // nt_array_ptr<const int> and nt_array_ptr<const int> OK
const int* _Array t33e = val ? s_const : s_const; // nt_array_ptr<const int> and nt_array_ptr<const int> OK
array_ptr<int> t34 = val ? p : r_const; // expected-warning {{discards qualifiers}}
// int * and array_ptr<const int> produce array_ptr<const int>
@ -651,8 +651,8 @@ extern void check_condexpr_cv(void)
// array_ptr<int> and array_ptr<const int> produce array_ptr<const int>
array_ptr<int> t41 = val ? r_const : r; // expected-warning {{discards qualifiers}}
// array_ptr<const int> and array_ptr<int> produce array_ptr<const int>
array_ptr<int> t42 = val ? r_const : r_const; // expected-warning {{discards qualifiers}}
// array_ptr<const int> and array_ptr<const int> produce array_ptr<const int>
int* _Array t42 = val ? r_const : r_const; // expected-warning {{discards qualifiers}}
// array_ptr<const int> and array_ptr<const int> produce array_ptr<const int>
array_ptr<int> t34a = val ? p : s_const; // expected-warning {{discards qualifiers}}
// int * and nt_array_ptr<const int> produce array_ptr<const int>
@ -680,7 +680,7 @@ extern void check_condexpr_cv(void)
// nt_array_ptr<int> and nt_array_ptr<const int> produce array_ptr<const int>
array_ptr<int> t43d = val ? s_const : s; // expected-warning {{discards qualifiers}}
// nt_array_ptr<const int> and nt_array_ptr<int> produce array_ptr<const int>
array_ptr<int> t42e = val ? s_const : s_const; // expected-warning {{discards qualifiers}}
int* _Array t42e = val ? s_const : s_const; // expected-warning {{discards qualifiers}}
// nt_array_ptr<const int> and nt_array_ptr<const int> produce array_ptr<const int>
// test different kinds of pointers with volatile modifers
@ -719,7 +719,7 @@ extern void check_condexpr_cv(void)
array_ptr<volatile int> t82d = val ? s_volatile : s; // nt_array_ptr<volatile int> and nt_array_ptr<int> OK
array_ptr<volatile int> t82e = val ? s_volatile : s_volatile; // nt_array_ptr<volatile int> and nt_array_ptr<volatile int> OK
array_ptr<int> t83 = val ? p : r_volatile; // expected-warning {{discards qualifiers}}
int* _Array t83 = val ? p : r_volatile; // expected-warning {{discards qualifiers}}
// int * and array_ptr<volatile int> produce array_ptr<volatile int>
array_ptr<int> t84 = val ? r_volatile : p; // expected-warning {{discards qualifiers}}
// array_ptr<volatile int> and int * produce array_ptr<volatile int>
@ -762,7 +762,7 @@ extern void check_condexpr_cv(void)
// nt_array_ptr<int> and nt_array_ptr<volatile int> produce array_ptr<volatile int>
array_ptr<int> t92d = val ? s_volatile : s; // expected-warning {{discards qualifiers}}
// nt_array_ptr<volatile int> and nt_array_ptr<int> produce array_ptr<volatile int>
array_ptr<int> t92e = val ? s_volatile : s_volatile; // expected-warning {{discards qualifiers}}
int* _Array t92e = val ? s_volatile : s_volatile; // expected-warning {{discards qualifiers}}
// nt_array_ptr<volatile int> and nt_array_ptr<volatile int> produce array_ptr<volatile int>
}
@ -827,7 +827,7 @@ extern void f13(_Bool p, int y) {
extern void f1_void(void *p, int y) {
}
extern void f2_void(ptr<void> p, int y) {
extern void f2_void(void* _Single p, int y) {
}
extern void f3_void(array_ptr<void> p, int y) {
@ -1037,7 +1037,7 @@ extern void check_call_void(void) {
// TODO: s will need bounds information
void *s = 0;
ptr<void> t = 0;
void* _Single t = 0;
array_ptr<void> u = 0;
// Test different kinds of pointers where the parameter type is a pointer to void and
@ -1885,14 +1885,14 @@ extern void check_vla(int i) {
// Test assigning an unchecked pointer with an nt_array_ptr
// bounds-safe interface to a checked nt_array_ptr.
extern void check_nt_bounds_safe_interface(const char *interop_string : itype(nt_array_ptr<const char>),
char **interop_ptr : itype(nt_array_ptr<ptr<char>>),
extern void check_nt_bounds_safe_interface(const char *interop_string : itype(const char* _Nt_array),
char **interop_ptr _Itype(nt_array_ptr<ptr<char>>),
char checked_arr nt_checked[3],
char unchecked_arr[3]) {
// LHS of assignment has nt_array_ptr<T> type and RHS of assignment
// is an unchecked pointer with nt_array_ptr<T> bounds-safe interface.
nt_array_ptr<const char> checked_str = interop_string;
nt_array_ptr<ptr<char>> checked_ptr = interop_ptr;
const char* _Nt_array checked_str = interop_string;
char* _Single * _Nt_array checked_ptr = interop_ptr;
// LHS of assignment has nt_array_ptr<T> type and RHS of assigment
// is an unchecked pointer with nt_array_ptr<U> bounds-safe interface,

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

@ -89,8 +89,8 @@ scope must have a pointer, array or function type that uses only checked types o
//
int *t40[10]; // expected-error {{local variable in a checked scope must have a checked type}}
ptr<int> t41[10]; // expected-error {{local variable in a checked scope must have a checked type}}
array_ptr<int> t42[10]; // expected-error {{local variable in a checked scope must have a checked type}}
int* _Single t41[10]; // expected-error {{local variable in a checked scope must have a checked type}}
int* _Array t42[10]; // expected-error {{local variable in a checked scope must have a checked type}}
int *t43 checked[10]; // 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 interfaces}}
@ -101,7 +101,7 @@ scope must have a pointer, array or function type that uses only checked types o
scope must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interfaces}}
ptr<int> *t47 checked[10][15]; // 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 interfaces}}
array_ptr<int> t48 checked[3][2] = {0};
int* _Array t48 checked[3][2] = {0};
//
// Checked pointers to function types that use constructed types.
@ -111,7 +111,7 @@ scope must have a pointer, array or function type that uses only checked types o
ptr<int *(int, int)> t60 = 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 interfaces}}
ptr<ptr<int>(int, int)> t61 = 0;
ptr<array_ptr<int>(int, int)> t62 = 0;
ptr<int* _Array(int, int)> t62 = 0;
// Function with different kinds of pointer arguments.
ptr<void(int *)> t63 = 0; // expected-error {{local variable in a checked \
@ -144,7 +144,7 @@ SCOPE_KIND int func4(int p[]) { // expected-error {{parameter in a checked scop
return 0;
}
SCOPE_KIND int func5(ptr<int> p, int *q) { // expected-error {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
SCOPE_KIND int func5(int* _Single p, int *q) { // expected-error {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
return 0;
}
@ -165,7 +165,7 @@ SCOPE_KIND int func9(ptr<int> p) {
}
// Test for checked function specifier & checked block.
int* func11(array_ptr<int> x, int len) SCOPE_KIND {
int* func11(int* _Array x, int len) SCOPE_KIND {
int *upa; // expected-error {{local variable in a checked scope must have a checked type}}
return upa;
}
@ -261,14 +261,14 @@ int a, b, c;
}
int KNR_func5(a, b)
ptr<int> a;
int* _Single a;
int b;
{
return 1;
}
int KNR_func6(a, b)
ptr<char> a;
char*_Single a;
ptr<int> b;
{
return 1;
@ -277,7 +277,7 @@ ptr<int> b;
#pragma CHECKED_SCOPE ON
void KNR_test(void) {
ptr<int> px = 0;
ptr<char> py = 0;
char*_Single py = 0;
int a,b,c;
KNR_func4(a,b,c); // expected-error {{function without a prototype cannot be used or declared in a checked scope}}
KNR_func5(px,a); // expected-error {{function without a prototype cannot be used or declared in a checked scope}}
@ -302,7 +302,7 @@ int func20(void) SCOPE_KIND {
int func21(void) {
SCOPE_KIND {
int a = 5;
ptr<int> pa = &a;
int* _Single pa = &a;
int b checked[5][5];
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
@ -389,8 +389,8 @@ checked void func27(void) {
void func28(void) {
int *upa;
array_ptr<int> pb;
ptr<int> pc = 0;
int* _Array pb;
int* _Single pc = 0;
}
int func29(void) {
@ -401,10 +401,10 @@ int func29(void) {
int *a; // expected-error {{member in a checked scope must have a checked type}}
char *b; // expected-error {{member in a checked scope must have a checked type}}
ptr<int> pc;
array_ptr<int> pd : count(len);
int* _Array pd _Count(len);
int len;
short e[10]; // expected-error {{member in a checked scope must have a checked type}}
int *f : itype(ptr<int>);
int *f : itype(int* _Single);
char *g : itype(array_ptr<char>);
} a = {0};
}
@ -414,7 +414,7 @@ int func29(void) {
void func30(void) {
int a = 5;
int len = 10;
array_ptr<int> pa : count(len) = 0;
int* _Array pa _Count(len) = 0;
/// checked is a function declaration specifier unless followed by '{' or '['
checked int len2; // expected-error {{'_Checked' can only appear on functions}}
checked [5][5]; // expected-error {{expected identifier}}
@ -427,7 +427,7 @@ SCOPE_KIND int * func40(int *p, int *q) unchecked {// expected-error {{return in
// 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;
int* _Single pa = &a;
int b[5][5];
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
@ -437,7 +437,7 @@ SCOPE_KIND int * func40(int *p, int *q) unchecked {// expected-error {{return in
return 0;
}
SCOPE_KIND int * func41(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}} \
SCOPE_KIND int * func41(int *p, int* _Single q, int* _Array r, int* _Array 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}}
int a = 5;
checked {
@ -540,7 +540,7 @@ SCOPE_KIND int func45(int *p, int *q) unchecked { // expected-error 2 {{paramete
int func46(ptr<int> p, int *q) unchecked {
int a = 5;
int *upa;
array_ptr<int> pc;
int* _Array pc;
SCOPE_KIND {
upa = &a; // expected-error {{local variable used in a checked scope must have a checked type}}
pc = &a;
@ -551,11 +551,11 @@ int func46(ptr<int> p, int *q) unchecked {
upa = &a; // expected-error {{local variable used in a checked scope must have a checked type}}
pc = &a;
}
ptr<int> pb = p;
int* _Single pb = p;
return *pb;
}
SCOPE_KIND array_ptr<int> func47(void) {
SCOPE_KIND int* _Array func47(void) {
int *upa; // expected-error {{local variable in a checked scope must have a checked type}}
unchecked {
int *upb;
@ -590,7 +590,7 @@ int func49(void) {
int len;
short e[10];
char f[10];
int *g : itype(ptr<int>);
int *g : itype(int* _Single);
char *h : itype(array_ptr<char>);
} b; // expected-error {{containing a checked pointer must have an initializer}}
@ -613,7 +613,7 @@ unchecked int * func50(int *p, int *q) {
return 0;
}
unchecked int * func51(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s : count(2)) {
unchecked int * func51(int *p, int* _Single q, int* _Array r, array_ptr<int> s : count(2)) {
int a = 5;
SCOPE_KIND {
*p = 1; // expected-error {{parameter used in a checked scope must have a checked type or a bounds-safe interface}}
@ -632,7 +632,7 @@ unchecked int * func51(int *p, ptr<int> q, array_ptr<int> r, array_ptr<int> s :
return 0;
}
unchecked int func52(ptr<int> p, int q[], int r[5]) unchecked {
unchecked int func52(int* _Single p, int q[], int r[5]) unchecked {
int a = 5;
checked {
int *upa = &a; // expected-error {{local variable in a checked scope must have a checked type}}
@ -866,9 +866,9 @@ void test_addrof_checked_scope(void) SCOPE_KIND {
x = b; // BinaryOperator (ImplicitCastExpr _Ptr (_Array_ptr)) \
// expected-error {{expression has unknown bounds, cast to ptr<T> expects source to have bounds}}
array_ptr<int> ax = &a[i];
array_ptr<int> ay = &b[2];
array_ptr<int> az = &i;
int* _Array ax = &a[i];
int* _Array ay = &b[2];
int* _Array az = &i;
ax = &a[i];
ay = &b[3];
@ -879,7 +879,7 @@ void test_addrof_checked_scope(void) SCOPE_KIND {
// &b[i] result type = array_ptr<int>
array_ptr<int> px = &(*(b+i));
array_ptr<int> py = &b[i];
array_ptr<int> pz = &(*(a+i));
int* _Array pz = &(*(a+i));
px = &(*(b+i));
py = &b[i];
@ -911,9 +911,9 @@ void test_addrof_unchecked_scope(void) unchecked {
// expected-error {{expression has unknown bounds, cast to ptr<T> expects source to have bounds}}
// checkSingleAssignmentConstraints(int * -> _Array_ptr<int> implicit casting)
array_ptr<int> ax = &a[i]; // ImplicitCastExpr _Array_ptr<int>(UnaryOperator)
array_ptr<int> ay = &b[0]; // ImplicitCastExpr _Array_ptr<int>(UnaryOperator)
array_ptr<int> az = &i; // ImplicitCastExpr _Array_ptr<int>(UnaryOperator)
int* _Array ax = &a[i]; // ImplicitCastExpr _Array_ptr<int>(UnaryOperator)
int* _Array ay = &b[0]; // ImplicitCastExpr _Array_ptr<int>(UnaryOperator)
int* _Array az = &i; // ImplicitCastExpr _Array_ptr<int>(UnaryOperator)
ax = &a[i]; // ImplicitCastExpr _Array_ptr<int>(UnaryOperator)
ay = &b[0]; // ImplicitCastExpr _Array_ptr<int>(UnaryOperator)
@ -935,8 +935,8 @@ void test_addrof_unchecked_scope(void) unchecked {
pz = &(*(a+i)); // UnaryOperator _Array_ptr<int>()
}
int *gptr0 : itype(ptr<int>);
int *gptr1 : itype(array_ptr<int>);
int *gptr0 _Itype(ptr<int>);
int *gptr1 _Itype(array_ptr<int>);
int *gptr2;
extern void check_indirection_unchecked(int p[10], const int const_p[10], int y) SCOPE_KIND {
@ -981,7 +981,8 @@ extern void check_assign(int val, int p[10], int q[], int r checked[10], int s c
// not propagate through typedefs
int *t1, *t2, *t3, *t4, *t5, *t6;
array_ptr<int> t7, t8, t9, t10, t11, t12, t13, t14, t15;
int* _Array t7, *_Array t8, *_Array t9,
*_Array t10,*_Array t11,*_Array t12,*_Array t13,*_Array t14,*_Array t15;
int *t16, *t17, *t18;
int (*t19)[10];
int (*t20)[10];
@ -1122,7 +1123,7 @@ extern void f13(_Bool p, int y) {
extern void f1_void(void *p, int y) {
}
extern void f2_void(ptr<void> p, int y) {
extern void f2_void(void* _Single p, int y) {
}
extern void f3_void(array_ptr<void> p, int y) {
@ -1228,7 +1229,7 @@ SCOPE_KIND int *h3(void) { // expected-error {{return in a checked scope must
return global; // expected-error {{variable used in a checked scope must have a checked type}}
}
SCOPE_KIND ptr<int> h4(void) {
SCOPE_KIND int* _Single h4(void) {
return global; // expected-error {{variable used in a checked scope must have a checked type}}
}
@ -1256,7 +1257,7 @@ SCOPE_KIND ptr<int> h10(void) {
return global_arr1; // expected-error {{variable used in a checked scope must have a checked type}}
}
SCOPE_KIND array_ptr<int> h11(int arr checked[10]) {
SCOPE_KIND int* _Array h11(int arr checked[10]) {
return arr;
}
@ -1276,7 +1277,7 @@ SCOPE_KIND int *h15(int arr checked[]) { // expected-error {{return in a check
return 0;
}
SCOPE_KIND array_ptr<int> h18(int arr checked[]) {
SCOPE_KIND int* _Array h18(int arr checked[]) {
return arr;
}
@ -1286,7 +1287,8 @@ SCOPE_KIND int(*h19(int arr[10][10]))[10]{ // expected-error {{return in a che
}
int global_arr2[10][10];
SCOPE_KIND ptr<int[10]> h20(void) { // expected-error {{must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interfaces}}
typedef int unchecked_arr_type[10];
SCOPE_KIND unchecked_arr_type* _Single h20(void) { // expected-error {{must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interfaces}}
return global_arr2; // expected-error {{variable used in a checked scope must have a checked type}}
}
@ -1365,7 +1367,7 @@ void check_pointer_difference(int flag) {
float val_float[5];
int *p_int = val_int;
float *p_float = val_float;
array_ptr<int> r_int = val_int;
int* _Array r_int = val_int;
int a_int[5];
int checked_a_int checked[5];
@ -1404,13 +1406,13 @@ void check_pointer_compare(void) {
int *p_int = val_int;
float *p_float = val_float;
ptr<int> q_int = 0;
int* _Single q_int = 0;
q_int = val_int;
ptr<float> q_float = 0;
float* _Single q_float = 0;
q_float = val_float;
array_ptr<int> r_int = val_int;
array_ptr<float> r_float = val_float;
float* _Array r_float = val_float;
SCOPE_KIND {
// relational comparisons between pointers and unchecked arrays;
@ -1517,7 +1519,7 @@ SCOPE_KIND void check_cast_operator(void) {
aparr = (array_ptr<int [5]>) &arr; // expected-error {{type in a checked scope must use only checked types or parameter/return types with bounds-safe interfaces}}
// ptr to variadic/unchecked func pointer
ptr<int(int,int)> vpa = 0;
int (* _Single vpa)(int,int) = 0;
vpa = (ptr<int(int,...)>) &arr; // expected-error {{type in a checked scope cannot have variable arguments}}
vpa = (ptr<int(int,ptr<int(int, ...)>)>) &arr; // expected-error {{type in a checked scope cannot have variable arguments}}
vpa = (ptr<int*(int,int)>) &arr; // expected-error {{type in a checked scope must use only checked types or parameter/return types with bounds-safe interfaces}}
@ -1550,8 +1552,8 @@ SCOPE_KIND void check_cast_operator(void) {
unchecked {
int *p;
ptr<int> q = 0;
array_ptr<int> r : count(5) = 0;
int* _Single q = 0;
int* _Array r _Count(5) = 0;
SCOPE_KIND {
p = _Dynamic_bounds_cast<int *>(q); // expected-error {{local variable used in a checked scope must have a checked type}} \
// expected-error {{type in a checked scope must be a checked pointer or array type}} \
@ -1570,8 +1572,8 @@ SCOPE_KIND void check_cast_operator(void) {
vpa = _Assume_bounds_cast<ptr<int(int,...)>>(r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}}
vpa = _Assume_bounds_cast<ptr<int(int,ptr<int(int, ...)>)>>(r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}}
vpa = _Assume_bounds_cast<ptr<int*(int,int)>>(r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}}
vpa = _Assume_bounds_cast<ptr<int(int,ptr<int(int, ...)>, ...)>>(r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}}
vpa = _Assume_bounds_cast_M_N(ptr<int*(int,int)> ,r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}}
vpa = _Assume_bounds_cast_M_N(ptr<int(int,ptr<int(int, ...)>, ...)>, r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}}
}
}
}
@ -1628,7 +1630,7 @@ void check_checked_constructed_type_variadic(void) SCOPE_KIND {
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 {{must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interfaces}}
int* (*_Single h)(int, int) = 0; // expected-error {{must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interfaces}}
unchecked {
ptr<int(int,...)> var_b = 0;
@ -1660,7 +1662,7 @@ SCOPE_KIND void checked_check_variadic1(int (*fptr)(int, ptr<int>, array_ptr<int
(*fptr)(5, a, b, a, b, a);
}
void checked_check_variadic2(int (*fptr)(int, ptr<int>, array_ptr<int>, ...)) SCOPE_KIND {
void checked_check_variadic2(int (*fptr)(int, int* _Single, int* _Array, ...)) SCOPE_KIND {
ptr<int> a = 0;
array_ptr<int> b;
(*fptr)(5, a, b, a, b, a); // expected-error {{parameter used in a checked scope must have a checked type or a bounds-safe interface}} \
@ -1707,8 +1709,8 @@ extern void test_function_pointer(void) SCOPE_KIND {
ptr<int(int*)> fn4 = &id_intp; // expected-error {{must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interfaces}}
ptr<int(int*)> fn5 = id_intp; // expected-error {{must have a pointer, array or function type that uses only checked types or parameter/return types with bounds-safe interfaces}}
ptr<ptr<int>(ptr<int>)> fn8 = &id_checked_intp;
ptr<ptr<int>(ptr<int>)> fn9 = id_checked_intp;
int* _Single (*_Single fn8)(int* _Single) = &id_checked_intp;
int* _Single (*_Single fn9)(int* _Single) = id_checked_intp;
int val0;
// address-of (&) operator produces array_ptr<T> except for function type
@ -1740,8 +1742,8 @@ extern void test_cast_to_nt_array_ptr(void) checked {
nt_array_ptr<int> p6 = (nt_array_ptr<int>)arr_i; // expected-error {{'_Array_ptr<int>' cannot be cast to '_Nt_array_ptr<int>' in a checked scope because '_Array_ptr<int>' might not point to a null-terminated array}}
p6 = (nt_array_ptr<int>)p5; // expected-error {{'_Array_ptr<int>' cannot be cast to '_Nt_array_ptr<int>' in a checked scope because '_Array_ptr<int>' might not point to a null-terminated array}}
array_ptr<char> p7 : count(5) = arr_c;
nt_array_ptr<char> p8 = (nt_array_ptr<char>)arr_c; // expected-error {{'_Array_ptr<char>' cannot be cast to '_Nt_array_ptr<char>' in a checked scope because '_Array_ptr<char>' might not point to a null-terminated array}}
p8 = (nt_array_ptr<char>)p7; // expected-error {{'_Array_ptr<char>' cannot be cast to '_Nt_array_ptr<char>' in a checked scope because '_Array_ptr<char>' might not point to a null-terminated array}}
char* _Nt_array p8 = (char* _Nt_array)arr_c; // expected-error {{'_Array_ptr<char>' cannot be cast to '_Nt_array_ptr<char>' in a checked scope because '_Array_ptr<char>' might not point to a null-terminated array}}
p8 = (char* _Nt_array)p7; // expected-error {{'_Array_ptr<char>' cannot be cast to '_Nt_array_ptr<char>' in a checked scope because '_Array_ptr<char>' might not point to a null-terminated array}}
// Test casting nt_array_ptr to nt_array_ptr
nt_array_ptr<char> p9 = "hello";
@ -1756,8 +1758,8 @@ extern void test_cast_to_nt_array_ptr(void) checked {
// Test casting array_ptr to nt_array_ptr.
p6 = (nt_array_ptr<int>)arr_i; // allowed here; disallowed in a checked scope.
p6 = (nt_array_ptr<int>)p5; // allowed here; disallowed in a checked scope.
p8 = (nt_array_ptr<char>)p7; // allowed here; disallowed in a checked scope.
p6 = (int *_Nt_array)p5; // allowed here; disallowed in a checked scope.
p8 = (char* _Nt_array)p7; // allowed here; disallowed in a checked scope.
// Test casting nt_array_ptr to nt_array_ptr
p10 = (nt_array_ptr<char>)p9; // allowed in both checked and unchecked scopes.
@ -1766,7 +1768,7 @@ extern void test_cast_to_nt_array_ptr(void) checked {
int arr_i_unchecked[5];
p6 = (nt_array_ptr<int>)arr_i_unchecked; // allowed
char arr_c_unchecked[5];
p8 = (nt_array_ptr<char>)arr_c_unchecked; // allowed
p8 = (char* _Nt_array)arr_c_unchecked; // allowed
}
}

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

@ -22,7 +22,7 @@
#include <stdchecked.h>
// Parameters with simple types.
checked int f1(int *s : itype(ptr<int>)) {
checked int f1(int *s _Itype(int *_Single)) {
int t1 = *s; // Allowed in checked scope.
int t2 = *(s + 4); // expected-error {{arithmetic on _Ptr type}}
int t3 = s[4]; // expected-error {{subscript of '_Ptr<int>'}}
@ -32,8 +32,8 @@ checked int f1(int *s : itype(ptr<int>)) {
array_ptr<int> t4 : count(1) = s;
s = t4;
array_ptr<float> t5 : count(1) = s; // expected-error {{incompatible type}}
array_ptr<float> t6 = 0;
float* _Array t5 _Count(1) = s; // expected-error {{incompatible type}}
float* _Array t6 = 0;
s = t6; // expected-error {{incompatible type}}
return 0;
@ -51,7 +51,7 @@ checked int f2(int *s : count(len), int len) {
return 0;
}
checked int f3(int *s : itype(array_ptr<int>), int len) {
checked int f3(int *s _Itype(int *_Array), int len) {
array_ptr<int> t1 = s + 5; // allowed
int t2 = *s; // expected-error {{expression has unknown bounds}}
int t3 = s[4]; // expected-error {{expression has unknown bounds}}
@ -61,8 +61,8 @@ checked int f3(int *s : itype(array_ptr<int>), int len) {
return 0;
}
checked int f4(int *s : itype(int checked[4])) {
array_ptr<int> t1 = s + 4;
checked int f4(int *s _Itype(int checked[4])){
int *_Array t1 = s + 4;
int t2 = *s;
int t3 = s[3];
*(s + 3) = 0;
@ -83,8 +83,8 @@ checked int f5(int *s : itype(int checked[])) {
// Test cases where a bounds-safe interface type is implied by a bounds
// expression on an unchecked type
checked int f6(int *s : count(4)) {
array_ptr<int> t1 = s + 3;
checked int f6(int *s _Count(4)) {
int *_Array t1 = s + 3;
int t2 = *s;
int t3 = s[3];
*(s + 3) = 0;
@ -103,8 +103,8 @@ checked int f7(int *s : bounds(s, s + 4)) {
return 0;
}
checked int f8(int *s : byte_count(4 * sizeof(int))) {
array_ptr<int> t1 = s + 3;
checked int f8(int *s _Byte_count(4 * sizeof(int))) {
int *_Array t1 = s + 3;
int t2 = *s;
int t3 = s[3];
*(s + 3) = 0;
@ -113,11 +113,11 @@ checked int f8(int *s : byte_count(4 * sizeof(int))) {
return 0;
}
checked int* func10(ptr<int> p, int *q : itype(ptr<int>)) : itype(ptr<int>) {
checked int* func10(int *_Single p, int *q _Itype(int *_Single)) _Itype(int *_Single) {
int a = 5;
ptr<int> pa = &a;
ptr<int> pb = p;
ptr<int> pc = q;
int *_Single pa = &a;
int *_Single pb = p;
int *_Single pc = q;
return 0;
}
@ -137,43 +137,43 @@ int *gptr : bounds(garr, garr + 5);
int gval : bounds(garr, garr + 10);
checked void test_globals(void) {
// ptr<int>
// int *_Single
int t1 = *g1; // Allowed in checked scope.
int t2 = *(g1 + 4); // expected-error {{arithmetic on _Ptr type}}
int t3 = g1[4]; // expected-error {{subscript of '_Ptr<int>'}}
*(g1 + 4) = 0; // expected-error {{arithmetic on _Ptr type}}
g1[4] = 0; // expected-error {{subscript of '_Ptr<int>'}}
array_ptr<int> t4 : count(1) = g1;
int *_Array t4 _Count(1) = g1;
g1 = t4;
array_ptr<float> t5 : count(1) = g1; // expected-error {{incompatible type}}
array_ptr<float> t6 = 0;
float* _Array t5 _Count(1) = g1; // expected-error {{incompatible type}}
float* _Array t6 = 0;
g1 = t6; // expected-error {{incompatible type}}
// array_ptr<int> with bounds.
// int *_Array with bounds.
int t11 = *g2;
int t12 = *(g2 + 4);
int t12 = *(g2 + 4);
int t13 = g2[4];
*(g2 + 4) = 0;
g2[4] = 0;
// array_ptr<int> without bounds
array_ptr<int> t21 = g3 + 4; // allowed
// int *_Array without bounds
int *_Array t21 = g3 + 4; // allowed
int t22 = *g3; // expected-error {{expression has unknown bounds}}
int t23 = g3[4]; // expected-error {{expression has unknown bounds}}
*(g3 + 4) = 0; // expected-error {{expression has unknown bounds}}
g3[4] = 0; // expected-error {{expression has unknown bounds}}
// int checked[5]
array_ptr<int> t31 = g4 + 4;
int *_Array t31 = g4 + 4;
int t32 = *g4;
int t33 = g4[4];
*(g4 + 4) = 0;
g4[4] = 0;
// int checked[]
array_ptr<int> t41 = g5+ 4;
int *_Array t41 = g5+ 4;
int t42 = *g5; // expected-error {{expression has unknown bounds}}
int t43 = g5[4]; // expected-error {{expression has unknown bounds}}
*(g5 + 4) = 0; // expected-error {{expression has unknown bounds}}
@ -187,9 +187,8 @@ void f10(int *p : itype(ptr<int>));
void f11(int *p : count(4));
void f12(int *p : itype(array_ptr<int>));
void f13(int *p : itype(int checked[]));
void f14(int *p : itype(int checked[4]));
void f15(ptr<int> p, int *q : itype(ptr<int>));
void f14(int *p _Itype(int checked[4]));
void f15(int *_Single p, int *q _Itype(int *_Single));
extern int empty_global_arr[] : itype(int checked[]);
@ -197,7 +196,7 @@ extern int empty_global_arr[] : itype(int checked[]);
checked int test_call_parameters(void) {
ptr<int> param1 = 0;
array_ptr<int> param2 : count(4) = 0;
array_ptr<int> param3;
int *_Array param3;
int arr1 checked[4];
f10(param1);
f10(param2);
@ -243,8 +242,8 @@ checked void f11d(int *lower : itype(array_ptr<int>),
checked void f11e(char *buf : bounds(buf, end),
char *end : itype(_Array_ptr<char>));
checked void f12a(int *p : itype(array_ptr<int>));
checked void f13a(int *p : itype(int checked[]));
checked void f14a(int *p : itype(int checked[4]));
checked void f13a(int *p _Itype(int checked[]));
checked void f14a(int *p _Itype(int checked[4]));
checked void f15a(ptr<int> p, int *q : itype(ptr<int>));
@ -255,13 +254,14 @@ checked int* f20(int a checked[][5], int b checked[][5]) : itype(ptr<int>) {
return 0;
}
checked int* f21(int *a : itype(ptr<int>), int *b : itype(array_ptr<int>)) : itype(array_ptr<int>) checked {
checked int* f21(int *a _Itype(int *_Single), int *b _Itype(int *_Array))
_Itype(int *_Array) checked {
int e checked[5][5];
_Unchecked {
int *upa = f20(e, e);
}
int *upa = f20(e, e); // expected-error {{local variable in a checked scope must have a checked type}}
ptr<int> pb = f20(e, e);
int *_Single pb = f20(e, e);
return pb;
}
@ -273,7 +273,7 @@ checked int *f21b(int *b : count(4)) : byte_count(4 * sizeof(int)) {
return b;
}
checked int *f21c(int *b : count(4)) : bounds(return_value, return_value + 4) {
checked int *f21c(int *b : count(4)) _Bounds(return_value, return_value + 4) {
return b;
}
@ -287,7 +287,7 @@ checked int *f21d(int *b : count(4)) :
// Test checked return types implied by a bounds-safe interface
checked void test_checked_returns(void) {
int arr1 checked[5][5];
ptr<int> t1 = f20(arr1, arr1);
int *_Single t1 = f20(arr1, arr1);
int arr2 checked[4];
array_ptr<int> t2 = f21(0, arr2);
@ -308,7 +308,7 @@ checked int* f22() : itype(array_ptr<int>); // expected-error {{function withou
// Illegal interface types for parameters in a checked scope.
//
checked int* f23(int a[] : itype(int *), char b[] : itype(char *)) : itype(int *) checked {// expected-error 3 {{type must be a checked type}}
checked int* f23(int a[] _Itype(int *), char b[] _Itype(char *)) _Itype(int *) checked {// expected-error 3 {{type must be a checked type}}
}
//-----------------------------------------------------------------------
@ -318,7 +318,7 @@ checked int* f23(int a[] : itype(int *), char b[] : itype(char *)) : itype(int *
// Return a ptr from a checked scope for a function with a
// a bounds-safe interface return type of ptr.
int *f30(void) : itype(ptr<int>) {
int *f30(void) _Itype(int *_Single) {
checked{
ptr<int> p = 0;
return p;
@ -339,7 +339,7 @@ int *f31(int len) : count(len) {
// Return an ptr from a checked scope for a function with a
// a bounds-safe interface return type of ptr, where the
// returned value has a bounds-safe interface type.
int *f32(int * p : itype(ptr<int>)) : itype(ptr<int >) {
int *f32(int * p _Itype(int *_Single)) _Itype(ptr<int >) {
checked{
return p;
}
@ -385,7 +385,7 @@ int *f36(void) : itype(ptr<int>) {
int ga = 5;
checked int * func37(void) : itype(array_ptr<int>) _Unchecked {
checked int * func37(void) _Itype(int *_Array) _Unchecked {
int *upa = &ga;
return upa;
}
@ -402,8 +402,8 @@ checked int * func38(void) : itype(ptr<int>) _Unchecked {
#pragma CHECKED_SCOPE ON
struct S1 {
int *f1 : itype(ptr<int>);
int *f2 : count(5);
int *f3 : count(len);
int *f2 _Count(5);
int *f3 _Count(len);
int *f4 : bounds(f5, f5 + 5); // use of f5 here is intentional.
int *f5 : bounds(f5, f5 + len);
int len;
@ -523,15 +523,15 @@ struct S2 {
int *f4 : itype(array_ptr<int>);
int arr[5] : itype(int checked[5]);
// pointer to function that returns a ptr<ptr<int>>
int **((*fp1)(int *param : itype(ptr<int>))) :
itype(ptr<ptr<ptr<int>> (int *param : itype(ptr<int>))>);
int **((*fp1)(int *param _Itype(int *_Single))) :
itype(int *_Single *_Single (*_Single)(int *param _Itype(int *_Single)));
// pointer to function that returns an array_ptr<ptr<int>>
int **((*fp2)(int *param : itype(ptr<int>),int len)) :
itype(ptr<array_ptr<ptr<int>>(int *param : itype(ptr<int>), int len) : count(len)>);
};
checked int test_struct3(struct S2 *p : itype(ptr<struct S2>)) {
checked int test_struct3(struct S2 *p _Itype(ptr<struct S2>)) {
(*(p->fp1))(p->f1) + 5; // expected-error {{arithmetic on _Ptr type}}
*((*(p->fp1))(p->f1)) + 5; // expected-error {{arithmetic on _Ptr type}}
(*(p->fp2))(p->f1, 5) + 4;
@ -545,7 +545,7 @@ checked int test_struct3(struct S2 *p : itype(ptr<struct S2>)) {
}
// Unchecked version - there should be no error messages.
unchecked int test_struct4(struct S2 *p : itype(ptr<struct S2>)) {
unchecked int test_struct4(struct S2 *p _Itype(ptr<struct S2>)) {
(*(p->fp1))(p->f1) + 5;
*((*(p->fp1))(p->f1)) + 5;
(*(p->fp2))(p->f1, 5) + 4;
@ -576,7 +576,7 @@ base_with_interfaces table2[10] : itype(fnptr_interface checked[10]);
// In a checked scope, table1 and table2 are retyped as having checked types
// based on their bounds-safe interfaces. That means that the result of an
// indirect function call through table1 or table2 has typr Ptr.
checked void test1_array_of_function_pointers(ptr<int> arg1, ptr<ptr<int>> arg2, int num) {
checked void test1_array_of_function_pointers(int *_Single arg1, ptr<int *_Single> arg2, int num) {
ptr<int> result1 = (*(table1[num]))(arg1, arg2);
(*(table1[num]))(arg1, arg2) + 5; // expected-error {{arithmetic on _Ptr type}}
(*(table2[num]))(arg1, arg2);
@ -626,25 +626,25 @@ int mblen(const char *s : count(n), size_t n);
void (*signal(int sig,
void ((*func)(int)) :
itype(_Ptr<void (int)>) // bound-safe interface for func
) : itype(_Ptr<void (int)>) // bounds-safe interface for signal return
)(int);
itype(_Ptr<void (int)>) // bound-safe interface for func
) _Itype(_Ptr<void (int)>) // bounds-safe interface for signal return
)(int);
void handler(int); // for testing signal.
void test_bounds_safe_interface(void) {
array_ptr<int> arr0 : count(4) = checked_calloc(4, sizeof(size_t));
int *_Array arr0 _Count(4) = checked_calloc(4, sizeof(size_t));
for (int i = 0; i < 4; i++)
_Unchecked{
checked_malloc(arr0[i]);
}
ptr<int> arr1 = checked_malloc(10);
checked_malloc(arr0[i]);
}
int *_Single arr1 = checked_malloc(10);
#pragma CHECKED_SCOPE OFF
void *unchecked_ptr;
#pragma CHECKED_SCOPE ON
array_ptr<int> arr2 = checked_realloc(arr1, 20);
array_ptr<int> arr3 = checked_realloc(unchecked_ptr, 20); // expected-error {{local variable used in a checked scope must have a checked type}}
int *_Array arr2 = checked_realloc(arr1, 20);
int *_Array arr3 = checked_realloc(unchecked_ptr, 20); // expected-error {{local variable used in a checked scope must have a checked type}}
_Unchecked {
typedef void (*return_fn)(int);

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

@ -21,7 +21,7 @@
#include <stdchecked.h>
int printf(const char * restrict format : itype(restrict _Nt_array_ptr<const char>), ...);
int printf(const char * restrict format _Itype( const char* _Nt_array restrict ), ...);
// Test for pragma set/clear/set.
#if BOUNDS_ONLY
@ -40,18 +40,18 @@ int printf(const char * restrict format : itype(restrict _Nt_array_ptr<const cha
// 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 in a checked scope must have a checked type or a bounds-safe interface}} \
int* checked_func0(int* _Single p, int *q _Itype(int* _Single), int r[], int* _Array 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 {{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* _Single pc = p;
int* _Array pd = q;
int e[5][5]; // expected-error {{local variable in a checked scope must have a checked type}}
return upa;
}
unchecked int* unchecked_func0(ptr<int> p, int *q : itype(ptr<int>), int r[], array_ptr<int> s : count(len), int len) {
unchecked int* unchecked_func0(int* _Single p, int *q _Itype(int* _Single), int r[], int* _Array s _Count(len), int len) {
int a = 5;
int *upa = &a;
int *upb = q;
@ -62,13 +62,13 @@ 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 in a checked scope must have a checked type or a bounds-safe interface}}
int* _Array 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) {
unchecked int* _Array unchecked_func1_checked_body(int *x, int *y) {
#if BOUNDS_ONLY
#pragma CHECKED_SCOPE _Bounds_only
#else
@ -82,7 +82,7 @@ unchecked array_ptr<int> unchecked_func1_checked_body(int *x, int *y) {
return upb;
}
unchecked array_ptr<int> unchecked_func1_unchecked_body(int *x, int *y) {
unchecked int* _Array unchecked_func1_unchecked_body(int *x, int *y) {
int *upa = x;
int *upb = y;
return upb;
@ -109,12 +109,12 @@ int* checked_func2_unchecked_parm_unchecked_ret(int a [][5], int b [][5]) { // e
// 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* checked_func_check_call(int *a _Itype(int* _Single), int *b _Itype(int* _Array)) _Itype(int* _Array) {
int e checked[5][5];
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;
int* _Single pb = checked_func2_checked_parm_checked_ret(e, e);
int* _Single pc = 0;
pc = checked_func2_unchecked_parm_checked_ret(f, f);
return upa;
}
@ -235,7 +235,7 @@ int * checked_func_uc1_pragma(int *p, int *q) { // expected-error {{return in a
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 in a checked scope must have a checked type or a bounds-safe interface}}
int* _Single checked_func_u1(int *p, int* _Single q, int* _Array r, int* _Array 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;
@ -254,7 +254,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 in a checked scope must have a checked type or a bounds-safe interface}}
int* _Single checked_func_u1_pragma(int *p, int* _Single q, int* _Array r, int* _Array 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;
@ -283,7 +283,7 @@ ptr<int> checked_func_u1_pragma(int *p, ptr<int> q, array_ptr<int> r, array_ptr<
return q;
}
int * checked_func_uc(void) : itype(array_ptr<int>) unchecked {
int * checked_func_uc(void) _Itype(int* _Array) unchecked {
int a = 5;
int *upa = &a;
int b[5][5];
@ -303,7 +303,7 @@ int * checked_func_uc(void) : itype(array_ptr<int>) unchecked {
return upa;
}
int * checked_func_uc_pragma(void) : itype(array_ptr<int>) {
int * checked_func_uc_pragma(void) _Itype(int* _Array) {
#pragma CHECKED_SCOPE OFF
int a = 5;
int *upa = &a;
@ -329,7 +329,7 @@ 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 in a checked scope must have a checked type or a bounds-safe interface}}
int checked_func_ucu1(int *p, int *q, int *r _Itype(int* _Single), int *s _Itype(int* _Array)) 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;
@ -343,7 +343,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 in a checked scope must have a checked type or a bounds-safe interface}}
int checked_func_ucu1_pragma(int *p, int *q, int *r _Itype(int* _Single), int *s _Itype(int* _Array)) { // expected-error 2 {{parameter in a checked scope must have a checked type or a bounds-safe interface}}
#pragma CHECKED_SCOPE OFF
int sum = 0;
int a = 5;
@ -364,7 +364,7 @@ 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 in a checked scope must have a checked type or a bounds-safe interface}}
int checked_func_ucu2(int* _Single 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;
@ -450,8 +450,8 @@ unchecked int * unchecked_func3_checked_body(int *p, int q[]) {
unchecked array_ptr<int> unchecked_func4_unchecked_body(int p[], int q[10], int r[][10]) {
int *upa;
int *upb;
array_ptr<int> pb;
ptr<int> pc = 0;
int* _Array pb;
int* _Single pc = 0;
upa = pb; // expected-error {{assigning to 'int *' from incompatible type '_Array_ptr<int>'}}
upa = pc; // expected-error {{assigning to 'int *' from incompatible type '_Ptr<int>'}}
upb = pb; // expected-error {{assigning to 'int *' from incompatible type '_Array_ptr<int>'}}
@ -468,7 +468,7 @@ unchecked array_ptr<int> unchecked_func4_checked_body(int p[], int q[10], int r[
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;
int* _Single pc = 0;
upa = pb;
upa = pc;
upb = pb;
@ -530,8 +530,8 @@ int **a4 : itype(ptr<array_ptr<int>>) = 0;
int **a5 : itype(array_ptr<ptr<int>>) = 0;
int **a6 : itype(array_ptr<array_ptr<int>>) = 0;
int ***a7 : itype(ptr<ptr<ptr<int>>>) = 0;
int a8[10] : itype(int checked[10]);
extern int a9[] : itype(int checked[]);
int a8[10] _Itype(int checked[10]);
extern int a9[] _Itype(int checked[]);
#pragma CHECKED_SCOPE OFF
int *a10;
#if BOUNDS_ONLY
@ -575,7 +575,7 @@ struct S0 {
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}}
float *data14 _Itype(float *); // expected-error {{type must be a checked type}}
};
typedef struct _S1 {
@ -593,7 +593,7 @@ typedef struct _S1 {
#endif
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);
int* _Array pd _Count(len);
#pragma CHECKED_SCOPE OFF
#if BOUNDS_ONLY
#pragma CHECKED_SCOPE _Bounds_only
@ -633,7 +633,7 @@ int checked_func_with_checked_struct(void) {
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);
int* _Array pd _Count(len);
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;
@ -702,7 +702,7 @@ extern void variadic_func5(int cnt, ptr<int> p, ...) { // expected-error {{vari
#endif
void checked_func_call_variadic(void) {
ptr<int> a = 0;
array_ptr<int> b;
int* _Array b;
printf("check function call variadic %d\n", *a);
#pragma CHECKED_SCOPE OFF
printf("check function call variadic %d\n", *a);

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

@ -1,204 +1,204 @@
// Test type checking of generic structs.
//
// RUN: %clang_cc1 -verify -verify-ignore-unexpected=note %s
// A struct we can use with existential types.
struct Foo _For_any(T) {
T *elem;
};
// Test that we can parse existential types both as function arguments
// and in (uninitialized) expressions.
void TestParseExistentialType(_Exists(T, struct Foo<T>) exist) {
_Exists(U, struct Foo<U>) localVar;
}
// Test that we can't directly access fields of an existential:
// we need to unwrap the existential first.
void TestCantAccessFieldsInExistential(_Exists(T, struct Foo<T>) exist) {
exist.elem = 0; // expected-error {{member reference base type 'Exists(T, struct Foo<T>)' is not a structure or union}}
}
// Test that pack returns an existential type.
void TestPackReturnType() {
struct Foo<int> fooInt;
_Exists(T, struct Foo<T>) foo = _Pack(fooInt, _Exists(U, struct Foo<U>), int);
}
// Test that the type of the witness in _Pack(witness-expr, exist-type, subst-type)
// matches the given existential type.
void TestWitnessMismatch() {
struct Foo<int> fooInt;
struct Foo<struct Foo<int> > fooNested;
_Exists(T, struct Foo<T>) foo = _Pack(fooInt, _Exists(T, struct Foo<T>), int); // ok: witness and expected types match
_Pack(fooInt, _Exists(T, struct Foo<T>), char); // expected-error {{witness type does not match existential type}}
_Pack(fooNested, _Exists(T, struct Foo<T>), int); // expected-error {{witness type does not match existential type}}
_Exists(T, struct Foo<struct Foo<T> >) e = _Pack(fooNested, _Exists(T, struct Foo<struct Foo<T> >), int); // ok
_Exists(T, struct Foo<T>) e2 = _Pack(fooNested, _Exists(T, struct Foo<T>), struct Foo<int>); // ok
}
// Test that the same expression can be packed in different ways,
// if we change the substitution and return types.
void TestMultiplePacks() {
struct Foo<struct Foo<struct Foo<int> > > fooInt3;
_Pack(fooInt3, _Exists(T, struct Foo<T>), struct Foo<struct Foo<int> >); // expected-warning {{expression result unused}}
_Pack(fooInt3, _Exists(T, struct Foo<struct Foo<T> >), struct Foo<int>); // expected-warning {{expression result unused}}
_Pack(fooInt3, _Exists(T, struct Foo<T>), struct Foo<struct Foo<int> >); // expected-warning {{expression result unused}}
}
// Test different packings of a struct that contains multiple type parameters.
void TestMultipleTypeParams() {
struct Bar _For_any(A, B, C) {
};
struct Cat;
struct Dog;
struct Sheep;
struct Bar<struct Cat, struct Dog, struct Sheep> bar;
_Pack(bar, _Exists(T, struct Bar<T, struct Dog, struct Sheep>), struct Cat); // expected-warning {{expression result unused}}
_Pack(bar, _Exists(T, struct Bar<struct Cat, T, struct Sheep>), struct Dog); // expected-warning {{expression result unused}}
_Pack(bar, _Exists(T, struct Bar<struct Cat, struct Dog, T>), struct Sheep); // expected-warning {{expression result unused}}
_Pack(bar, _Exists(T, struct Bar<T, T, T>), struct Cat); // expected-error {{witness type does not match existential type}}
}
// Test that we can pack and unpack a simple generic.
void TestSimpleUnpack() {
struct Foo _For_any(A) {
A *a;
void (*op)(A*);
};
struct Foo<int> fooInt;
_Exists(T2, struct Foo<T2>) packedFoo = _Pack(fooInt, _Exists(T2, struct Foo<T2>), int);
// TODO: the error message should reference 'struct Foo<F>' and not 'struct Foo<T2>'.
// This is happening because incorrect canonicalization of existential types (and of type applications).
// Fix once that problem is fixed.
// Let's do an incorrect unpack.
// This is incorrect because _Unpack leaves 'U' abstract, so we can't recover the original
// 'int' type argument.
_Unpack (F) struct Foo<int> incorrect = packedFoo; // expected-error {{initializing 'struct Foo<int>' with an expression of incompatible type 'struct Foo<T2>'}}
// Now let's try a correct unpack.
_Unpack (U) struct Foo<U> unpackedFoo = packedFoo;
U *a2 = unpackedFoo.a;
unpackedFoo.op(a2);
}
_Exists(A, struct Foo<A>) foo1;
_Exists(A, _Exists(B, struct Foo<A>)) foo2;
_Exists(A, _Exists(B, struct Foo<B>)) foo3;
_Exists(A, _Exists(B, _Exists(C, struct Foo<int>))) foo4;
// Test that existential types can handle different levels of
// depth while still being detected as compatible.
_For_any(T) void TestCanonicalization(T *x) {
_Exists(A, struct Foo<A>) bar1;
_Exists(A, _Exists(B, struct Foo<A>)) bar2;
_Exists(A, _Exists(B, struct Foo<B>)) bar3;
_Exists(A, _Exists(B, _Exists(C, struct Foo<int>))) bar4;
bar1 = foo1;
bar2 = foo2;
bar3 = foo3;
bar4 = foo4;
foo1 = bar1;
foo2 = bar2;
foo3 = bar3;
foo4 = bar4;
foo1 = foo1;
foo2 = foo2;
foo3 = foo3;
foo4 = foo4;
bar1 = bar1;
bar2 = bar2;
bar3 = bar3;
bar4 = bar4;
// TODO: fix 'struct Foo<T>' in canonical types below after we've fixed canonicalization of type applications
bar1 = foo2; // expected-error {{assigning to 'Exists(A, struct Foo<B>)' from incompatible type 'Exists(A, Exists(B, struct Foo<T>))'}}
bar2 = foo3; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo<B>))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo<T>))') from incompatible type 'Exists(A, Exists(B, struct Foo<B>))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo<B>))')}}
bar3 = foo4; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo<B>))' from incompatible type 'Exists(A, Exists(B, Exists(C, struct Foo<int>)))'}}
bar4 = foo1; // expected-error {{assigning to 'Exists(A, Exists(B, Exists(C, struct Foo<int>)))' from incompatible type 'Exists(A, struct Foo<T>)'}}
_Exists(A, _Exists(B, struct Foo<T>)) zoom1;
zoom1 = foo2; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo<T>))' (aka 'Exists((1, 0), Exists((2, 0), struct Foo<T>))') from incompatible type 'Exists(A, Exists(B, struct Foo<T>))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo<T>))')}}
zoom1 = foo3; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo<T>))' from incompatible type 'Exists(A, Exists(B, struct Foo<B>))'}}
}
// Test that the names of bound variables inside existential types don't matter
// for compatibility purposes.
void TestAlphaEquivalence() {
struct Pair _For_any(T1, T2) {
};
_Exists(A, struct Foo<A>) a1;
_Exists(B, struct Foo<B>) a2;
a1 = a2;
a2 = a1;
_Exists(A, _Exists(B, struct Pair<int, char>)) b1;
_Exists(T1, _Exists(T2, struct Pair<int, char>)) b2;
b1 = b2;
b2 = b1;
_Exists(A, A*****) c1;
_Exists(B, B*****) c2;
c1 = c2;
c2 = c1;
struct Foo<_Exists(A, A *)> foo1;
struct Foo<_Exists(B, B *)> foo2;
foo1 = foo2;
foo2 = foo1;
_Exists(A, _Exists(B, struct Foo<_Exists(C, struct Foo<B>)>)) d1;
_Exists(T1, _Exists(T2, struct Foo<_Exists(T3, struct Foo<T2>)>)) d2;
d1 = d2;
d2 = d1;
}
// Test that parsing malformed existential types fails without
// a compiler crash.
void TestParseMalformedExistential() {
_Exists(int, T) e1; // expected-error {{expected type variable identifier}} expected-warning {{type specifier missing, defaults to 'int'}}
_Exists(int T) e2; // expected-error {{expected type variable identifier}} expected-warning {{type specifier missing, defaults to 'int'}}
_Exists(T int) e3; // expected-error {{expected ','}} expected-warning {{type specifier missing, defaults to 'int'}}
_Exists(T, int e4; // expected-error {{expected ')'}} expected-warning {{type specifier missing, defaults to 'int'}}
_Exists(T, T*)) e5; // expected-error {{expected identifier or '('}}
}
// Test that while typechecking _Pack expressions we check that the return type
// (which is the second argument to the pack) is an existential type.
// If not, we should display an error.
void TestPackReturnExpectsExistential() {
struct Foo _For_any(T) {};
struct Foo<int> fooInt;
_Exists(T, struct Foo<T>) fooExists = _Pack(fooInt, struct Foo<int>, int); // expected-error {{return type of a pack expression must be an existential type, but got 'struct Foo<int>' instead}}
}
// Test that we display an error message if the user tries
// to unpack multiple type variables (this will be supported in the future).
void TestUnpackWithMultipleTypeVars() {
struct Foo _For_any(T) {};
_Exists(T, struct Foo<T>) fooExist;
_Unpack (A, B, C) struct Foo<A> fooAbs = fooExist; // expected-error {{expected ')'}} expected-error {{expected identifier or '('}}
}
// Test that we check that the initializer to an unpack declaration
// has an existential type.
void TestUnpackRequiresExistentialInit() {
struct Foo _For_any(T) {};
struct Foo<int> fooInt;
_Exists(B, struct Foo<B>) fooExist = _Pack(fooInt, _Exists(C, struct Foo<C>), int);
_Unpack (A) struct Foo<A> fooA = fooInt; // expected-error {{unpack specifer expects an initializer that has an existential type}}
_Unpack (B) struct Foo<B> fooB = fooExist;
}
// Test that we can handle a malformed unpack specifier that's missing the type variable.
void TestUnpackMissingTypeVariable() {
struct Foo _For_any(T) {};
_Unpack (int) struct Foo<A> fooA; // expected-error {{expected type variable identifier}} expected-error {{unknown type name 'A'}}
// Test type checking of generic structs.
//
// RUN: %clang_cc1 -verify -verify-ignore-unexpected=note %s
// A struct we can use with existential types.
struct Foo _For_any(T) {
T *elem;
};
// Test that we can parse existential types both as function arguments
// and in (uninitialized) expressions.
void TestParseExistentialType(_Exists(T, struct Foo<T>) exist) {
_Exists(U, struct Foo<U>) localVar;
}
// Test that we can't directly access fields of an existential:
// we need to unwrap the existential first.
void TestCantAccessFieldsInExistential(_Exists(T, struct Foo<T>) exist) {
exist.elem = 0; // expected-error {{member reference base type 'Exists(T, struct Foo<T>)' is not a structure or union}}
}
// Test that pack returns an existential type.
void TestPackReturnType() {
struct Foo<int> fooInt;
_Exists(T, struct Foo<T>) foo = _Pack(fooInt, _Exists(U, struct Foo<U>), int);
}
// Test that the type of the witness in _Pack(witness-expr, exist-type, subst-type)
// matches the given existential type.
void TestWitnessMismatch() {
struct Foo<int> fooInt;
struct Foo<struct Foo<int> > fooNested;
_Exists(T, struct Foo<T>) foo = _Pack(fooInt, _Exists(T, struct Foo<T>), int); // ok: witness and expected types match
_Pack(fooInt, _Exists(T, struct Foo<T>), char); // expected-error {{witness type does not match existential type}}
_Pack(fooNested, _Exists(T, struct Foo<T>), int); // expected-error {{witness type does not match existential type}}
_Exists(T, struct Foo<struct Foo<T> >) e = _Pack(fooNested, _Exists(T, struct Foo<struct Foo<T> >), int); // ok
_Exists(T, struct Foo<T>) e2 = _Pack(fooNested, _Exists(T, struct Foo<T>), struct Foo<int>); // ok
}
// Test that the same expression can be packed in different ways,
// if we change the substitution and return types.
void TestMultiplePacks() {
struct Foo<struct Foo<struct Foo<int> > > fooInt3;
_Pack(fooInt3, _Exists(T, struct Foo<T>), struct Foo<struct Foo<int> >); // expected-warning {{expression result unused}}
_Pack(fooInt3, _Exists(T, struct Foo<struct Foo<T> >), struct Foo<int>); // expected-warning {{expression result unused}}
_Pack(fooInt3, _Exists(T, struct Foo<T>), struct Foo<struct Foo<int> >); // expected-warning {{expression result unused}}
}
// Test different packings of a struct that contains multiple type parameters.
void TestMultipleTypeParams() {
struct Bar _For_any(A, B, C) {
};
struct Cat;
struct Dog;
struct Sheep;
struct Bar<struct Cat, struct Dog, struct Sheep> bar;
_Pack(bar, _Exists(T, struct Bar<T, struct Dog, struct Sheep>), struct Cat); // expected-warning {{expression result unused}}
_Pack(bar, _Exists(T, struct Bar<struct Cat, T, struct Sheep>), struct Dog); // expected-warning {{expression result unused}}
_Pack(bar, _Exists(T, struct Bar<struct Cat, struct Dog, T>), struct Sheep); // expected-warning {{expression result unused}}
_Pack(bar, _Exists(T, struct Bar<T, T, T>), struct Cat); // expected-error {{witness type does not match existential type}}
}
// Test that we can pack and unpack a simple generic.
void TestSimpleUnpack() {
struct Foo _For_any(A) {
A *a;
void (*op)(A*);
};
struct Foo<int> fooInt;
_Exists(T2, struct Foo<T2>) packedFoo = _Pack(fooInt, _Exists(T2, struct Foo<T2>), int);
// TODO: the error message should reference 'struct Foo<F>' and not 'struct Foo<T2>'.
// This is happening because incorrect canonicalization of existential types (and of type applications).
// Fix once that problem is fixed.
// Let's do an incorrect unpack.
// This is incorrect because _Unpack leaves 'U' abstract, so we can't recover the original
// 'int' type argument.
_Unpack (F) struct Foo<int> incorrect = packedFoo; // expected-error {{initializing 'struct Foo<int>' with an expression of incompatible type 'struct Foo<T2>'}}
// Now let's try a correct unpack.
_Unpack (U) struct Foo<U> unpackedFoo = packedFoo;
U *a2 = unpackedFoo.a;
unpackedFoo.op(a2);
}
_Exists(A, struct Foo<A>) foo1;
_Exists(A, _Exists(B, struct Foo<A>)) foo2;
_Exists(A, _Exists(B, struct Foo<B>)) foo3;
_Exists(A, _Exists(B, _Exists(C, struct Foo<int>))) foo4;
// Test that existential types can handle different levels of
// depth while still being detected as compatible.
_For_any(T) void TestCanonicalization(T *x) {
_Exists(A, struct Foo<A>) bar1;
_Exists(A, _Exists(B, struct Foo<A>)) bar2;
_Exists(A, _Exists(B, struct Foo<B>)) bar3;
_Exists(A, _Exists(B, _Exists(C, struct Foo<int>))) bar4;
bar1 = foo1;
bar2 = foo2;
bar3 = foo3;
bar4 = foo4;
foo1 = bar1;
foo2 = bar2;
foo3 = bar3;
foo4 = bar4;
foo1 = foo1;
foo2 = foo2;
foo3 = foo3;
foo4 = foo4;
bar1 = bar1;
bar2 = bar2;
bar3 = bar3;
bar4 = bar4;
// TODO: fix 'struct Foo<T>' in canonical types below after we've fixed canonicalization of type applications
bar1 = foo2; // expected-error {{assigning to 'Exists(A, struct Foo<B>)' from incompatible type 'Exists(A, Exists(B, struct Foo<T>))'}}
bar2 = foo3; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo<B>))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo<T>))') from incompatible type 'Exists(A, Exists(B, struct Foo<B>))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo<B>))')}}
bar3 = foo4; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo<B>))' from incompatible type 'Exists(A, Exists(B, Exists(C, struct Foo<int>)))'}}
bar4 = foo1; // expected-error {{assigning to 'Exists(A, Exists(B, Exists(C, struct Foo<int>)))' from incompatible type 'Exists(A, struct Foo<T>)'}}
_Exists(A, _Exists(B, struct Foo<T>)) zoom1;
zoom1 = foo2; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo<T>))' (aka 'Exists((1, 0), Exists((2, 0), struct Foo<T>))') from incompatible type 'Exists(A, Exists(B, struct Foo<T>))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo<T>))')}}
zoom1 = foo3; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo<T>))' from incompatible type 'Exists(A, Exists(B, struct Foo<B>))'}}
}
// Test that the names of bound variables inside existential types don't matter
// for compatibility purposes.
void TestAlphaEquivalence() {
struct Pair _For_any(T1, T2) {
};
_Exists(A, struct Foo<A>) a1;
_Exists(B, struct Foo<B>) a2;
a1 = a2;
a2 = a1;
_Exists(A, _Exists(B, struct Pair<int, char>)) b1;
_Exists(T1, _Exists(T2, struct Pair<int, char>)) b2;
b1 = b2;
b2 = b1;
_Exists(A, A*****) c1;
_Exists(B, B*****) c2;
c1 = c2;
c2 = c1;
struct Foo<_Exists(A, A *)> foo1;
struct Foo<_Exists(B, B *)> foo2;
foo1 = foo2;
foo2 = foo1;
_Exists(A, _Exists(B, struct Foo<_Exists(C, struct Foo<B>)>)) d1;
_Exists(T1, _Exists(T2, struct Foo<_Exists(T3, struct Foo<T2>)>)) d2;
d1 = d2;
d2 = d1;
}
// Test that parsing malformed existential types fails without
// a compiler crash.
void TestParseMalformedExistential() {
_Exists(int, T) e1; // expected-error {{expected type variable identifier}} expected-warning {{type specifier missing, defaults to 'int'}}
_Exists(int T) e2; // expected-error {{expected type variable identifier}} expected-warning {{type specifier missing, defaults to 'int'}}
_Exists(T int) e3; // expected-error {{expected ','}} expected-warning {{type specifier missing, defaults to 'int'}}
_Exists(T, int e4; // expected-error {{expected ')'}} expected-warning {{type specifier missing, defaults to 'int'}}
_Exists(T, T*)) e5; // expected-error {{expected identifier or '('}}
}
// Test that while typechecking _Pack expressions we check that the return type
// (which is the second argument to the pack) is an existential type.
// If not, we should display an error.
void TestPackReturnExpectsExistential() {
struct Foo _For_any(T) {};
struct Foo<int> fooInt;
_Exists(T, struct Foo<T>) fooExists = _Pack(fooInt, struct Foo<int>, int); // expected-error {{return type of a pack expression must be an existential type, but got 'struct Foo<int>' instead}}
}
// Test that we display an error message if the user tries
// to unpack multiple type variables (this will be supported in the future).
void TestUnpackWithMultipleTypeVars() {
struct Foo _For_any(T) {};
_Exists(T, struct Foo<T>) fooExist;
_Unpack (A, B, C) struct Foo<A> fooAbs = fooExist; // expected-error {{expected ')'}} expected-error {{expected identifier or '('}}
}
// Test that we check that the initializer to an unpack declaration
// has an existential type.
void TestUnpackRequiresExistentialInit() {
struct Foo _For_any(T) {};
struct Foo<int> fooInt;
_Exists(B, struct Foo<B>) fooExist = _Pack(fooInt, _Exists(C, struct Foo<C>), int);
_Unpack (A) struct Foo<A> fooA = fooInt; // expected-error {{unpack specifer expects an initializer that has an existential type}}
_Unpack (B) struct Foo<B> fooB = fooExist;
}
// Test that we can handle a malformed unpack specifier that's missing the type variable.
void TestUnpackMissingTypeVariable() {
struct Foo _For_any(T) {};
_Unpack (int) struct Foo<A> fooA; // expected-error {{expected type variable identifier}} expected-error {{unknown type name 'A'}}
}

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

@ -14,7 +14,7 @@
//
//
void f1(int *p : itype(ptr<int>)) {
void f1(int *p _Itype(int* _Single)) {
}
void f2(int *p : count(len), int len) {
@ -23,7 +23,7 @@ void f2(int *p : count(len), int len) {
void f3(int *p : byte_count(len * sizeof(int)), int len) {
}
void f4(int *p : bounds(p, p + len), int len) {
void f4(int *p _Bounds(p, p + len), int len) {
}
// single-dimensional array parameters
@ -48,7 +48,7 @@ void f2_incomplete_arr(int p[] : count(len), int len) {
void f3_incomplete_arr(int p[] : byte_count(len * sizeof(int)), int len) {
}
void f4_incomplete_arr(int p[] : bounds(p, p + len), int len) {
void f4_incomplete_arr(int p[] _Bounds(p, p + len), int len) {
}
// multi-dimensional array parameters
@ -73,7 +73,7 @@ void f2_incomplete_md_arr(int p[][10] : count(len), int len) {
void f3_incomplete_md_arr(int p[][10] : byte_count(len * sizeof(int[10])), int len) {
}
void f4_incomplete_md_arr(int p[][10] : bounds(p, p + len), int len) {
void f4_incomplete_md_arr(int p[][10] _Bounds(p, p + len), int len) {
}
// void * parameters with interop declarations. Note that count bounds
@ -88,7 +88,7 @@ void f2_void(void *p : count(len), int len) { // expected-error {{expected 'p' t
void f3_void(void *p : byte_count(len * sizeof(int)), int len) {
}
void f4_void(void *p : bounds(p, (char *)p + len), int len) {
void f4_void(void *p _Bounds(p, (char *)p + len), int len) {
}
void g1(ptr<int> p) {
@ -158,7 +158,7 @@ void g2_complete_array_arg(void) {
// Test passing multi-diemensional arrays through bounds-safe
// interfaces.
void g2_md(array_ptr<int checked[10]> ap : count(len), int len) {
void g2_md(int (* _Array ap) checked[10] _Count(len), int len) {
if (len >= 10) {
f1_complete_md_arr(ap); // expected-error {{it is not possible to prove argument meets declared bounds for 1st parameter}}
f2_complete_md_arr(ap); // expected-error {{it is not possible to prove argument meets declared bounds for 1st parameter}}
@ -172,7 +172,7 @@ void g2_md(array_ptr<int checked[10]> ap : count(len), int len) {
f4_incomplete_md_arr(ap, len);
}
void g2_incomplete_md_array_param(int ap checked[][10] : count(len), int len) {
void g2_incomplete_md_array_param(int ap checked[][10] _Count(len), int len) {
f1_incomplete_md_arr(ap);
f2_incomplete_md_arr(ap, len);
f3_incomplete_md_arr(ap, len);
@ -217,7 +217,7 @@ void g3(ptr<float> p) {
f1(p); // expected-error {{incompatible type}}
}
void g4(array_ptr<float> ap : count(len), int len) {
void g4(float* _Array ap _Count(len), int len) {
f2(ap, len); // expected-error {{incompatible type}}
f3(ap, len); // expected-error {{incompatible type}}
f4(ap, len); // expected-error {{incompatible type}}
@ -261,10 +261,10 @@ void f1_const(const int *p : itype(ptr<const int>)) {
void f2_const(const int *p : count(len), int len) {
}
void f3_const(const int *p : byte_count(len * sizeof(int)), int len) {
void f3_const(const int *p _Byte_count(len * sizeof(int)), int len) {
}
void f4_const(const int *p : bounds(p, p + len), int len) {
void f4_const(const int *p _Bounds(p, p + len), int len) {
}
// Pointers to non-const qualified data can be passed to parameters that are pointers
@ -278,7 +278,7 @@ void g10(ptr<const int> p) {
f1_const(p);
}
void g11(array_ptr<int> ap : count(len), int len) {
void g11(int* _Array ap _Count(len), int len) {
f2_const(ap, len);
f3_const(ap, len);
f4_const(ap, len);
@ -346,7 +346,7 @@ void g20(ptr<int> p) {
v1 = p;
}
void g21(array_ptr<int> ap : count(10)) {
void g21(int* _Array ap _Count(10)) {
v2 = ap;
v3 = ap;
v4 = ap;
@ -363,7 +363,7 @@ void g22(ptr<float> p) {
v1 = p; // expected-error {{incompatible type}}
}
void g23(array_ptr<float> ap : count(10)) {
void g23(float* _Array ap _Count(10)) {
v2 = ap; // expected-error {{incompatible type}}
v3 = ap; // expected-error {{incompatible type}}
v4 = ap; // expected-error {{incompatible type}}
@ -387,7 +387,7 @@ void g26(ptr<void> p) {
v1_void = p;
}
void g27(array_ptr<void> ap : byte_count(10 * sizeof(int))) {
void g27(void* _Array ap _Byte_count(10 * sizeof(int))) {
v3 = ap;
v4 = ap;
v3_void = ap;
@ -411,10 +411,10 @@ void g30(ptr<int> p) {
const_v1 = p;
}
void g31(array_ptr<int> ap : count(10)) {
const_v2 = ap;
const_v3 = ap;
const_v4 = ap; // expected-error {{it is not possible to prove that the inferred bounds of 'const_v4' imply the declared bounds of 'const_v4' after assignment}}
void g31(int* _Array ap _Count(10)) {
const_v2 = ap;
const_v3 = ap;
const_v4 = ap; // expected-error {{it is not possible to prove that the inferred bounds of 'const_v4' imply the declared bounds of 'const_v4' after assignment}}
}
// Pointers to const-data should not be assigned to pointers to non-const qualified
@ -434,7 +434,7 @@ void g34(ptr<int> p) {
v1_const = p; // expected-error {{cannot assign to variable}}
}
void g35(array_ptr<int> ap : count(10)) {
void g35(int* _Array ap _Count(10)) {
v2_const = ap; // expected-error {{cannot assign to variable 'v2_const' with const-qualified}}
v3_const = ap; // expected-error {{cannot assign to variable 'v3_const' with const-qualified}}
v4_const = ap; // expected-error {{cannot assign to variable 'v4_const' with const-qualified}}
@ -460,7 +460,7 @@ struct S1_void {
void *arr3 : bounds(arr3, (char *) arr3 + 10 * sizeof(int));
};
void g40(ptr<struct S1> p, ptr<int> p1, array_ptr<int> p2 : count(10)) {
void g40(struct S1* _Single p, int* _Single p1, int* _Array p2 _Count(10)) {
p->pint = p1;
p->arr1 = p2;
p->arr2 = p2;
@ -529,7 +529,7 @@ struct S3 {
int *const arr3 : bounds(arr3, arr3 + 10);
};
void g47(ptr<struct S3> p, ptr<int> p1, array_ptr<int> p2 : count(10)) {
void g47(struct S3* _Single p, void* _Single p1, int* _Array p2 _Count(10)) {
p->pint = p1; // expected-error {{cannot assign to non-static data member 'pint' with const-qualified type }}
p->arr1 = p2; // expected-error {{cannot assign to non-static data member 'arr1' with const-qualified type}}
p->arr2 = p2; // expected-error {{cannot assign to non-static data member 'arr2' with const-qualified type}}
@ -615,7 +615,7 @@ void g82(callback_fn3 fn) {
// Assign a checked pointer to the dereference of an
// unchecked pointer with a bounds-safe interface.
void g90(int **interop_ptr : itype(array_ptr<ptr<int>>) count(3), ptr<int> checked_ptr) {
void g90(int **interop_ptr _Itype(array_ptr<ptr<int>>) count(3), int* _Single checked_ptr) {
*interop_ptr = checked_ptr;
*(interop_ptr - 1) = checked_ptr;
*(2 + interop_ptr) = checked_ptr;

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

@ -10,7 +10,7 @@ _Itype_for_any(T) void* oneTypeVariable(void* a : itype(_Ptr<T>), void* b : ityp
return a;
}
_Itype_for_any(T, Q) void* manyTypeVariables(void* a : itype(_Ptr<T>), void* b : itype(_Ptr<Q>)) : itype(_Ptr<Q>) {
_Itype_for_any(T, Q) void* manyTypeVariables(void* a _Itype(T* _Single), void* b _Itype(Q* _Single)) _Itype(Q* _Single) {
return b;
}
@ -19,13 +19,12 @@ _Itype_for_any(T)
void* validItypeGenericFunction(int a, void* b : itype(_Ptr<T>), void* c : itype(_Ptr<T>)) : itype(_Ptr<T>);
_Itype_for_any(T)
void* validItypeGenericFunction(int a, void* b : itype(_Ptr<T>) , void* c : itype(_Ptr<T>) ) : itype(_Ptr<T>) {
_Ptr<T> m = b;
void* validItypeGenericFunction(int a, void* b _Itype(T* _Single) , void* c _Itype(T* _Single) ) _Itype(T* _Single) {
T* _Single m = b;
return m;
}
void CallItypeGenericFunctions(void) {
int a = 0, b = 0, c = 0, d = 0;
_Ptr<int> ap = &a;

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

@ -37,7 +37,7 @@ void f4(void) unchecked {
// Test you can always `free` a `malloc`d ptr
void f11(void) {
ptr<int> x = malloc<int>(sizeof(int));
int* _Single x = malloc _TyArgs(int) (sizeof(int));
free<int>(x);
}
@ -78,9 +78,9 @@ void f22(void) {
// Test you can always `free` a `realloc`d array_ptr
void f23(void) {
array_ptr<int> x : count(4) = malloc<int>(4 * sizeof(int));
array_ptr<int> y : count(8) = realloc<int>(x, 8 * sizeof(int));
free<int>(y);
int* _Array x _Count(4) = malloc _TyArgs(int) (4 * sizeof(int));
int* _Array y _Count(8) = realloc _TyArgs(int) (x, 8 * sizeof(int));
free _TyArgs(int) (y);
}
// Test you can always `free` a `aligned_alloc`d array_ptr

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

@ -81,7 +81,7 @@ union U7 {
// embedded in objects.
//
extern ptr<int> f1(); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
extern int* _Single f1(); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
extern array_ptr<int> f2();// expected-error {{function with no prototype cannot have a return type that is a checked type}}
extern struct S1 f3(); // expected-error {{function with no prototype cannot have a return type that is a structure with a member with a checked type}}
extern struct S2 f4(); // expected-error {{function with no prototype cannot have a return type that is a structure with a member with a checked type}}
@ -106,7 +106,7 @@ extern int (*f19())(ptr<int>); // expected-error {{function with no prototype c
// Returns an unchecked pointer to a no-prototype function returning a checked
// value (ptr<int>)
extern ptr<int> (*f20(void))(); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
extern int* _Single (*f20(void))(); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
// Returns a checked pointer to a function with a checked argument (ptr<int>)
extern ptr<int (ptr<int>)> f21(); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
@ -120,7 +120,7 @@ extern ptr<int (ptr<int>)> f21(); // expected-error {{function with no prototype
// pointers to function types that take or return checked values.
extern ptr<int> *f30();
extern array_ptr<int> *f31();
extern int* _Array *f31();
extern struct S1 *f32();
extern struct S2 *f33();
extern struct S3 *f34();
@ -139,7 +139,7 @@ extern struct S9 *f41();
extern array_ptr<int> f50() : count(5); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
extern int f51() : byte_count(10);
extern int *f52() : byte_count(10);
extern int *f53() : itype(ptr<int>);
extern int *f53() _Itype(ptr<int>);
// No prototype functions cannot be redeclared to take arguments that are
// checked values or objects with checked values embedded within them.
@ -148,7 +148,7 @@ extern void f60();
extern void f60(ptr<int>); // expected-error {{cannot redeclare a function with no prototype to have an argument type that is a checked type}}
extern void f61();
extern void f61(array_ptr<int>); // expected-error {{cannot redeclare a function with no prototype to have an argument type that is a checked type}}
extern void f61(int* _Array); // expected-error {{cannot redeclare a function with no prototype to have an argument type that is a checked type}}
extern void f62();
extern void f62(struct S1); // expected-error {{cannot redeclare a function with no prototype to have an argument type that is a structure with a member with a checked type}}
@ -202,7 +202,7 @@ extern void f80(int checked[]); // expected-error {{cannot redeclare a function
// Function type arguments.
extern void f81();
extern void f81(ptr<int> f(void)); // expected-error {{cannot redeclare a function with no prototype to have an argument type that is a checked type}}
extern void f81(int* _Single f(void)); // expected-error {{cannot redeclare a function with no prototype to have an argument type that is a checked type}}
extern void f82();
extern void f82(int f(ptr<int>)); // expected-error {{cannot redeclare a function with no prototype to have an argument type that is a checked type}}
@ -216,7 +216,7 @@ extern void f84(int f()); // expected-error {{conflicting types for 'f84'}}
// No prototype functions can be redeclared with bounds-safe interfaces on integer and
// unchecked pointer arguments.
extern void f85();
extern void f85(char *p : bounds(p, p + len), int len);
extern void f85(char *p _Bounds(p, p + len), int len);
//
// Redeclaring a function with a checked argument as a no prototype function is not allowed.
@ -236,10 +236,10 @@ extern void f91();
//
struct S20 {
ptr<int> (*f)(); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
int* _Single (*f)(); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
};
typedef ptr<int> functype1(); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
typedef int* _Single functype1(); // expected-error {{function with no prototype cannot have a return type that is a checked type}}
// Check the obscure case of a function being declared as a no-prototype, then
// being declared to have a prototype with an incomplete type, and then
@ -249,7 +249,7 @@ struct S21;
extern void f100();
extern void f100(struct S21);
struct S21 {
ptr<int> m;
int* _Single m;
};
extern void f100(struct S21 x) { // expected-error {{cannot redeclare a function with no prototype to have an argument type that is a structure with a member with a checked type}}

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

@ -1,32 +1,32 @@
// Feature tests of typechecking new Checked C bounds declarations.
//
// The following lines are for the LLVM test harness:
//
// RUN: %clang_cc1 -Wno-check-bounds-decls -verify -verify-ignore-unexpected=note %s
#include <stdchecked.h>
_Static_assert(sizeof(void*) > sizeof(int),
"Pointers must be larger than ints");
enum E1 {
EnumVal1,
EnumVal2
};
void int_local_var_bounds_decl(void) {
// bounds declarations are allowed for integer variables to support
// casting of pointers to integers and back. We usually expect this
// to happen within expressions, but to allow uniform use of language
// features, we allow bounds on integer-typed variables.
int a1 checked[5];
// byte_count
int t21 : byte_count(5 * sizeof(int)) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
// bounds
int t25 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
long int t26 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
unsigned long int t27 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
enum E1 t28 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
}
// Feature tests of typechecking new Checked C bounds declarations.
//
// The following lines are for the LLVM test harness:
//
// RUN: %clang_cc1 -Wno-check-bounds-decls -verify -verify-ignore-unexpected=note %s
#include <stdchecked.h>
_Static_assert(sizeof(void*) > sizeof(int),
"Pointers must be larger than ints");
enum E1 {
EnumVal1,
EnumVal2
};
void int_local_var_bounds_decl(void) {
// bounds declarations are allowed for integer variables to support
// casting of pointers to integers and back. We usually expect this
// to happen within expressions, but to allow uniform use of language
// features, we allow bounds on integer-typed variables.
int a1 checked[5];
// byte_count
int t21 _Byte_count(5 * sizeof(int)) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
// bounds
int t25 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
long int t26 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
unsigned long int t27 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
enum E1 t28 _Bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr<int>'}}
}

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

@ -1,21 +1,21 @@
// Feature tests of typechecking new Checked C bounds declarations.
//
// The following lines are for the LLVM test harness:
//
// RUN: %clang_cc1 -Wno-check-bounds-decls -verify -verify-ignore-unexpected=note %s
#include <stdchecked.h>
_Static_assert(sizeof(void*) > sizeof(long),
"Pointers must be larger than longs");
void int_local_var_bounds_decl(void) {
// bounds declarations are allowed for integer variables to support
// casting of pointers to integers and back. We usually expect this
// to happen within expressions, but to allow uniform use of language
// features, we allow bounds on integer-typed variables.
int a1 checked[5];
long int t22 : byte_count(5 * sizeof(int)) = (long int)a1; // expected-warning {{cast to smaller integer type 'long' from '_Array_ptr<int>'}}
unsigned long int t23 : byte_count(5 * sizeof(int)) = (unsigned long int) a1; // expected-warning {{cast to smaller integer type 'unsigned long' from '_Array_ptr<int>'}}
}
// Feature tests of typechecking new Checked C bounds declarations.
//
// The following lines are for the LLVM test harness:
//
// RUN: %clang_cc1 -Wno-check-bounds-decls -verify -verify-ignore-unexpected=note %s
#include <stdchecked.h>
_Static_assert(sizeof(void*) > sizeof(long),
"Pointers must be larger than longs");
void int_local_var_bounds_decl(void) {
// bounds declarations are allowed for integer variables to support
// casting of pointers to integers and back. We usually expect this
// to happen within expressions, but to allow uniform use of language
// features, we allow bounds on integer-typed variables.
int a1 checked[5];
long int t22 : byte_count(5 * sizeof(int)) = (long int)a1; // expected-warning {{cast to smaller integer type 'long' from '_Array_ptr<int>'}}
unsigned long int t23 : byte_count(5 * sizeof(int)) = (unsigned long int) a1; // expected-warning {{cast to smaller integer type 'unsigned long' from '_Array_ptr<int>'}}
}

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

@ -11,7 +11,7 @@ int f0(int a) {
return a;
}
void local_convert(int(*f1)(int), ptr<int(int)> f2) {
void local_convert(int(*f1)(int), int (*_Single f2)(int)) {
// There's no good reason to do this to any function pointers
// and it's definitely not safe.
ptr<int(int)> local_weird_unsafe1 = (ptr<int(int)>)~(long)f1; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr<int (int)>'}}
@ -24,7 +24,7 @@ void local_convert(int(*f1)(int), ptr<int(int)> f2) {
ptr<int(int)> local_weird_unsafe8 = (ptr<int(int)>) + (long)f2; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr<int (int)>'}}
ptr<int(int)> local_weird_unsafe9 = (ptr<int(int)>) + (long)f0; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr<int (int)>'}}
ptr<int(int)> local_weird_unsafe10 = (ptr<int(int)>) - (long)f1; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr<int (int)>'}}
ptr<int(int)> local_weird_unsafe11 = (ptr<int(int)>) - (long)f2; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr<int (int)>'}}
ptr<int(int)> local_weird_unsafe12 = (ptr<int(int)>) - (long)f0; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr<int (int)>'}}
int (*_Single local_weird_unsafe11)(int) = (int (*_Single )(int)) - (long)f2; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr<int (int)>'}}
int (*_Single local_weird_unsafe12)(int) = (int (*_Single )(int)) - (long)f0; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr<int (int)>'}}
}

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

@ -14,7 +14,7 @@ _Static_assert(sizeof(void*) == sizeof(long),
struct S1 {
int len;
// bound declaration on a long-typed member.
long p : bounds((char *)p, (char *)p + len);
long p _Bounds((char *)p, (char *)p + len);
};
extern struct S1 f1(); // expected-error {{function with no prototype cannot have a return type that is a structure with a member with a checked type}}
@ -25,7 +25,7 @@ extern void f2(struct S1); // expected-error {{cannot redeclare a function with
extern void f3();
extern void f3(long p : bounds((char *)p, (char *)p + len), int len);
extern void f4(long p : bounds((char *)p, (char *)p + len), int len);
extern void f4(long p _Bounds((char *)p, (char *)p + len), int len);
extern void f4();
//
@ -70,6 +70,7 @@ extern int f10(int a, _Array_ptr<int> b,
// expected-warning 2 {{cast to '_Array_ptr<int>' from smaller integer type 'short'}} \
// expected-warning 2 {{cast to smaller integer type 'short' from '_Array_ptr<int>'}}
extern int f11(int a, _Array_ptr<int> b, _Array_ptr<char> p : bounds(b, b + a));
extern int f11(int a, _Array_ptr<int> b,
_Array_ptr<char> p : bounds(b, (_Array_ptr<int>) (void *) (long) b + a));
extern int f11(int a, int* _Array b, char* _Array p _Bounds(b, b + a));
extern int f11(int a, int* _Array b,
char* _Array p _Bounds(b, (int* _Array) (void *) (long) b + a));

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

@ -13,11 +13,11 @@ extern void check_indirection_unsafe_ptr(int *p, const int *const_p, int y) {
y = *const_p;
}
extern void check_indirection_ptr(ptr<int> p, ptr<const int> const_p, int y) {
*p = y;
y = *p;
*const_p = y; // expected-error {{read-only variable is not assignable}}
y = *const_p;
extern void check_indirection_ptr(int* _Single p, const int *_Single const_p, int y) {
*p = y;
y = *p;
*const_p = y; // expected-error {{read-only variable is not assignable}}
y = *const_p;
}
extern void check_indirection_array_ptr(array_ptr<int> p : count(1),
@ -84,17 +84,17 @@ extern void check_subscript_nt_array_ptr(nt_array_ptr<int> p : count(1),
// Test restrictions on null-terminated pointer types.
void check_nullterm_restrictions(void) {
nt_array_ptr<int> t1 = 0; // integer types are OK.
nt_array_ptr<ptr<int>> t2 = 0; // pointer types are OK.
int* _Nt_array t1 = 0; // integer types are OK.
int* _Single *_Nt_array t2 = 0; // pointer types are OK.
enum E { Null, Blue, White };
nt_array_ptr<enum E> t3 = 0; // enum types are OK
enum E* _Nt_array t3 = 0; // enum types are OK
nt_array_ptr<void> t10 = 0; // expected-error {{only integer and pointer types are allowed}}
nt_array_ptr<float> t11 = 0; // expected-error {{only integer and pointer types are allowed}}
nt_array_ptr<double> t12 = 0; // expected-error {{only integer and pointer types are allowed}}
nt_array_ptr<int checked[5]> t13 = 0; // expected-error {{only integer and pointer types are allowed}}
void* _Nt_array t10 = 0; // expected-error {{only integer and pointer types are allowed}}
float* _Nt_array t11 = 0; // expected-error {{only integer and pointer types are allowed}}
double* _Nt_array t12 = 0; // expected-error {{only integer and pointer types are allowed}}
int* _Nt_array t13 checked[5] = 0; // expected-error {{array initializer must be an initializer list}}
struct S { int i; };
nt_array_ptr<struct S> t14 = 0; // expected-error {{only integer and pointer types are allowed}}
struct S* _Nt_array t14 = 0; // expected-error {{only integer and pointer types are allowed}}
}
@ -120,13 +120,13 @@ extern void check_assign(int val, int *p, ptr<int> q, array_ptr<int> r,
// T * = nt_array_ptr<T> not OK
ptr<int> t8 = r; // expected-error {{expression has unknown bounds}}
// ptr<T> = array_ptr<T> OK
ptr<int> t8a = v; // ptr<T> = nt_array_ptr<T> OK.
array_ptr<int> t9 = q; // array_ptr<T> = ptr<T> OK
array_ptr<int> t10a = v; // array_ptr<T> = nt_array_ptr<T> OK.
nt_array_ptr<int> t10b = q; // expected-error {{incompatible type}}
// nt_array_ptr<T> = ptr<T> not OK.
nt_array_ptr<int> t10ca = r; // expected-error {{incompatible type}}
// nt_array_ptr<T> = array_ptr<T> not OK.
int* _Single t8a = v; // ptr<T> = nt_array_ptr<T> OK.
int* _Array t9 = q; // array_ptr<T> = ptr<T> OK
int* _Array t10a = v; // array_ptr<T> = nt_array_ptr<T> OK.
int* _Nt_array t10b = q; // expected-error {{incompatible type}}
// nt_array_ptr<T> = ptr<T> not OK.
int* _Nt_array t10ca = r; // expected-error {{incompatible type}}
// nt_array_ptr<T> = array_ptr<T> not OK.
// check assigning different kinds of pointers with different referent
// types
@ -172,7 +172,7 @@ extern void check_assign(int val, int *p, ptr<int> q, array_ptr<int> r,
// array_ptr<T> = S * not OK;
array_ptr<float> t25 = q; // expected-error {{incompatible type}}
// array_ptr<T> = ptr<S> not OK;
array_ptr<float> t26 = r; // expected-error {{incompatible type}}
float* _Array t26 = r; // expected-error {{incompatible type}}
// array_ptr<T> = array_ptr<S> not OK
// C compilers enforcing C99 conversion rules allow implicit
@ -210,8 +210,8 @@ extern void check_assign(int val, int *p, ptr<int> q, array_ptr<int> r,
ptr<int> t38 = (_Bool)(1); // expected-error {{incompatible type}}
ptr<float> t39 = (_Bool)(1); // expected-error {{incompatible type}}
array_ptr<int> t40 = (_Bool)(1); // expected-error {{incompatible type}}
array_ptr<float> t41 = (_Bool)(1); // expected-error {{incompatible type}}
nt_array_ptr<int> t41a = (_Bool)(1); // expected-error {{incompatible type}}
float* _Array t41 = (_Bool)(1); // expected-error {{incompatible type}}
int* _Nt_array t41a = (_Bool)(1); // expected-error {{incompatible type}}
// Implicit conversion of 0 to a safe pointer type is OK.
ptr<int> t42 = 0;
@ -242,7 +242,7 @@ extern void check_assign(int val, int *p, ptr<int> q, array_ptr<int> r,
array_ptr<int> t53 = unchecked_ptr_to_checked_ptr; // expected-error {{incompatible type}}
array_ptr<int> t54 = checked_ptr_to_checked_ptr; // expected-error {{incompatible type}}
array_ptr<int> t56 = array_ptr_to_checked_ptr; // expected-error {{incompatible type}}
int* _Array t56 = array_ptr_to_checked_ptr; // expected-error {{incompatible type}}
unchecked_ptr_to_checked_ptr = q; // expected-error {{incompatible type}}
checked_ptr_to_checked_ptr = p; // expected-error {{incompatible type}}
@ -336,12 +336,12 @@ check_assign_void_unchecked(int val, int *p, ptr<int> q,
array_ptr<int> t25 = u;
nt_array_ptr<int> t25a = (void *)&val; // expected-error {{incompatible type}}
// nt_array_ptr<int> = void * not OK.
nt_array_ptr<int> t25b = s; // expected-error {{incompatible type}}
// nt_array_ptr<int> = void * not OK, even with obunds
nt_array_ptr<int> t25c = t; // expected-error {{incompatible type}}
// nt_array_ptr<int> = ptr<void> not OK.
nt_array_ptr<int> t25d = u; // expected-error {{incompatible type}}
// nt_array_ptr<int> = array_ptr<void> not OK.
int* _Nt_array t25b = s; // expected-error {{incompatible type}}
// int* _Nt_array = void * not OK, even with obunds
int* _Nt_array t25c = t; // expected-error {{incompatible type}}
// int* _Nt_array = void* _Single not OK.
int* _Nt_array t25d = u; // expected-error {{incompatible type}}
// int* _Nt_array = void* _Array not OK.
// conversions between integers and safe void pointers.
int t26 = t; // expected-error {{incompatible type}}
// int = ptr<void> not OK;
@ -367,8 +367,8 @@ check_assign_void_unchecked(int val, int *p, ptr<int> q,
array_ptr<void> t35 = (_Bool)(1); // expected-error {{incompatible type}}
// Implicit conversion of 0 to a safe void pointer type is OK.
ptr<void> t37 = 0;
array_ptr<void> t38 = 0;
void* _Single t37 = 0;
void* _Array t38 = 0;
}
// Test assignments between different kinds of pointers where the
@ -377,7 +377,7 @@ check_assign_void_unchecked(int val, int *p, ptr<int> q,
// Checked scope
struct CheckedData1 {
int len;
array_ptr<int> p : count(len);
int* _Array p : count(len);
};
extern void
@ -1214,8 +1214,8 @@ extern void check_call(void) {
int val = 0;
float fval = 0.0;
int *p = 0;
ptr<int> q = 0;
array_ptr<int> r : count(1) = 0;
int* _Single q = 0;
int* _Array r : count(1) = 0;
float *s = 0;
@ -1523,12 +1523,12 @@ extern void check_call_void_checked(void) checked {
extern void check_call_void_checked_bounds_only(void) checked bounds_only {
int val = 0;
float fval = 0.0;
ptr<int> q = 0;
array_ptr<int> r : count(1) = 0;
int* _Single q = 0;
int* _Array r : count(1) = 0;
ptr<struct CheckedData1> s = 0;
ptr<void> t = 0;
array_ptr<void> u : byte_count(sizeof(struct CheckedData1)) = 0;
nt_array_ptr<int> v : count(1) = 0;
void* _Single t = 0;
void* _Array u : byte_count(sizeof(struct CheckedData1)) = 0;
int* _Nt_array v : count(1) = 0;
// Test different kinds of pointers where the parameter type is a pointer to void and
// the referent type is not a void pointer.
@ -1832,7 +1832,7 @@ array_ptr<void> check_voidptr_return21(int *p) {
return p;
}
array_ptr<void> check_voidptr_return21a(int *p) : byte_count(sizeof(int)) {
void* _Array check_voidptr_return21a(int *p) : byte_count(sizeof(int)) {
return p; // expected-error {{return value has unknown bounds, bounds expected because the function 'check_voidptr_return21a' has bounds}}
}
@ -1874,7 +1874,7 @@ array_ptr<void> check_voidptr_return28(nt_array_ptr<int> p : count(1)) {
return p;
}
array_ptr<void> check_voidptr_return29(ptr<struct CheckedData1> p) {
void* _Array check_voidptr_return29(ptr<struct CheckedData1> p) {
return p;
}
@ -2483,8 +2483,8 @@ void check_pointer_equality_compare(void)
array_ptr<void> r_void = val_int;
array_ptr<void> r2_void = val_int;
nt_array_ptr<int> s_int = 0;
nt_array_ptr<int> s2_int = 0;
int* _Nt_array s_int = 0;
int* _Nt_array s2_int = 0;
nt_array_ptr<char> s_char = 0;
// equality/inequality comparisons using different kinds of pointers to float
@ -2762,8 +2762,8 @@ void check_illegal_operators(void)
int val[5];
int *p = val;
ptr<int> q = &val[0];
array_ptr<int> r = val;
nt_array_ptr<int> s = 0;
int* _Array r = val;
int* _Nt_array s = 0;
p * 5; // expected-error {{invalid operands to binary expression}}
5 * p; // expected-error {{invalid operands to binary expression}}
@ -3051,9 +3051,9 @@ extern void test_sprintf(char *s);
void check_address_of_types(char s[10],
char *c : itype(char _Checked[10]),
char buf _Nt_checked[],
_Nt_array_ptr<char> str,
_Array_ptr<char> arr : count(10),
_Ptr<char> p) {
char* _Nt_array str,
char* _Array arr : count(10),
char* _Single p) {
_Unchecked {
test_sprintf(s);
test_sprintf(&*s);

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

@ -1,59 +1,59 @@
// Test type checking of static variables.
// Static variable declarations should not use free type variables.
//
// RUN: %clang_cc1 -verify %s
struct S _For_any(X, Y, Z) { };
// Global static variable declarations can use bound type variables.
static _Exists(T, struct S<T, T, T>) gs;
//
// Test that declarations of static variables cannot use free type variables.
//
_For_any(T, U, V) void f1(_Ptr<T> pt, struct S<T, U, V> s) {
static T t; // expected-error {{static variable 't' has a type that uses a type variable bound in an enclosing scope (type is 'T' and type variable is 'T')}} \
// expected-note@15 {{type variable 'T' declared here}}
static _Ptr<U> p; // expected-error {{static variable 'p' has a type that uses a type variable bound in an enclosing scope (type is '_Ptr<U>' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}}
static _Array_ptr<V> a1; // expected-error {{static variable 'a1' has a type that uses a type variable bound in an enclosing scope (type is '_Array_ptr<V>' and type variable is 'V')}} \
// expected-note@15 {{type variable 'V' declared here}}
static _Array_ptr<_Array_ptr<T>> a2; // expected-error {{static variable 'a2' has a type that uses a type variable bound in an enclosing scope (type is '_Array_ptr<_Array_ptr<T>>' and type variable is 'T')}} \
// expected-note@15 {{type variable 'T' declared here}}
static struct S<T, U, T> s1; // expected-error {{static variable 's1' has a type that uses a type variable bound in an enclosing scope (type is 'struct S<T, U, T>' and type variable is 'T')}} \
// expected-note@15 {{type variable 'T' declared here}} \
// expected-error {{static variable 's1' has a type that uses a type variable bound in an enclosing scope (type is 'struct S<T, U, T>' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}}
static _Exists(T, _Ptr<U>) e1; // expected-error {{static variable 'e1' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(T, _Ptr<U>)' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}}
static _Exists(T, struct S<T, U, V>) e2; // expected-error {{static variable 'e2' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(T, struct S<T, U, V>)' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}} \
// expected-error {{static variable 'e2' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(T, struct S<T, U, V>)' and type variable is 'V')}} \
// expected-note@15 {{type variable 'V' declared here}}
static _Exists(A, struct S<T, U, V>) e3; // expected-error {{static variable 'e3' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(A, struct S<T, U, V>)' and type variable is 'T')}} \
// expected-note@15 {{type variable 'T' declared here}} \
// expected-error {{static variable 'e3' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(A, struct S<T, U, V>)' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}} \
// expected-error {{static variable 'e3' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(A, struct S<T, U, V>)' and type variable is 'V')}} \
// expected-note@15 {{type variable 'V' declared here}}
// Static variable declarations can use integral and pointer types and bound type variables.
static int i;
static struct S<char, _Ptr<int>, double> s2;
static _Exists(T, _Ptr<T>) e4;
static _Exists(A, struct S<A, _Ptr<A>, _Array_ptr<A>>) e5;
// Non-static variable declarations can use free type variables.
_Ptr<T> q = 0;
_Array_ptr<_Array_ptr<U>> a3;
struct S<T, U, V> s3;
_Exists(U, _Ptr<T>) e6;
}
// Test type checking of static variables.
// Static variable declarations should not use free type variables.
//
// RUN: %clang_cc1 -verify %s
struct S _For_any(X, Y, Z) { };
// Global static variable declarations can use bound type variables.
static _Exists(T, struct S<T, T, T>) gs;
//
// Test that declarations of static variables cannot use free type variables.
//
_For_any(T, U, V) void f1(_Ptr<T> pt, struct S<T, U, V> s) {
static T t; // expected-error {{static variable 't' has a type that uses a type variable bound in an enclosing scope (type is 'T' and type variable is 'T')}} \
// expected-note@15 {{type variable 'T' declared here}}
static _Ptr<U> p; // expected-error {{static variable 'p' has a type that uses a type variable bound in an enclosing scope (type is '_Ptr<U>' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}}
static _Array_ptr<V> a1; // expected-error {{static variable 'a1' has a type that uses a type variable bound in an enclosing scope (type is '_Array_ptr<V>' and type variable is 'V')}} \
// expected-note@15 {{type variable 'V' declared here}}
static _Array_ptr<_Array_ptr<T>> a2; // expected-error {{static variable 'a2' has a type that uses a type variable bound in an enclosing scope (type is '_Array_ptr<_Array_ptr<T>>' and type variable is 'T')}} \
// expected-note@15 {{type variable 'T' declared here}}
static struct S<T, U, T> s1; // expected-error {{static variable 's1' has a type that uses a type variable bound in an enclosing scope (type is 'struct S<T, U, T>' and type variable is 'T')}} \
// expected-note@15 {{type variable 'T' declared here}} \
// expected-error {{static variable 's1' has a type that uses a type variable bound in an enclosing scope (type is 'struct S<T, U, T>' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}}
static _Exists(T, _Ptr<U>) e1; // expected-error {{static variable 'e1' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(T, _Ptr<U>)' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}}
static _Exists(T, struct S<T, U, V>) e2; // expected-error {{static variable 'e2' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(T, struct S<T, U, V>)' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}} \
// expected-error {{static variable 'e2' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(T, struct S<T, U, V>)' and type variable is 'V')}} \
// expected-note@15 {{type variable 'V' declared here}}
static _Exists(A, struct S<T, U, V>) e3; // expected-error {{static variable 'e3' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(A, struct S<T, U, V>)' and type variable is 'T')}} \
// expected-note@15 {{type variable 'T' declared here}} \
// expected-error {{static variable 'e3' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(A, struct S<T, U, V>)' and type variable is 'U')}} \
// expected-note@15 {{type variable 'U' declared here}} \
// expected-error {{static variable 'e3' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(A, struct S<T, U, V>)' and type variable is 'V')}} \
// expected-note@15 {{type variable 'V' declared here}}
// Static variable declarations can use integral and pointer types and bound type variables.
static int i;
static struct S<char, _Ptr<int>, double> s2;
static _Exists(T, _Ptr<T>) e4;
static _Exists(A, struct S<A, _Ptr<A>, _Array_ptr<A>>) e5;
// Non-static variable declarations can use free type variables.
_Ptr<T> q = 0;
_Array_ptr<_Array_ptr<U>> a3;
struct S<T, U, V> s3;
_Exists(U, _Ptr<T>) e6;
}

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

@ -6,15 +6,15 @@
#include <stdchecked.h>
extern void f1() {
array_ptr<int> a : count(1) = 0;
int* _Array a _Count(1) = 0;
int i;
ptr<int> c = 0;
int b[10];
int p[10];
array_ptr<int> checkedc_p : bounds(checkedc_p, checkedc_p + 1) = 0;
a = _Dynamic_bounds_cast<array_ptr<int>>(b, count(10));
c = _Dynamic_bounds_cast<int>(p); // expected-error {{expected _Ptr or * type}}
a = _Dynamic_bounds_cast_M(int* _Array, b, count(10));
c = _Dynamic_bounds_cast_M_N(int ,p); // expected-error {{expected _Ptr or * type}}
}
extern void f2() {
@ -30,8 +30,8 @@ extern void f3() {
char p[10];
ptr<int> c = 0;
array_ptr<int> a : count(2) = 0;
a = _Assume_bounds_cast<array_ptr<int>>(p, count(p + 2)); // expected-error {{invalid argument type 'char *' to count expression}}
c = _Assume_bounds_cast<ptr<int>>(p, count(1)); // expected-error {{expected _Array_ptr type}}
a = _Assume_bounds_cast_M (int* _Array , p, count(p + 2)); // expected-error {{invalid argument type 'char *' to count expression}}
c = _Assume_bounds_cast_M(int* _Single ,p, count(1)); // expected-error {{expected _Array_ptr type}}
}
extern void f4() {
@ -69,21 +69,21 @@ extern array_ptr<int> h4(void) : count(3) {
extern void f6() {
int i[2];
array_ptr<int> int_array_ptr_lb = i, int_array_ptr_ub = i + 1;
ptr<int> int_ptr_lb = i, int_ptr_ub = i + 1;
int* _Array int_array_ptr_lb = i, *_Array int_array_ptr_ub = i + 1;
int* _Single int_ptr_lb = i, *_Single int_ptr_ub = i + 1;
int *int_unchecked_ptr_lb = i, *int_unchecked_ptr_ub = i + 1;
array_ptr<char> char_array_ptr_lb = (array_ptr<char>)i,
char_array_ptr_ub = (array_ptr<char>)i + 1;
ptr<char> char_ptr_lb = (ptr<char>)i, char_ptr_ub = (ptr<char>)(i + 1);
char* _Array char_array_ptr_lb = (char* _Array)i,
*_Array char_array_ptr_ub = (char* _Array)i + 1;
char* _Single char_ptr_lb = (char* _Single)i, *_Single char_ptr_ub = (char* _Single)(i + 1);
char *char_unchecked_ptr_lb = (char *)i,
*char_unchecked_ptr_ub = (char *)i + 1;
array_ptr<int> t20 : bounds(int_array_ptr_lb, char_array_ptr_ub) = // expected-error {{pointer type mismatch}}
_Assume_bounds_cast<array_ptr<int>>(i, bounds(int_array_ptr_lb, char_array_ptr_ub)); // expected-error {{pointer type mismatch}}
int* _Array t20 _Bounds(int_array_ptr_lb, char_array_ptr_ub) = // expected-error {{pointer type mismatch}}
_Assume_bounds_cast_M(int* _Array, i, _Bounds(int_array_ptr_lb, char_array_ptr_ub)); // expected-error {{pointer type mismatch}}
array_ptr<int> t21 : bounds(int_ptr_lb, char_array_ptr_ub) = // expected-error {{pointer type mismatch}}
_Assume_bounds_cast<array_ptr<int>>(i, bounds(int_ptr_lb, int_array_ptr_ub));
int* _Array t21 _Bounds(int_ptr_lb, char_array_ptr_ub) = // expected-error {{pointer type mismatch}}
_Assume_bounds_cast_M(int* _Array ,i, bounds(int_ptr_lb, int_array_ptr_ub));
}
extern void f7(void *p) {
@ -95,19 +95,19 @@ extern void f7(void *p) {
extern void f8() {
int *p;
ptr<int> q = 0;
ptr<int> r = 0;
ptr<int *> s = 0;
ptr<ptr<int>> t = 0;
r = _Assume_bounds_cast<ptr<int>>(q);
p = _Assume_bounds_cast<int *>(q);
r = _Dynamic_bounds_cast<ptr<int>>(q);
p = _Dynamic_bounds_cast<int *>(q);
s = _Assume_bounds_cast<ptr<int *>>(q);
t = _Assume_bounds_cast<ptr<ptr<int>>>(q);
t = _Dynamic_bounds_cast<ptr<ptr<int>>>(q);
r = _Assume_bounds_cast<ptr<int>>(q);
p = _Assume_bounds_cast<int *>(q);
int* _Single q = 0;
int* _Single r = 0;
int* *_Single s = 0;
int* _Single *_Single t = 0;
r = _Dynamic_bounds_cast_M_N(int* _Single, q);
p = _Assume_bounds_cast_M_N(int * , q);
r = _Dynamic_bounds_cast_M_N(int* _Single , q);
p = _Dynamic_bounds_cast_M_N(int * ,q);
s = _Assume_bounds_cast_M_N(int * *_Single, q);
t = _Assume_bounds_cast_M_N(int* _Single *_Single , q);
t = _Dynamic_bounds_cast_M_N(int* _Single *_Single ,q);
r = _Dynamic_bounds_cast_M_N(int* _Single ,q);
p = _Assume_bounds_cast_M_N(int *,q);
}
@ -172,19 +172,19 @@ extern void f11() {
q = _Dynamic_bounds_cast<ptr<int>>(rr, count(1)); // expected-error{{expected _Array_ptr type}}
q = _Dynamic_bounds_cast<ptr<int>>(rr, bounds(rr, rr + 1)); // expected-error{{expected _Array_ptr type}}
p = _Dynamic_bounds_cast<int *>(q, count(1)); // expected-error {{expected _Array_ptr type}}
q = _Dynamic_bounds_cast<ptr<int>>(q, count(1)); // expected-error {{expected _Array_ptr type}}
q = _Dynamic_bounds_cast<ptr<int>>(i, count(1)); // expected-error {{expected _Array_ptr type}}
p = _Dynamic_bounds_cast<int *>(i, count(1)); // expected-error {{expected _Array_ptr type}}
q = _Dynamic_bounds_cast<ptr<int>>(i, bounds(i, i + 1)); // expected-error 2 {{expected expression with pointer type}}
p = _Dynamic_bounds_cast<int *>(i, bounds(i, i + 1)); // expected-error 2 {{expected expression with pointer type}}
p = _Dynamic_bounds_cast_M(int *, q, count(1)); // expected-error {{expected _Array_ptr type}}
q = _Dynamic_bounds_cast_M(int* _Single, q, count(1)); // expected-error {{expected _Array_ptr type}}
q = _Dynamic_bounds_cast_M(int* _Single, i, count(1)); // expected-error {{expected _Array_ptr type}}
p = _Dynamic_bounds_cast_M(int *, i, count(1)); // expected-error {{expected _Array_ptr type}}
q = _Dynamic_bounds_cast_M(int* _Single, i, bounds(i, i + 1)); // expected-error 2 {{expected expression with pointer type}}
p = _Dynamic_bounds_cast_M(int *, i, bounds(i, i + 1)); // expected-error 2 {{expected expression with pointer type}}
q = _Dynamic_bounds_cast<ptr<int>>(p, count(1)); // expected-error {{expected _Array_ptr type}}
p = _Dynamic_bounds_cast<int *>(p, count(1)); // expected-error {{expected _Array_ptr type}}
q = _Dynamic_bounds_cast<ptr<int>>(p, bounds(p, p + 1)); // expected-error {{expected _Array_ptr type}}
p = _Dynamic_bounds_cast<int *>(p, bounds(p, p + 1)); // expected-error {{expected _Array_ptr type}}
q = _Assume_bounds_cast<ptr<int>>(r, count(1)) + 3; // expected-error{{expected _Array_ptr type}}
c = _Dynamic_bounds_cast<ptr<int>>(p, count(4)); // expected-error{{expected _Array_ptr type}}
q = _Dynamic_bounds_cast_M(int* _Single, p, count(1)); // expected-error {{expected _Array_ptr type}}
p = _Dynamic_bounds_cast_M(int *, p, count(1)); // expected-error {{expected _Array_ptr type}}
q = _Dynamic_bounds_cast_M(int* _Single, p, bounds(p, p + 1)); // expected-error {{expected _Array_ptr type}}
p = _Dynamic_bounds_cast_M(int *, p, bounds(p, p + 1)); // expected-error {{expected _Array_ptr type}}
q = _Dynamic_bounds_cast_M(int* _Single, r, count(1)) + 3; // expected-error{{expected _Array_ptr type}}
c = _Dynamic_bounds_cast_M(int* _Single, p, count(4)); // expected-error{{expected _Array_ptr type}}
}