diff --git a/include/stdchecked.h b/include/stdchecked.h index 98f5832..89d45fd 100644 --- a/include/stdchecked.h +++ b/include/stdchecked.h @@ -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(e1, __VA_ARGS__) +#define _Dynamic_bounds_cast_M_N(T, e1 ) _Dynamic_bounds_cast(e1) +#define _Assume_bounds_cast_M(T, e1, ... ) _Assume_bounds_cast(e1, __VA_ARGS__) +#define _Assume_bounds_cast_M_N(T, e1 ) _Assume_bounds_cast(e1) #endif /* __STDCHECKED_H */ diff --git a/tests/dynamic_checking/checked_headers/ext.c b/tests/dynamic_checking/checked_headers/ext.c index 6841f5a..7a77abe 100644 --- a/tests/dynamic_checking/checked_headers/ext.c +++ b/tests/dynamic_checking/checked_headers/ext.c @@ -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) count(n-1), - size_t n _Where n > 0, - const char * restrict src : itype(restrict _Nt_array_ptr)) { +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) count( -void iface_test1(_Array_ptr 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 p : count(len), size_t len) { iface(p, len + 1, "Hello world"); } -void test3(_Array_ptr 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"); } } diff --git a/tests/dynamic_checking/dynamic-bounds-cast-check.c b/tests/dynamic_checking/dynamic-bounds-cast-check.c index 366f6db..72c2277 100644 --- a/tests/dynamic_checking/dynamic-bounds-cast-check.c +++ b/tests/dynamic_checking/dynamic-bounds-cast-check.c @@ -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 pc : count(len), unsigned len); -void failing_test_6(array_ptr pc : count(len), unsigned len); +void failing_test_6(char* _Array pc _Count(len), unsigned len); void failing_test_7(array_ptr 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 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 argv : count(argc)) { // CHECK-FAIL-4-NOT: Unexpected Success failing_test_4(5); } else if (strcmp(argv[1], "fail5") == 0) { - array_ptr 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 argv : count(argc)) { failing_test_6(p, 1); failing_test_6(p, 0); } else if (strcmp(argv[1], "fail7") == 0) { - array_ptr 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 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 q = 0; + int* _Single q = 0; int r checked[10] = {0,1,2,3,4,5,6,7,8,9}; - array_ptr s : count(5) = r; + int* _Array s _Count(5) = r; q = _Dynamic_bounds_cast>(r); printf("Printable0\n"); - q = _Dynamic_bounds_cast>(r, count(3)); + q = _Dynamic_bounds_cast_M(int* _Array, r, _Count(3)); printf("Printable1\n"); q = _Dynamic_bounds_cast>(r+3, count(3)); printf("Printable2\n"); - q = _Dynamic_bounds_cast>(r, bounds(s, s+3)); + q = _Dynamic_bounds_cast_M(int* _Array, r, _Bounds(s, s+3)); printf("Printable3\n"); - nt_array_ptr p : count(2) = - _Dynamic_bounds_cast>("abcdef", count(2)); + const char* _Nt_array p _Count(2) = + _Dynamic_bounds_cast>("abcdef", _Count(2)); printf("Printable4\n"); puts("Expected Success"); @@ -191,14 +191,14 @@ void passing_test_2(void) { q = _Dynamic_bounds_cast>(NULL); printf("Printable0\n"); - q = _Dynamic_bounds_cast>(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>(s); printf("Printable2\n"); - q = _Dynamic_bounds_cast>(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 pi = &i; ptr pv = pi; void *unchecked_pv = 0; - ptr p1 = _Dynamic_bounds_cast>(pi); + void* _Single p1 = _Dynamic_bounds_cast_M_N(void* _Single, pi); printf("Passed p1"); ptr p2 = _Dynamic_bounds_cast>(pv); printf("Passed p2"); @@ -218,7 +218,7 @@ void passing_test_3(void) { printf("Passed unchecked_pv"); ptr p3 = _Assume_bounds_cast>(unchecked_pv); printf("Passed p3"); - void *p4 = _Assume_bounds_cast(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 q = 0; int r checked[10] = {0,1,2,3,4,5,6,7,8,9}; - q = _Dynamic_bounds_cast>(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 q = 0; int r checked[10] = {0,1,2,3,4,5,6,7,8,9}; - q = _Dynamic_bounds_cast>(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 s : count(5) = r; - q = _Dynamic_bounds_cast>(r); + q = _Dynamic_bounds_cast_M_N(int* _Single, r); printf("Printable0\n"); q = _Dynamic_bounds_cast>(r, count(5)); printf("Printable1\n"); - q = _Dynamic_bounds_cast>(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 s : count(3) = _Dynamic_bounds_cast>(r, count(5)); + int* _Array s _Count(3) = _Dynamic_bounds_cast_M(array_ptr, 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. void failing_test_5(array_ptr pc : count(len), unsigned len) { - ptr pi = _Dynamic_bounds_cast>(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 pc : count(len), unsigned len) { // Test dynamic checks involving possibly failing conversions from // string literals. void failing_test_8(unsigned len) { - nt_array_ptr p : count(len) = - _Dynamic_bounds_cast>("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') diff --git a/tests/exist_types_runtest/callbacks.c b/tests/exist_types_runtest/callbacks.c index 80aec76..2acb9ad 100644 --- a/tests/exist_types_runtest/callbacks.c +++ b/tests/exist_types_runtest/callbacks.c @@ -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 -#include - -// 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) info; -}; - -int num_entries = 0; -struct map_entry cb_map[MAX_CB]; - -_For_any(T) void reg_cb(event_id id, struct cb_info info) { - _Exists(A, struct cb_info) opaque_info = _Pack(info, _Exists(A, struct cb_info), 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 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 start_info = { "task1", &cb_start }; - struct cb_info 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 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 stop_info = { cont_info, &cb_stop }; - - reg_cb(EVENT_START, start_info); - reg_cb(EVENT_START, start_info2); - reg_cb(EVENT_PAUSE, pause_info); - reg_cb(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 +#include + +// 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) info; +}; + +int num_entries = 0; +struct map_entry cb_map[MAX_CB]; + +_For_any(T) void reg_cb(event_id id, struct cb_info info) { + _Exists(A, struct cb_info) opaque_info = _Pack(info, _Exists(A, struct cb_info), 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 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 start_info = { "task1", &cb_start }; + struct cb_info 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 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 stop_info = { cont_info, &cb_stop }; + + reg_cb(EVENT_START, start_info); + reg_cb(EVENT_START, start_info2); + reg_cb(EVENT_PAUSE, pause_info); + reg_cb(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 +} + + diff --git a/tests/exist_types_runtest/counters.c b/tests/exist_types_runtest/counters.c index 77d6cb4..8979e28 100644 --- a/tests/exist_types_runtest/counters.c +++ b/tests/exist_types_runtest/counters.c @@ -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 -#include - -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) getCounter() { - struct Counter 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), int); -} - -// Mod2 counter - -void toggleMod2Counter(char *x) { - *x = !(*x); -} - -int getValMod2Counter(char *x) { - return *x; -} - -_Exists(T, struct Counter) getMod2Counter() { - struct Counter 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), char); -} - -int main(int argc, char *argv[]) { - _Exists(T, struct Counter) counters[2]; - counters[0] = getCounter(); - counters[1] = getMod2Counter(); - - for (int i = 0; i < 2; i++) { - _Unpack (U) struct Counter 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 +#include + +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) getCounter() { + struct Counter 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), int); +} + +// Mod2 counter + +void toggleMod2Counter(char *x) { + *x = !(*x); +} + +int getValMod2Counter(char *x) { + return *x; +} + +_Exists(T, struct Counter) getMod2Counter() { + struct Counter 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), char); +} + +int main(int argc, char *argv[]) { + _Exists(T, struct Counter) counters[2]; + counters[0] = getCounter(); + counters[1] = getMod2Counter(); + + for (int i = 0; i < 2; i++) { + _Unpack (U) struct Counter 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; +} diff --git a/tests/parsing/checked_array_types.c b/tests/parsing/checked_array_types.c index 15e34d5..6e09891 100644 --- a/tests/parsing/checked_array_types.c +++ b/tests/parsing/checked_array_types.c @@ -141,9 +141,9 @@ extern int Multiply(struct Vector vec1, struct Vector vec2) { return 0; } -extern int Multiply2(ptr vec1p, ptr 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 vec1p, ptr vec2p) { return 0; } + // // Declaring checked arrays of function pointers // @@ -167,6 +168,10 @@ ptr array_of_ptr_to_func checked[10]; extern ptr array_of_ptr_to_func checked[]; ptr aptr2 checked[10]; ptr 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 ptr_to_array; ptr ptr_to_nullterm_array; array_ptr array_ptr_to_array; array_ptr 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 ptr_to_incomplete_array; ptr ptr_to_nullterm_incomplete_array; array_ptr array_ptr_to_incomplete_array; array_ptr 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 array_of_array_ptrs checked[5]; array_ptr nullterm_array_of_array_ptrs nt_checked[5]; nt_array_ptr array_of_nullterm_array_ptrs checked[5]; nt_array_ptr 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(*unchecked_ptr_to_array_of_ptrs) checked[5]; array_ptr(*unchecked_ptr_to_array_of_array_ptrs) checked[5]; array_ptr(*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 ptr_to_array_of_unchecked_ptrs; @@ -205,6 +223,8 @@ ptr checked[5]> ptr_to_array_of_ptrs; ptr checked[5]> ptr_to_array_of_array_ptrs; ptr nt_checked[5]> ptr_to_nullterm_array_of_array_ptrs; ptr 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 ptr_to_array_of_unchecked_func_ptrs; @@ -215,6 +235,10 @@ ptr(ptr x, ptr y)>checked[5]> ptr_to_array_of_checked_func_ptrs_with_ptr_parameters; ptr (ptr x, ptr 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 s3 = sizeof(array_ptr); - int s4 = sizeof(ptrchecked[5]); - int s5 = sizeof(array_ptr 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 s8 = sizeof(array_ptr); - int s9 = sizeof(ptr nt_checked[5]); - int s10 = sizeof(array_ptr 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 s22 = _Alignof(array_ptr); int s23 = _Alignof(ptr checked[5]); - int s24 = _Alignof(array_ptrchecked[5]); - int s25 = _Alignof(nt_array_ptrchecked[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 s28 = _Alignof(array_ptr); int s29 = _Alignof(ptr nt_checked[5]); - int s30 = _Alignof(array_ptr nt_checked[5]); - int s31 = _Alignof(nt_array_ptr 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 px = (ptr) &x; - array_ptr pax = (array_ptr) &x; + int* _Array pax = (int* _Array) &x; pax = arr; // ptr to array type ptr parr = 0; diff --git a/tests/parsing/declaration_bounds.c b/tests/parsing/declaration_bounds.c index d267941..0f6b762 100644 --- a/tests/parsing/declaration_bounds.c +++ b/tests/parsing/declaration_bounds.c @@ -8,25 +8,25 @@ // Top level declarations with different storage classes and // storage classes omitted. -extern array_ptr a : count(5); -extern array_ptr b : count(3 + 2); +extern int* _Array a : count(5); +extern int* _Array b _Count(3 + 2); extern int cLen; -extern array_ptr c : count(cLen); -extern array_ptr d : byte_count(20); +extern int* _Array c : count(cLen); +extern int* _Array d _Byte_count(20); extern array_ptr e : byte_count(5 * sizeof(int)); extern array_ptr f : byte_count(cLen * sizeof(int)); extern array_ptr g : bounds(unknown); extern array_ptr h : bounds(f - 2, f + 3); -extern array_ptr 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 l : count(5) = vals; static _Thread_local array_ptr m : count(5); array_ptr b : count(3 + 2) = 0; -array_ptr d : byte_count(20) = 0; -array_ptr 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 arr : count(5)) { array_ptr s : byte_count(20) = arr; array_ptr t : byte_count(5 * sizeof(int)) = arr; array_ptr u : byte_count(len * sizeof(int)) = arr; - array_ptr v : bounds(v, v + 5) = arr; - array_ptr w : bounds(unknown) = arr; - array_ptr x : bounds(unknown); - array_ptr 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 cache1 : count(5); static array_ptr cache1_ptr : bounds(cache1 - 2, cache1 + 3); } // Multiple declarators in one declaration -extern void f2(array_ptr arr : count(5)) { - array_ptr 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 r : count(len) = arr, s : byte_count(20) = arr; - array_ptr 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 arr : count(5)) { array_ptr p : count((5)) = arr; @@ -70,9 +71,9 @@ extern void f3(array_ptr arr : count(5)) { array_ptr s : byte_count((20)) = arr; array_ptr t : byte_count(5 * (sizeof(int))) = arr; array_ptr u : byte_count((len) * sizeof(int)) = arr; - array_ptr v : bounds(v, (v + 5) + len - len) = arr; - array_ptr w: bounds((w + len - (len)), (w + len)) = arr; - array_ptr 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 arr : count(len), int len) { // unknown is a contextual a keyword if it follows 'bounds' '(' array_ptr q : bounds(unknown) = arr; array_ptr r : bounds(unknown + arr, arr + len) = arr; // expected-error {{expected ')'}} expected-note {{to match this '('}} - array_ptr s : bounds(arr + unknown, arr + len) = arr; - array_ptr 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 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 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 r : count(len) = arr; array_ptr s : byte_count(5 * sizeof(int)) = arr; - array_ptr t : byte_count(len * sizeof(int)) = arr; + array_ptr 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 arr7 checked[5] : count(5) = {0}; ptr arr8 checked[5] : bounds(arr8, arr8 + 5) = {0}; // Array_ptrs to checked pointers to functions. - array_ptr> u : count(5) = 0; + typedef int (*_Single func_u)(int, int); + func_u* _Array u : count(5) = 0; array_ptr> v : bounds(v, v + 5) = 0; array_ptr> w : bounds(v, v + 5) = 0; array_ptr arr : count(len))>> x : bounds(x, x + 5) = 0; } // Bounds expressions with incorrect syntax or semantics -extern void f7(array_ptr arr : count(5)) { - array_ptr p : bounds(start, end + 5) = 0; // expected-error {{undeclared identifier 'start'}} expected-error {{undeclared identifier 'end'}} - array_ptr q : count(len) = 0; // expected-error {{undeclared identifier 'len'}} - array_ptr r : byte_count(len) = 0; // expected-error {{undeclared identifier 'len'}} - array_ptr s : 6 + 6 = 0; // expected-error {{expected bounds expression}} - array_ptr t : 6 + 6, u : count(5) = arr; // expected-error {{expected bounds expression}} - array_ptr v : boounds(a, b + 5) = 0; // expected-error {{expected bounds expression}} - array_ptr w : coount(5) = 0; // expected-error {{expected bounds expression}} - array_ptr 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; } - diff --git a/tests/parsing/interop_and_bounds.c b/tests/parsing/interop_and_bounds.c index a8d1887..d7802d2 100644 --- a/tests/parsing/interop_and_bounds.c +++ b/tests/parsing/interop_and_bounds.c @@ -35,13 +35,13 @@ extern void f6(int **p : itype(array_ptr>) byte_count(y), int y) { extern void f10(int **p : count(y) itype(ptr checked[]), int y) { } -extern void f11(int **p : itype(ptr 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 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 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>)) { extern void g4(int y, int **p : itype(array_ptr>) bounds(p, p + y)) { } -extern void g5(int y, int **p : byte_count(y) itype(array_ptr>)) { +extern void g5(int y, int **p _Byte_count(y) _Itype(int* _Single *_Array)) { } -extern void g6(int y, int **p : itype(array_ptr>) 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 checked[])) { } -extern void g11(int y, int **p : itype(ptr 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 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 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 p) : itype(array_ptr>) byte_count(y) { return 0; } -extern int **h2(int y, ptr p) : count(y) itype(array_ptr>) { +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 p) : count(y) itype(array_ptr>) { int size; int **a1 : itype(array_ptr>) count(size) = 0; int **a2 : count(size) itype(array_ptr>) = 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>); float **data4 : itype(array_ptr>) 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 checked[]) count(len); + float data6[4] _Count(3) _Itype(float checked[4]); + float *data7[] _Itype(ptr checked[]) count(len); }; struct S2 { @@ -133,7 +132,7 @@ typedef ptr 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}} diff --git a/tests/parsing/interop_types.c b/tests/parsing/interop_types.c index add3e4a..ccd64b6 100644 --- a/tests/parsing/interop_types.c +++ b/tests/parsing/interop_types.c @@ -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>), 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>), int y) { @@ -36,7 +36,7 @@ extern void f6(int **p : itype(array_ptr>), int y) { extern void f7(int **p : itype(ptr 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>)) { extern void g6(int y, int **p : itype(ptr>)) { } -extern void g7(int y, int **p : itype(array_ptr>)) { +extern void g7(int y, int **p _Itype(int *_Single *_Array)) { } -extern void g8(int y, int **p : itype(ptr 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>) { return 0; } -extern int **h4(void) : itype(array_ptr>) { +extern int **h4(void) _Itype(int *_Single *_Array) { return 0; } @@ -100,9 +100,9 @@ int **a3 : itype(ptr>) = 0; int **a4 : itype(ptr>) = 0; int **a5 : itype(array_ptr>) = 0; int **a6 : itype(array_ptr>) = 0; -int ***a7 : itype(ptr>>) = 0; -int a8[10] : itype(int checked[10]); -extern int a9[] : itype(int checked[]); +int ***a7 _Itype(ptr>>) = 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>); float **data5 : itype(array_ptr>); float ***data6 : itype(ptr>>); - 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)) { } -extern const int *f34(void) : itype(ptr) { +extern const int *f34(void) _Itype(const int * _Single ) { return 0; } -const int *a10 : itype(ptr) = 0; -int *const a11 : itype(const ptr) = 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 pint; -typedef ptr 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 a)) { // expected-error {{type name cannot have identifier in it}} diff --git a/tests/parsing/member_bounds.c b/tests/parsing/member_bounds.c index de8a80f..0345467 100644 --- a/tests/parsing/member_bounds.c +++ b/tests/parsing/member_bounds.c @@ -7,7 +7,7 @@ #include struct S1 { - array_ptr arr : count(5); + int* _Array arr _Count(5); }; struct S2 { @@ -33,7 +33,7 @@ struct S6 { }; struct S7 { - array_ptr 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 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 arr : count(count); + int* _Array arr _Count(count); }; struct S13 { @@ -78,7 +78,7 @@ struct S13 { array_ptr arr3 : bounds(unknown + arr2, unknown + arr2 + 5); // expected-error {{expected ')'}} \ // expected-note {{to match this '('}} // not a keyword - array_ptr 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 arr3 : bounds(bounds + arr2, bounds + arr2 + 5); // not a keyword - array_ptr 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 : count(5)); int(*s2)(array_ptr arg : count(5)); int(*s3)(int n, array_ptr arg : count(n)); - int(*s4)(array_ptr arg : count(n), int n); + int(*s4)(int* _Array arg _Count(n), int n); // Use 'byte_count' instead of 'count'. int(*t1)(array_ptr : byte_count(5 * sizeof(int))); int(*t2)(array_ptr arg : count(5 * sizeof(int))); - int(*t3)(int n, array_ptr arg : count(n * sizeof(int))); - int(*t4)(array_ptr 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 arr : count(len)); - array_ptr (*f2)(int len, array_ptr 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 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 lower; - array_ptr upper; + int* _Array lower; + int* _Array upper; } pair; array_ptr arr1 : bounds(pair.lower, pair.upper); struct S20 { @@ -193,7 +193,7 @@ struct S18 { struct S21 { struct { array_ptr lower; - array_ptr upper; + int* _Array upper; } pair; array_ptr arr1 : bounds(pair.lower, pair.upper); struct { @@ -210,7 +210,7 @@ struct S22 { }; struct S23 { - array_ptr 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 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 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 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 ip : count(4); - array_ptr 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 cp : count(tag ? len : 0); - array_ptr ip : count(!tag ? 0 : len); + int* _Array ip _Count(!tag ? 0 : len); }; }; @@ -336,7 +336,7 @@ struct S32 { union U5 { _Bool isInteger; ptr ip; - ptr fp; + float* _Single fp; }; union U6 { diff --git a/tests/parsing/pointer-larger-int/member_bounds.c b/tests/parsing/pointer-larger-int/member_bounds.c index 1f75c18..ec1bd72 100644 --- a/tests/parsing/pointer-larger-int/member_bounds.c +++ b/tests/parsing/pointer-larger-int/member_bounds.c @@ -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 - -_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 ip : bounds(ip, is_tagged_int(ip) ? ip : ip + 5); // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} - 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 + +_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 ip : bounds(ip, is_tagged_int(ip) ? ip : ip + 5); // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} + int i; +}; diff --git a/tests/parsing/pointer_types.c b/tests/parsing/pointer_types.c index 096eb7c..35955a9 100644 --- a/tests/parsing/pointer_types.c +++ b/tests/parsing/pointer_types.c @@ -39,11 +39,11 @@ extern void f5(ptr>> p, int y) { ***p = y; } -extern void f6(array_ptr p : count(1), int y) { - *p = y; +extern void f6(int *_Array p _Count(1), int y) { + *p = y; } -extern void f7(array_ptr 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 p : count(1), int y) { f8(p, y); } -extern void f10(nt_array_ptr> p : count(1), - nt_array_ptr 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 p : count(1)) { f7(p, y); } -extern void g7(int y, nt_array_ptr 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 h6(int y, array_ptr p) { return p; } - -extern array_ptr> h7(int y, array_ptr> p : count(1)) { +extern int *_Single *_Array h7(int y, int *_Single *_Array p _Count(1)) { **p = y; return p; } -extern nt_array_ptr h8(int y, nt_array_ptr p) { +extern int *_Nt_array h8(int y, int *_Nt_array p) { return p; } - extern nt_array_ptr> h9(int y, nt_array_ptr> p : count(1)) { **p = y; return p; @@ -156,8 +154,8 @@ extern void k1(int y) int v = y; ptr t1 = &v; array_ptr t2 : count(1) = &v; - array_ptr> t3 : count(1) = &t1; - nt_array_ptr 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 vec1p, ptr 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 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> array_ptr_of_ptrfunc; -nt_array_ptr> 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 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(*unchecked_ptr_to_array_of_ptrs)[5]; -array_ptr(*unchecked_ptr_to_array_of_array_ptrs)[5]; -nt_array_ptr(*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(*unchecked_ptr_to_nullterm_array_of_ptrs) nt_checked[5]; @@ -257,17 +255,18 @@ ptr[5]> ptr_to_array_of_array_ptrs; ptr[5]> ptr_to_array_of_nullterm_array_ptrs; // Declare ptr to nullterm arrays of pointers -ptr ptr_to_nullterm_array_of_unchecked_ptrs; -ptrnt_checked[5]> ptr_to_nullterm_array_of_ptrs; -ptrnt_checked[5]> ptr_to_nullterm_array_of_array_ptrs; -ptrnt_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 ptr_to_array_of_unchecked_func_ptrs; ptr[5]> ptr_to_array_of_checked_func_ptrs; // Make parameter and return types be ptrs too. -ptr (ptr x, ptr y)>[5]> ptr_to_array_of_checked_func_ptrs_with_ptr_parameters; +ptr[5]> + ptr_to_array_of_checked_func_ptrs_with_ptr_parameters; // // Typedefs using checked pointer types @@ -277,8 +276,8 @@ typedef ptr t_ptr_int; typedef ptr t_ptr_func; typedef array_ptr t_array_ptr_int; typedef array_ptr> t_array_ptr_ptr_int; -typedef nt_array_ptr t_nullterm_array_ptr_int; -typedef nt_array_ptr> 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 x, int y)); // These are OK - int s30 = _Alignof(ptr); + 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 pfunc = (ptr) 0; ptr[5]> ptr_to_pfunc_arr = (ptr[5]>) 0; + int (*_Single (*_Single m_ptr_to_pfunc_arr)[5])(int x, int y)= (int (*_Single (*_Single)[5])(int x, int y)) 0; + } diff --git a/tests/parsing/rel_align.c b/tests/parsing/rel_align.c index 411ea98..9003775 100644 --- a/tests/parsing/rel_align.c +++ b/tests/parsing/rel_align.c @@ -10,10 +10,10 @@ extern int cLen; extern array_ptr f : byte_count(cLen * sizeof(int)); extern array_ptr g : bounds(f - 2, f + 3) rel_align(char); extern array_ptr h : bounds(f - 2, f + 3) rel_align_value(sizeof(char)); -extern array_ptr 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 cursor : bounds(buf, buf + 128) rel_align(char) = buf + 64; @@ -28,8 +28,8 @@ extern void f1(array_ptr arr : count(5)) { array_ptr midarr1 : bounds(midarr1 - 1, midarr1 - 1 + 2) rel_align_value(sizeof(char)) = arr + 2; static array_ptr cache1 : count(5); - static array_ptr cache1_ptr : bounds(cache1 - 2, cache1 + 3) rel_align(char); - static array_ptr 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 arr : count(5)) { @@ -38,9 +38,9 @@ extern void f2(array_ptr arr : count(5)) { u : bounds(u, u + 5) rel_align(char) = arr, v : bounds(unknown) = arr; - array_ptr 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 arr : count(5)) { @@ -51,7 +51,7 @@ extern void f3(array_ptr arr : count(5)) { array_ptr v1 : bounds(v1, (v1 + 5) + len - len) rel_align_value(sizeof(char)) = arr; array_ptr w1 : bounds((w1 + len - (len)), (w1 + len)) rel_align_value(sizeof(char)) = arr; - array_ptr 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 arr : count(len), int len) { @@ -63,7 +63,7 @@ extern void f4(array_ptr arr : count(len), int len) { array_ptr t1 : bounds(t, t + count) rel_align_value(sizeof(char)) = arr; int bounds = len; array_ptr u : bounds(u, u + bounds) rel_align(char) = arr; - array_ptr 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 cache_ptr : bounds(cache - 2, cache + 3) rel_align(char); - static array_ptr 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 f9s(int start, array_ptr arr : bounds(arr - start, ar extern array_ptr f10(int bounds, array_ptr arr : count(bounds)) : bounds(arr, arr + bounds) rel_align(char); -extern array_ptr f10s(int bounds, array_ptr 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 f11(array_ptr 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> f14(array_ptr> arr : count(5)) return arr; } -extern array_ptr> f14s(array_ptr> arr : count(5)) - : bounds(arr, arr + 5) rel_align_value(5) { +extern array_ptr> f14s(array_ptr> arr _Count(5)) + _Bounds(arr, arr + 5) rel_align_value(5) { return arr; } @@ -175,8 +175,8 @@ extern array_ptr f15(array_ptr arr : count(5)) return arr; } -extern array_ptr f15s(array_ptr arr : count(5)) - : bounds(arr, arr + 3) rel_align_value(sizeof(char)) { +extern array_ptr f15s(array_ptr 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 arg3 : count(n), int n) : bounds(arg3, arg3 + n) rel_align_value(sizeof(char))> r4 = 0; - typedef int func2(array_ptr 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 f17(int len, array_ptr arr : count(len)) : boounds(arr, arr + len) rel_align(1) { // expected-error {{expected bounds expression}} } extern array_ptr f18(int len, array_ptr arr : count(len)) : boounds(arr, arr + len) rel_align(char) { // expected-error {{expected bounds expression}} } -extern array_ptr f19(int len, array_ptr 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 arr : bounds(buffer, buffer + len) rel_align(char); // expected-error 2 {{use of undeclared member 'buffer'}} - array_ptr 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 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 f25(int len, array_ptr arr : count(len)) : boounds(ar extern array_ptr f26(int len, array_ptr arr : count(len)) : boounds() rel_align(1) {} // expected-error {{expected bounds expression or bounds-safe interface type}} -extern array_ptr f27(int len, array_ptr 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 arg : bo0unds(arg, arg + 5) rel_alive(1) = 0; // expected-error {{expected bounds expression or bounds-safe interface type}} - array_ptr arg1 : bo0unds rel_alive(1) = 0; // expected-error {{expected bounds expression or bounds-safe interface type}} - array_ptr 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 arr : bounds(arr - start, arr - start + 5) rel_align(char); - array_ptr 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 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 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 arr5 : bounds(bounds + arr5, bounds + arr5 + 2) rel_align_value(sizeof(int)); array_ptr arr6 : bounds(bounds + arr2, bounds + arr2 + 5) rel_align_value(sizeof(char)); - array_ptr 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 arg2 : count(n), int n) : bounds(arg2, arg2 + n) rel_align(char)> r3 = 0; - ptr 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 r4 = 0; // expected-error {{expression is not an integer constant expression}} } struct S7 { @@ -312,7 +313,7 @@ struct S7 { array_ptr arr1 : bounds(pair.lower, pair.upper) rel_align_value(sizeof(pair)); struct S9 { array_ptr arr2 : bounds(pair.lower, pair.upper) rel_align(char); - array_ptr 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 arr1 : bounds(pair.lower, pair.upper) rel_align_value(sizeof(char)); struct { array_ptr arr2 : bounds(pair.lower, pair.upper) rel_align(char); - array_ptr 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 arr : bounds(arr, unknown_id) rel_align(char); // expected-error {{use of undeclared member}} - array_ptr 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 arr1: bounds() rel_align_value(len); // expected-error {{expected expression}} \ // expected-error {{expression is not an integer constant expression}} - array_ptr 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 arr4 : bounds() rel_align_value(); // expected-error 2 {{expected expression}} + int* _Array arr4 _Bounds() rel_align_value(); // expected-error 2 {{expected expression}} }; array_ptr global_bound; struct S14 { int len; - array_ptr 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 arr1 : bounds(global_bound, global_bound + len) rel_align_value(sizeof(int)); // expected-error 2 {{use of undeclared member 'global_bound'}} diff --git a/tests/parsing/return_bounds.c b/tests/parsing/return_bounds.c index 73de577..c6ed8fa 100644 --- a/tests/parsing/return_bounds.c +++ b/tests/parsing/return_bounds.c @@ -18,10 +18,10 @@ extern array_ptr f5(array_ptr arr : byte_count(5 * sizeof(int))) : byte_count(5 * sizeof(int)); extern array_ptr f6(array_ptr arr : bounds(arr, arr + 5)) : bounds(arr, arr + 5); -extern array_ptr f7(int start, - array_ptr arr : bounds(arr - start, arr - start + 5)) - : bounds(arr - start, arr - start + 5); -extern array_ptr 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 f3a(int len, array_ptr arr : count(len)) // only when they immediately follow a ':'; extern array_ptr f9(int count) : count(count); extern array_ptr f10(int unknown) : count(unknown); -extern array_ptr f11(int bounds, array_ptr 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 f1(array_ptr arr : count(5)) : count(5) { @@ -53,11 +53,12 @@ extern array_ptr f3(int len, return arr; } -extern array_ptr f4(array_ptr 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 f5(array_ptr arr : byte_count(5 * sizeof(int))) : byte_count(5 * sizeof(int)) { return arr; @@ -68,10 +69,10 @@ extern array_ptr f6(array_ptr arr : bounds(arr, arr + 5)) return arr; } -extern array_ptr f7(int start, - array_ptr 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 f8(void) : bounds(unknown) { @@ -92,8 +93,8 @@ extern array_ptr 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 f11(int bounds, array_ptr 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 f16(array_ptr arr : count(5)) return arr; } -extern array_ptr f17(array_ptr 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(int len) : count(len)> f19(int len) { } // Check that return_value can be used. Expand count to a bounds expression. -extern ptr(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 (*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_ptrs of that length. -extern array_ptr(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 arg : count(5)) : bounds(arg, arg + 5)> r1 = 0; - ptr 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 : count(5)) = 0; int(*s2)(array_ptr arg : count(5)) = 0; @@ -218,8 +224,8 @@ extern void f24(void) { // Use 'byte_count' instead of 'count'. int(*t1)(array_ptr : byte_count(5 * sizeof(int))) = 0; int(*t2)(array_ptr arg : count(5 * sizeof(int))) = 0; - int(*t3)(int n, array_ptr arg : count(n * sizeof(int))) = 0; - int(*t4)(array_ptr 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 func1(int len) : count(len); @@ -237,7 +243,7 @@ extern array_ptr f26(void) : count(len) { // expected-error {{use of undec } // Misspell bounds to cause a parsing error. -extern array_ptr f27(int len, array_ptr 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 f29(int len, array_ptr arr : count(len)) : bounds(arr } // Omit both arguments to bounds to cause a parsing error -extern array_ptr f30(int len, array_ptr 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 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}} diff --git a/tests/parsing/typevariable/forany_parsing.c b/tests/parsing/typevariable/forany_parsing.c index 4291250..83427e8 100644 --- a/tests/parsing/typevariable/forany_parsing.c +++ b/tests/parsing/typevariable/forany_parsing.c @@ -10,15 +10,15 @@ // expected-no-diagnostics // Testing for function declaration with function body, with parameters -_For_any(T, S) _Ptr TestDefinitionWithParameter(_Ptr at, _Ptr bt, _Ptr cs) { +_For_any(T, S) T* _Single TestDefinitionWithParameter(T* _Single at, T* _Single bt, _Ptr cs) { _Ptr newT = at; return newT; } // Testing for function declaration without function body, without parameters. -_For_any(R) _Ptr TestDeclarationWithNoParameter(void); +_For_any(R) R* _Single TestDeclarationWithNoParameter(void); // Testing for function declaration without function body, with parameters -_For_any(Q) _Ptr TestDeclarationWithParameter(_Ptr aq, _Ptr bq, _Ptr cq); +_For_any(Q) Q* _Single TestDeclarationWithParameter(Q* _Single aq, _Ptr bq, _Ptr cq); int callPolymorphicTypes() { int num = 0; diff --git a/tests/parsing/typevariable/forany_parsing_error.c b/tests/parsing/typevariable/forany_parsing_error.c index b342a90..a7c46eb 100644 --- a/tests/parsing/typevariable/forany_parsing_error.c +++ b/tests/parsing/typevariable/forany_parsing_error.c @@ -7,9 +7,9 @@ // // RUN: %clang_cc1 -verify %s -_For_any(R) _Ptr 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 foo3(void); // expected-error{{expected type variable identifier}} -_For_any(R T) _Ptr foo4(void); // expected-error{{expected , or )}} +_For_any(R T) R* _Single foo4(void); // expected-error{{expected , or )}} diff --git a/tests/parsing/typevariable/generic_func_parsing.c b/tests/parsing/typevariable/generic_func_parsing.c index 377d9b3..5efd57b 100644 --- a/tests/parsing/typevariable/generic_func_parsing.c +++ b/tests/parsing/typevariable/generic_func_parsing.c @@ -10,7 +10,7 @@ // RUN: %clang_cc1 -verify %s // expected-no-diagnostics -_For_any(T) _Ptr foo(_Ptr a, _Ptr b) { +_For_any(T) T* _Single foo(T* _Single a, T* _Single b) { return a; } diff --git a/tests/parsing/typevariable/generic_func_parsing_error.c b/tests/parsing/typevariable/generic_func_parsing_error.c index 72cce5f..b126dc0 100644 --- a/tests/parsing/typevariable/generic_func_parsing_error.c +++ b/tests/parsing/typevariable/generic_func_parsing_error.c @@ -3,7 +3,7 @@ // // RUN: %clang_cc1 -verify %s -_For_any(T) _Ptr Foo(_Ptr a, _Ptr b) { +_For_any(T) T* _Single Foo(T* _Single a, T* _Single b) { return a; } diff --git a/tests/runtime_operations/assignments.c b/tests/runtime_operations/assignments.c index bb682f0..61867e3 100644 --- a/tests/runtime_operations/assignments.c +++ b/tests/runtime_operations/assignments.c @@ -9,7 +9,7 @@ static char *test : itype(ptr); char p = 5; -static char *init : itype(ptr) = &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 argv : count(argc)) { +int main(int argc, char**_Array argv : count(argc)) { // CHECK: Starting test puts("Starting test"); testfn(init, 1); diff --git a/tests/static_checking/address_of.c b/tests/static_checking/address_of.c index c6ba56e..392f8bb 100644 --- a/tests/static_checking/address_of.c +++ b/tests/static_checking/address_of.c @@ -13,7 +13,7 @@ // Test taking addresses of members using in bounds expressions for checked members. struct S1 { - _Array_ptr 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 *p6 = &(s2->s).p; // expected-error {{cannot take address of member with bounds}} _Array_ptr *p7 = &s1_nested->p; // expected-error {{cannot take address of member with bounds}} _Array_ptr *p8 = &(s1_nested->p); // expected-error {{cannot take address of member with bounds}} - _Array_ptr *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 p9 = &(s3_nested.child).len; // expected-error {{cannot take address of member used in member bounds}} _Ptr p10 = &s3_nested.child; // expected-error {{cannot take address of member used in member bounds}} _Ptr p11 = &(s3_nested).child; // expected-error {{cannot take address of member used in member bounds}} - _Ptr 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 s3, _Ptr s4, _Ptr p9 = &(s3_nested->child).len; // expected-error {{cannot take address of member used in member bounds}} _Ptr p10 = &s3_nested->child; // expected-error {{cannot take address of member used in member bounds}} _Ptr p11 = &(s3_nested)->child; // expected-error {{cannot take address of member used in member bounds}} - _Ptr 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> p6 = &(s4.s).p; // expected-error {{cannot take address of member with bounds}} _Ptr<_Array_ptr> p7 = &s3_nested.p; // expected-error {{cannot take address of member with bounds}} _Ptr<_Array_ptr> p8 = &(s3_nested.p); // expected-error {{cannot take address of member with bounds}} - _Ptr<_Array_ptr> 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 s3, _Ptr s4, _Ptr s3_nested) { @@ -207,7 +207,7 @@ extern checked void f11(_Ptr s3, _Ptr s4, _Ptr> p6 = &(s4->s).p; // expected-error {{cannot take address of member with bounds}} _Ptr<_Array_ptr> p7 = &s3_nested->p; // expected-error {{cannot take address of member with bounds}} _Ptr<_Array_ptr> p8 = &(s3_nested->p); // expected-error {{cannot take address of member with bounds}} - _Ptr<_Array_ptr> 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 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 s7) { } extern checked void f33a(struct S7 *s7 : itype(_Ptr)) { - _Ptr 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 s8) { extern checked void f35a(struct S8 *s8 : itype(_Ptr)) { _Ptr p1 = &s8->len; // expected-error {{cannot take address of member used in member bounds}} - _Ptr 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 p1 = &s10->len; // expected-error {{cannot take address of member used in member bounds}} - _Ptr 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 s12) { _Ptr p1 = &s12->len; // expected-error {{cannot take address of member used in member bounds}} - _Ptr 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> p3 = &s.upper; // expected-error {{cannot take address of member used in member bounds}} _Ptr<_Array_ptr> p4 = &s.upper; // expected-error {{cannot take address of member used in member bounds}} _Ptr<_Array_ptr> p5 = &s.q; // expected-error {{cannot take address of member with bounds}} - _Ptr 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 x : count(len), int len) { _Ptr<_Array_ptr> py = &y; // expected-error {{cannot take address of variable 'y' with bounds}} _Ptr<_Array_ptr> pg = &global_var1; // expected-error {{cannot take address of variable 'global_var1' with bounds}} _Ptr parr1 = &global_arr1; - _Ptr 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> px1 = &x; // expected-error {{cannot take address of variable 'x' with bounds}} _Ptr<_Array_ptr> px2 = &(x); // expected-error {{cannot take address of variable 'x' with bounds}} _Ptr<_Array_ptr> px3 = (&x); // expected-error {{cannot take address of variable 'x' with bounds}} - _Ptr<_Array_ptr> 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 parr1 = &global_arr2; _Ptr parr2 = &(global_arr2); diff --git a/tests/static_checking/bounds_decl_checking.c b/tests/static_checking/bounds_decl_checking.c index ca0d011..9fe0321 100644 --- a/tests/static_checking/bounds_decl_checking.c +++ b/tests/static_checking/bounds_decl_checking.c @@ -13,7 +13,7 @@ int gtmp; int *g1 = >mp; ptr g2 = >mp; array_ptr g3 = >mp; -array_ptr g4 : count(1) = >mp; +int* _Array g4 _Count(1) = >mp; extern void check_exprs(int *arg1, ptr arg2, array_ptr arg3, @@ -31,7 +31,7 @@ extern void check_exprs(int *arg1, ptr arg2, array_ptr arg3, array_ptr arr1 : count(3) = (int checked[3]){0, 1, 2}; array_ptr arr2 : count(4) = (int checked[3]){0, 1, 2}; // expected-error {{declared bounds for 'arr2' are invalid after initialization}} array_ptr arr_struct1 : count(1) = &(struct S1){0}; - array_ptr 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 arg2, array_ptr arg3, int *t1 = &tmp1; ptr t2 = &tmp1; array_ptr t3 = &tmp1; - array_ptr 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 arg2, array_ptr arg3, nt_array_ptr g11 : bounds(unknown) = 0; nt_array_ptr g12 = (int nt_checked[]) { 1, 0 }; // default bounds of count(0); -nt_array_ptr g13 : count(1) = (int nt_checked[]) { 1, 0 }; +int* _Nt_array g13 _Count(1) = (int nt_checked[]) { 1, 0 }; struct S2 { nt_array_ptr f1 : bounds(unknown); nt_array_ptr f2; - nt_array_ptr f3 : count(1); + int* _Nt_array f3 _Count(1); }; extern void check_exprs_nullterm(nt_array_ptr arg1 : bounds(unknown), @@ -231,7 +231,7 @@ extern void check_exprs_nullterm(nt_array_ptr arg1 : bounds(unknown), arg3 = 0; arg1 = (nt_array_ptr)0xabcd; arg2 = (nt_array_ptr)0xabcd; // expected-error {{inferred bounds for 'arg2' are unknown after assignment}} - arg3 = (nt_array_ptr)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 arg1 : bounds(unknown), // locals assigned from parameters nt_array_ptr t1 : bounds(unknown); nt_array_ptr t2 = 0; - nt_array_ptr 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 arg1 : bounds(unknown), int i1; nt_array_ptr c2 : count(u1) = 0; nt_array_ptr c3 : count(u1 * u2 + 2 * i1) = 0; - nt_array_ptr 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 p : count(0)); extern void check_call_args(int *arg1, ptr arg2, array_ptr arg3, array_ptr arg4 : count(1), - array_ptr arg5 : count(arglen), int arglen, + int* _Array arg5 _Count(arglen), int arglen, array_ptr 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 arg2, nt_array_ptr arg3 : count(1), nt_array_ptr arg4 : count(arglen), int arglen, - nt_array_ptr 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)); extern void test_bsi_f3(int *p : itype(array_ptr)); 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, _Ptr)>)); extern int test_cmp(_Ptr a, _Ptr b); extern void check_call_bsi(int *arg1, ptr arg2, array_ptr arg3, array_ptr arg4 : count(1), - array_ptr 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 a, nt_array_ptr extern void check_nullterm_call_bsi(int *arg1 : itype(nt_array_ptr), nt_array_ptr arg2 : bounds(unknown), nt_array_ptr arg3, - nt_array_ptr arg4 : count(1), + int* _Nt_array arg4 _Count(1), nt_array_ptr arg5 : count(arglen), int arglen, int **arg6, @@ -631,7 +631,7 @@ extern void check_nullterm_call_bsi(int *arg1 : itype(nt_array_ptr), } } -nt_array_ptr nullterm_return1(void); +char* _Nt_array nullterm_return1(void); nt_array_ptr 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 check_nullterm_return1(void) { +char* _Nt_array check_nullterm_return1(void) { nt_array_ptr p : bounds(unknown) = 0; return p; // expected-error {{return value has unknown bounds, bounds expected because the function 'check_nullterm_return1' has bounds}} } diff --git a/tests/static_checking/bundled_statements.c b/tests/static_checking/bundled_statements.c index 1a70733..4a79bb8 100644 --- a/tests/static_checking/bundled_statements.c +++ b/tests/static_checking/bundled_statements.c @@ -7,10 +7,10 @@ void f1() _Checked{ - _Array_ptr p : count(2) = 0; + _Array_ptr p _Count(2) = 0; int val = 5; int val1 _Checked[3]; - _Array_ptr q : count(1) = &val; + _Array_ptr q _Count(1) = &val; _Bundled { p = q; *(p+1) = 4; // expected-error {{out-of-bounds memory access}} @@ -26,7 +26,7 @@ _Checked{ _Array_ptr p : count(2) = 0; int val = 5; int val1 _Checked[3]; - _Array_ptr 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 p : count(2) = 0; int val = 5; int val1 _Checked[3]; - _Array_ptr 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 p : count(2) = 0; int val = 5; int val1 _Checked[8]; - _Array_ptr 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 p : count(2) = 0; int val = 5; int val1 _Checked[3]; - _Array_ptr 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 p : count(2) = 0; + int* _Array p _Count(2) = 0; int val = 5; int val1 _Checked[3]; _Array_ptr q : count(1) = &val; @@ -138,7 +138,7 @@ _Checked{ _Array_ptr p : count(2) = 0; int val = 5; int val1 _Checked[3]; - _Array_ptr q : count(1) = &val; + _Array_ptr q _Count(1) = &val; p = val1; p++; p++; @@ -150,10 +150,10 @@ _Checked{ void f9(int flag) _Checked{ - _Array_ptr p : count(2) = 0; + _Array_ptr p _Count(2) = 0; int val = 5; int val1 _Checked[3]; - _Array_ptr q : count(1) = &val; + int* _Array q _Count(1) = &val; p = val1, p++, p++, @@ -166,7 +166,7 @@ _Checked{ int val = 5; _Array_ptr q : count(2) = &val; // expected-error {{declared bounds for 'q' are invalid after initialization}} _Bundled { - _Array_ptr 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 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 r : count(2) = &val; r = valarr; @@ -186,7 +186,7 @@ _Checked{ _Array_ptr p : count(2) = 0; int val = 5; int val1 _Checked[3]; - _Array_ptr q : count(1) = &val; + int* _Array q _Count(1) = &val; L1: _Bundled { p = val1; @@ -202,8 +202,7 @@ _Checked{ extern _Array_ptr my_malloc(int len) : count(len); extern void copy1(_Array_ptr to, _Array_ptr from : count(n), int n); -extern _Array_ptr copy2(_Array_ptr to, _Array_ptr 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 resize1(_Array_ptr buf : count(buflen), int buflen, int len) : count(len) { _Array_ptr tmp : count(len) = my_malloc(len); @@ -216,7 +215,7 @@ _Array_ptr resize1(_Array_ptr buf : count(buflen), int buflen, int len } int buflen = 0; -_Array_ptr buf : count(buflen) = 0; +_Array_ptr buf _Count(buflen) = 0; void resize2(int newlen) { _Array_ptr tmp : count(newlen) = my_malloc(newlen); @@ -235,7 +234,7 @@ _Array_ptr g4 : count(1) = >mp; int *h1 = >mp; _Ptr h2 = >mp; _Array_ptr h3 = >mp; -_Array_ptr h4 : count(1) = >mp; +int* _Array h4 _Count(1) = >mp; void gf0(void) { @@ -314,8 +313,8 @@ extern void test_bsi_f6(int((*compar)(const int *, const int *)) : extern int test_cmp(_Ptr a, _Ptr b); extern void check_call_bsi(int *arg1, _Ptr arg2, _Array_ptr arg3, - _Array_ptr arg4 : count(1), - _Array_ptr 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 list : count (n); + struct Node* _Array list _Count(n); unsigned int n; }; extern unsigned int my_strlen(_Nt_array_ptr); // get the first name that starts with the letters 'Ar' -_Nt_array_ptr get_name(_Array_ptr groups : count(gcnt), unsigned int gcnt) +char* _Nt_array get_name(_Array_ptr groups : count(gcnt), unsigned int gcnt) _Checked { unsigned int n = 0; _Array_ptr group : count(n) = 0; @@ -407,7 +406,7 @@ _Checked { } for (int j = 0; j < n; j++) { _Nt_array_ptr 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; } diff --git a/tests/static_checking/initializers.c b/tests/static_checking/initializers.c index 3603d1a..51cfadb 100644 --- a/tests/static_checking/initializers.c +++ b/tests/static_checking/initializers.c @@ -18,7 +18,7 @@ extern void f1() { array_ptr v7 : byte_count(5 * sizeof(int)) = 0; array_ptr v8 : byte_count(5 * sizeof(int)); // expected-error {{automatic variable 'v8' with bounds must have initializer}} array_ptr v9 : bounds(v9, v9 + 5) = 0; - array_ptr 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 v20 = 0; ptr v21; // expected-error {{automatic variable 'v21' with _Ptr type must have initializer}} @@ -50,7 +50,7 @@ nt_array_ptr g31 : count(0) = (int checked[]) { 0, [2] = 2, 3, 5, 0 }; nt_array_ptr g32 : count(5) = "abcde"; array_ptr g33 : count(5) = "abcde"; array_ptr g34 : count(5) = (char[5]) { 'a', 'b', 'c', 'd', 'e' }; -array_ptr 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 g37 nt_checked[] = { "the", "brown", "fox", "jumped", void callback1(int a); void callback2(int a); -nt_array_ptr> callback_table = (ptr[]) { callback1, callback2, 0 }; +void(*_Single *_Nt_array callback_table)(int) = (ptr[]) { callback1, callback2, 0 }; void f3(char *escape) { } @@ -122,8 +122,8 @@ void f5(void) checked { nt_array_ptr t32 : count(5) = "abcde"; array_ptr t33 : count(5) = "abcde"; - array_ptr t34 = (char[5]) { 'a', 'b', 'c', 'd', 'e' }; - array_ptr 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 t38 checked[3][2] = { [1] = "ab", "cd", "ef", "jk" }; - nt_array_ptr 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 p = 0; // initializer required. array_ptr q : count(5) = 0; // has bounds; initializer required. - array_ptr 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 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 lower; - array_ptr 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 lower : count(5); - array_ptr upper : count(5); + array_ptr lower _Count(5); + array_ptr upper _Count(5); float y; }; @@ -232,8 +232,8 @@ void f6(void) { union u_checked_value_has_bounds { int x; - array_ptr lower : count(5); - array_ptr 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 name : count(20); + array_ptr 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}} diff --git a/tests/static_checking/lexical_equality.c b/tests/static_checking/lexical_equality.c index a63c69c..c5eb4c5 100644 --- a/tests/static_checking/lexical_equality.c +++ b/tests/static_checking/lexical_equality.c @@ -11,6 +11,10 @@ // expression first. Then we check against prior kinds of expressions. // //--------------------------------------------------------------------------// +#define _Dynamic_bounds_cast_M(T, e1, ... ) _Dynamic_bounds_cast(e1, __VA_ARGS__) +#define _Dynamic_bounds_cast_M_N(T, e1 ) _Dynamic_bounds_cast(e1) +#define _Assume_bounds_cast_M(T, e1, ... ) _Assume_bounds_cast(e1, __VA_ARGS__) +#define _Assume_bounds_cast_M_N(T, e1 ) _Assume_bounds_cast(e1) //--------------------------------------------------------------------------// // Constants // @@ -25,13 +29,13 @@ extern int f1_1(_Array_ptr p : count(0)); extern int f1_2(_Array_ptr p : count(1)); extern int f1_2(_Array_ptr p : count(1)); extern int f1_3(_Array_ptr p : count(5)); -extern int f1_3(_Array_ptr p : count(5)); +extern int f1_3(int* _Array p _Count(5)); // Integer constant inequality extern int f1_4(_Array_ptr p : count(0)); extern int f1_4(_Array_ptr p : count(1)); // expected-error {{conflicting parameter bounds}} extern int f1_5(_Array_ptr p : count(0)); -extern int f1_5(_Array_ptr 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 p : count('a')); @@ -43,7 +47,7 @@ extern int f1_7(_Array_ptr p : count('b')); // expected-error {{confl // Character constant vs. integer constant inequality extern int f1_8(_Array_ptr p : count(0)); -extern int f1_8(_Array_ptr 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 p : count((int) 0.0F)); extern int f3_2(_Array_ptr p : count((int) 5.0f)); extern int f3_2(_Array_ptr p : count((int) 5.0f)); extern int f3_2(_Array_ptr p : count((int) 5.0F)); -extern int f3_2(_Array_ptr 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 p : count((int) 0.0f)); @@ -84,14 +88,14 @@ extern int f4_1(_Array_ptr p : count((int) 5.0f)); // expected-error {{con extern int f4_2(_Array_ptr p : count((int) 0.0F)); extern int f4_2(_Array_ptr p : count((int) 5.0F)); // expected-error {{conflicting parameter bounds}} extern int f4_3(_Array_ptr p : count((int) 0.0f)); -extern int f4_3(_Array_ptr 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 p : count((int) 0.0)); extern int f5_1(_Array_ptr p : count((int) 0.0f)); // expected-error {{conflicting parameter bounds}} extern int f5_2(_Array_ptr p : count((int) 0.0)); -extern int f5_2(_Array_ptr 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 p : count((int) 0.0l)); @@ -99,7 +103,7 @@ extern int f6_1(_Array_ptr p : count((int) 1.0l)); // expected-error {{con extern int f6_2(_Array_ptr p : count((int) 0.0l)); extern int f6_2(_Array_ptr p : count((int) 5.0L)); // expected-error {{conflicting parameter bounds}} extern int f6_3(_Array_ptr p : count((int) 0.0l)); -extern int f6_3(_Array_ptr 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 p : count((int) 0.0L)); // expected-error {{con extern int f8_1(_Array_ptr p : count((int) 0.0f)); extern int f8_1(_Array_ptr p : count((int) 0.0l)); // expected-error {{conflicting parameter bounds}} extern int f8_2(_Array_ptr p : count((int) 0.0f)); -extern int f8_2(_Array_ptr 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 p : count((int) 0.0)); // expected-error {{conf extern int f9_2(_Array_ptr p : count((int) 5)); extern int f9_2(_Array_ptr p : count((int) 5.0f)); // expected-error {{conflicting parameter bounds}} extern int f9_3(_Array_ptr p : count((int) 150)); -extern int f9_3(_Array_ptr 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 arr1_1 : count(arr1_len); // Global variable inequality. extern _Array_ptr arr1_2 : count(arr1_len); -extern _Array_ptr 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 arr1 : count(d)); // Parameter variable inequality. extern int f20_3(_Array_ptr arr1 : count(a), int a, int b); -extern int f20_3(_Array_ptr 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 arr1_3 : count(arr1_len); // expected-error {{variable re // Parameter variable vs. constant inequality. extern int f21_1(_Array_ptr arr1 : count(len), int len); -extern int f21_1(_Array_ptr 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 p : count(!a)); extern int f30_6(int a, _Array_ptr p : count(!a)); extern int f30_7(int a, _Array_ptr p : byte_count(sizeof(a))); extern int f30_7(int a, _Array_ptr p : byte_count(sizeof(a))); -extern int f30_8(int a, _Array_ptr p : byte_count(sizeof(int[2]))); -extern int f30_8(int a, _Array_ptr 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 p : count(sizeof(a)), int a); extern int f31_8(_Array_ptr p : count(+a), int a); // expected-error {{conflicting parameter bounds}} extern int f31_9(_Array_ptr p : count(sizeof(a)), int a); extern int f31_9(_Array_ptr p : count(~a), int a); // expected-error {{conflicting parameter bounds}} -extern int f31_10(_Array_ptr p : count(sizeof(a)), int a); -extern int f31_10(_Array_ptr 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 p : byte_count(sizeof(a))); @@ -234,8 +238,8 @@ extern int f32_1(int a, _Array_ptr p : bounds(&arr4[5], &arr4[50])); extern int f32_1(int a, _Array_ptr p : bounds(&arr4[6], &arr4[50])); // expected-error {{conflicting parameter bounds}} // Inequality of dereference expressions -extern int f32_2(_Ptr plen, _Array_ptr p : count(*plen), _Ptr slen); -extern int f32_2(_Ptr plen, _Array_ptr p : count(*slen), _Ptr 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 plen, _Array_ptr p : count(*plen), int slen); @@ -249,7 +253,7 @@ extern int f32_5(_Array_ptr p : count((int) (5.0)), int a); // expected-er // Inequality of unary operator expressions and variables. extern int f32_6(_Array_ptr p : count(!a), int a); -extern int f32_6(_Array_ptr 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 p : count(a * b)); extern int f40_2(int a, int b, _Array_ptr p : count(a / b)); extern int f40_2(int a, int b, _Array_ptr p : count(a / b)); extern int f40_3(int a, int b, _Array_ptr p : count(a % b)); -extern int f40_3(int a, int b, _Array_ptr 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 p : count(a + b)); @@ -275,7 +279,7 @@ extern int f40_5(int a, int b, _Array_ptr p : count(a - b)); extern int f40_6(int a, int b, _Array_ptr p : count(a << b)); extern int f40_6(int a, int b, _Array_ptr p : count(a << b)); extern int f40_7(int a, int b, _Array_ptr p : count(a >> b)); -extern int f40_7(int a, int b, _Array_ptr 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 p : count(a < b)); @@ -285,13 +289,13 @@ extern int f41_2(int a, int b, _Array_ptr p : count(a > b)); extern int f41_3(int a, int b, _Array_ptr p : count(a <= b)); extern int f41_3(int a, int b, _Array_ptr p : count(a <= b)); extern int f41_4(int a, int b, _Array_ptr p : count(a >= b)); -extern int f41_4(int a, int b, _Array_ptr 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 p : count(a == b)); extern int f41_5(int a, int b, _Array_ptr p : count(a == b)); extern int f41_6(int a, int b, _Array_ptr p : count(a != b)); -extern int f41_6(int a, int b, _Array_ptr 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 p : count(a & b)); @@ -312,8 +316,8 @@ extern int f43_1(int a, _Array_ptr b, _Array_ptr p : bounds(b, b + a)) extern int f43_1(int a, _Array_ptr b, _Array_ptr p : bounds(b, b + a)); extern int f43_2(int a, _Array_ptr b, _Array_ptr p : bounds(b - a, b)); extern int f43_2(int a, _Array_ptr b, _Array_ptr p : bounds(b - a, b)); -extern int f43_3(_Array_ptr a, _Array_ptr b, _Array_ptr p : count(b - a)); -extern int f43_3(_Array_ptr a, _Array_ptr b, _Array_ptr 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 a, _Array_ptr b, _Array_ptr p : count #define TESTOP / #define FUNC(index) NAME(50, index) -extern int FUNC(1)(int a, int b, _Array_ptr 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 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 p : count(a * b)); // expected extern int FUNC(2)(int a, int b, _Array_ptr p : count(a TESTOP b)); extern int FUNC(2)(int a, int b, _Array_ptr p : count(a / b)); // expected-error {{conflicting parameter bounds}} -extern int FUNC(3)(int a, int b, _Array_ptr 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 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 p : count(a / b)); // expected extern int FUNC(3)(int a, int b, _Array_ptr p : count(a TESTOP b)); extern int FUNC(3)(int a, int b, _Array_ptr p : count(a % b)); // expected-error {{conflicting parameter bounds}} -extern int FUNC(4)(int a, int b, _Array_ptr 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 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 p : count(a % b)); // expected extern int FUNC(4)(int a, int b, _Array_ptr p : count(a TESTOP b)); extern int FUNC(4)(int a, int b, _Array_ptr p : count(a + b)); // expected-error {{conflicting parameter bounds}} -extern int FUNC(5)(int a, int b, _Array_ptr p : count(a TESTOP b)); -extern int FUNC(5)(int a, int b, _Array_ptr 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 p : count(a + b)); // expected extern int FUNC(5)(int a, int b, _Array_ptr p : count(a TESTOP b)); extern int FUNC(5)(int a, int b, _Array_ptr p : count(a - b)); // expected-error {{conflicting parameter bounds}} -extern int FUNC(6)(int a, int b, _Array_ptr p : count(a TESTOP b)); -extern int FUNC(6)(int a, int b, _Array_ptr 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 p : count(a ^ b)); // expecte extern int FUNC(15)(int a, int b, _Array_ptr p : count(a TESTOP b)); extern int FUNC(15)(int a, int b, _Array_ptr p : count(a | b)); // expected-error {{conflicting parameter bounds}} -extern int FUNC(15)(int a, int b, _Array_ptr p : count(a TESTOP b)); -extern int FUNC(15)(int a, int b, _Array_ptr 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 p : bounds(p, p + a)); @@ -906,7 +910,7 @@ extern int f80_1(int a, _Array_ptr b, _Array_ptr p : bounds(b, (_Arra extern int f80_2(int a, _Array_ptr b, _Array_ptr p : bounds((apint) b, (apint) b + a)); extern int f80_2(int a, _Array_ptr b, _Array_ptr p : bounds((apint) b, (apint) b + a)); -extern int f80_2(int a, _Array_ptr b, _Array_ptr p : bounds((_Array_ptr) b, (_Array_ptr) 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 b, extern int f80_5(int a, _Array_ptr b, _Array_ptr p : bounds(b, (_Array_ptr) ((apint) b + a))); -extern int f80_5(int a, _Array_ptr b, - _Array_ptr p : bounds(b, (_Array_ptr) ((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 b : count(c->f1), struct S *c); extern int f91_2(struct S *a, _Array_ptr b : count(c->f1), struct S *c); extern int f91_3(struct S *a, _Array_ptr b : count(a->f2), struct S *c); -extern int f91_3(struct S *a, _Array_ptr 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 b : count(a.f1)); @@ -992,7 +996,7 @@ extern int f93_2(struct S *a, _Array_ptr b : count(a->f1), struct S *c); extern int f93_2(struct S *a, _Array_ptr b : count(c->f1), struct S *c); // expected-error {{conflicting parameter bounds}} extern int f93_3(struct S *a, _Array_ptr b : count(a->f1), struct S *c); -extern int f93_3(struct S *a, _Array_ptr 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 b, extern int f201_2(int a, _Array_ptr b, _Array_ptr p : bounds(b, (_Array_ptr) (void *) b + a)); -extern int f201_2(int a, _Array_ptr b, - _Array_ptr p : bounds(b, (_Array_ptr) (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 b, extern int f202_2(unsigned int a, _Array_ptr b, _Array_ptr p : bounds(b, b + a)); -extern int f202_2(unsigned int a, _Array_ptr b, - _Array_ptr 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 b : count(a + 1)); extern int f203_1(short int a, _Array_ptr b : count((int) a + 1)); extern int f203_2(short int a, _Array_ptr b, _Array_ptr p : bounds(b, b + a)); -extern int f203_2(short int a, _Array_ptr b, _Array_ptr 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 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 b : bounds(&arr, &arr)); +extern int f211_2(int* _Array b _Bounds(&arr, &arr)); extern int f211_2(_Array_ptr b : bounds((int (*) _Checked[10]) arr, (int (*) _Checked[10]) arr)); -extern int f211_2(_Array_ptr 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 a : bounds(_Assume_bounds_cast<_Array_ptr a : bounds(_Assume_bounds_cast<_Array_ptr>(a, count(1)), _Assume_bounds_cast<_Array_ptr>(a, count(2)) + 3)); extern void f212_3(_Array_ptr a : bounds(_Dynamic_bounds_cast<_Array_ptr>(a, count(1)), _Assume_bounds_cast<_Array_ptr>(a, count(2)) + 3)); // expected-error {{conflicting parameter bounds}} -extern void f212_4(_Array_ptr a : bounds(_Dynamic_bounds_cast<_Array_ptr>(a, count(1)), _Assume_bounds_cast<_Array_ptr>(a, count(2)) + 3)); -extern void f212_4(_Array_ptr a : bounds(_Dynamic_bounds_cast<_Array_ptr>(a, count(1)), _Dynamic_bounds_cast<_Array_ptr>(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 a : bounds(_Dynamic_bounds_cast<_Array_ptr>(a, count(1)), _Assume_bounds_cast<_Array_ptr>(a, count(2)) + 3)); -extern void f212_5(_Array_ptr a : bounds(_Dynamic_bounds_cast<_Array_ptr>(a, count(5)), _Assume_bounds_cast<_Array_ptr>(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 a : bounds(_Dynamic_bounds_cast<_Array_ptr>(a, count(1)), _Assume_bounds_cast<_Array_ptr>(a, count(2)) + 3)); -extern void f212_6(_Array_ptr a : bounds(_Dynamic_bounds_cast<_Array_ptr>(a, count(1)), _Assume_bounds_cast<_Array_ptr>(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 a : bounds(_Dynamic_bounds_cast<_Array_ptr>(b, count(1)), b + 3), _Array_ptr b : count(1)); -extern void f212_7(_Array_ptr a : bounds(b, b + 3), _Array_ptr 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 a : bounds(b, _Assume_bounds_cast<_Array_ptr>(b, count(1)) + 3), _Array_ptr b : count(1)); -extern void f212_8(_Array_ptr a : bounds(b, b + 3), _Array_ptr 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}} diff --git a/tests/static_checking/nme_bounds.c b/tests/static_checking/nme_bounds.c index 88c8cdc..796376b 100644 --- a/tests/static_checking/nme_bounds.c +++ b/tests/static_checking/nme_bounds.c @@ -36,7 +36,7 @@ void f1(int i, int* loc) { array_ptr as2a : count(i -= 1) = 0; // expected-error {{assignment expression not allowed in count expression}} array_ptr as2b : byte_count(i -= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}} array_ptr as2c : bounds(loc -= 1, loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}} - array_ptr 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 as3a : count(i *= 1) = 0; // expected-error {{assignment expression not allowed in count expression}} array_ptr 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 as4a : count(i /= 1) = 0; // expected-error {{assignment expression not allowed in count expression}} array_ptr as4b : byte_count(i /= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}} array_ptr as4c : bounds(loc + (i /= 1), loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}} - array_ptr 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 as5a : count(i %= 1) = 0; // expected-error {{assignment expression not allowed in count expression}} array_ptr 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 as6a : count(i <<= 1) = 0; // expected-error {{assignment expression not allowed in count expression}} array_ptr as6b : byte_count(i <<= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}} array_ptr as6c : bounds(loc + (i <<= 1), loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}} - array_ptr 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 as7a : count(i >>= 1) = 0; // expected-error {{assignment expression not allowed in count expression}} array_ptr 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 as8a : count(i &= 1) = 0; // expected-error {{assignment expression not allowed in count expression}} array_ptr as8b : byte_count(i &= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}} array_ptr as8c : bounds(loc + (i &= 1), loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}} - array_ptr 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 as9a : count(i ^= 1) = 0; // expected-error {{assignment expression not allowed in count expression}} array_ptr 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 as10a : count(i |= 1) = 0; // expected-error {{assignment expression not allowed in count expression}} array_ptr as10b : byte_count(i |= 1) = 0; // expected-error {{assignment expression not allowed in byte count expression}} - array_ptr as10c : bounds(loc + (i |= 1), loc) = 0; // expected-error {{assignment expression not allowed in bounds expression}} - array_ptr 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 as11a : count(i++) = 0; // expected-error {{increment expression not allowed in count expression}} array_ptr 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 as12a : count(++i) = 0; // expected-error {{increment expression not allowed in count expression}} array_ptr as12b : byte_count(++i) = 0; // expected-error {{increment expression not allowed in byte count expression}} - array_ptr as12c : bounds(++loc, loc) = 0; // expected-error {{increment expression not allowed in bounds expression}} - array_ptr 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 as13a : count(i--) = 0; // expected-error {{decrement expression not allowed in count expression}} array_ptr 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 as14a : count(--i) = 0; // expected-error {{decrement expression not allowed in count expression}} array_ptr as14b : byte_count(--i) = 0; // expected-error {{decrement expression not allowed in byte count expression}} - array_ptr as14c : bounds(--loc, loc) = 0; // expected-error {{decrement expression not allowed in bounds expression}} - array_ptr 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 as15a : count(f0int()) = 0; // expected-error {{call expression not allowed in count expression}} array_ptr 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 as16a : count(f0int() + 1) = 0; // expected-error {{call expression not allowed in count expression}} array_ptr as16b : byte_count(f0int() + 1) = 0; // expected-error {{call expression not allowed in byte count expression}} - array_ptr as16c : bounds(f0ptr() + 1, loc) = 0; // expected-error {{call expression not allowed in bounds expression}} - array_ptr 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 as17a : count(j) = 0; // expected-error {{volatile expression not allowed in count expression}} array_ptr 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 as18a : count(i + j) = 0; // expected-error {{volatile expression not allowed in count expression}} array_ptr as18b : byte_count(i + j) = 0; // expected-error {{volatile expression not allowed in byte count expression}} - array_ptr as18c : bounds(loc + (i + j), loc) = 0; // expected-error {{volatile expression not allowed in bounds expression}} - array_ptr 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 as4a : count(&i == &j) = 0; array_ptr as4b : byte_count(&i == &j) = 0; - array_ptr as4c : bounds(&i, loc) = 0; - array_ptr as4d : bounds(loc, &i) = 0; + int* _Array as4c _Bounds(&i, loc) = 0; + int* _Array as4d _Bounds(loc, &i) = 0; array_ptr as5a : count(*pi) = 0; array_ptr as5b : byte_count(*pi) = 0; @@ -159,33 +159,33 @@ void f2(int i, int* loc) { array_ptr as6a : count((int)'a') = 0; array_ptr as6b : byte_count((int)'a') = 0; - array_ptr as6c : bounds((int*)0, loc) = 0; - array_ptr as6d : bounds(loc, (int*)0) = 0; + int* _Array as6c _Bounds((int*)0, loc) = 0; + int* _Array as6d _Bounds(loc, (int*)0) = 0; array_ptr as7a : count(+i) = 0; array_ptr as7b : byte_count(+i) = 0; array_ptr as7c : bounds(loc + (+i), loc) = 0; - array_ptr as7d : bounds(loc, loc + (+i)) = 0; + int* _Array as7d _Bounds(loc, loc + (+i)) = 0; array_ptr as8a : count(-i) = 0; array_ptr as8b : byte_count(-i) = 0; array_ptr as8c : bounds(loc + -i, loc) = 0; - array_ptr as8d : bounds(loc, loc + -i) = 0; + int* _Array as8d _Bounds(loc, loc + -i) = 0; array_ptr as9a : count(~i) = 0; array_ptr as9b : byte_count(~i) = 0; array_ptr as9c : bounds(loc + ~i, loc) = 0; - array_ptr as9d : bounds(loc, loc + ~i) = 0; + int* _Array as9d _Bounds(loc, loc + ~i) = 0; array_ptr as10a : count(!i) = 0; array_ptr as10b : byte_count(!i) = 0; - array_ptr as10c : bounds(loc + !i, loc) = 0; - array_ptr as10d : bounds(loc, loc + !i) = 0; + int* _Array as10c _Bounds(loc + !i, loc) = 0; + int* _Array as10d _Bounds(loc, loc + !i) = 0; array_ptr as11a : count(sizeof(i)) = 0; array_ptr as11b : byte_count(sizeof(i)) = 0; array_ptr as11c : bounds(loc + sizeof(loc), loc) = 0; - array_ptr as11d : bounds(loc, loc + sizeof(loc)) = 0; + int* _Array as11d _Bounds(loc, loc + sizeof(loc)) = 0; array_ptr as12a : count(i * 1 / 1 % 1) = 0; array_ptr as12b : byte_count(i * 1 / 1 % 1) = 0; @@ -195,7 +195,7 @@ void f2(int i, int* loc) { array_ptr as13a : count(i + 1 - 1) = 0; array_ptr as13b : byte_count(i + 1 - 1) = 0; array_ptr as13c : bounds(loc + 1 - 1, loc) = 0; - array_ptr as13d : bounds(loc, loc + 1 - 1) = 0; + int* _Array as13d _Bounds(loc, loc + 1 - 1) = 0; array_ptr as14a : count(i << 1 >> 1) = 0; array_ptr as14b : byte_count(i << 1 >> 1) = 0; @@ -203,7 +203,7 @@ void f2(int i, int* loc) { array_ptr as14d : bounds(loc, loc + (i << 1 >> 1)) = 0; array_ptr as15a : count(i < j) = 0; - array_ptr as15b : byte_count(i < j) = 0; + int* _Array as15b _Byte_count(i < j) = 0; array_ptr as16a : count(i > j) = 0; array_ptr as16b : byte_count(i > j) = 0; @@ -212,12 +212,12 @@ void f2(int i, int* loc) { array_ptr as17b : byte_count(i <= j) = 0; array_ptr as18a : count(i >= j) = 0; - array_ptr as18b : byte_count(i >= j) = 0; + int* _Array as18b _Byte_count(i >= j) = 0; array_ptr as19a : count(i == j) = 0; array_ptr as19b : byte_count(i == j) = 0; array_ptr as19c : bounds(loc + (loc == loc2), loc) = 0; - array_ptr as19d : bounds(loc, loc + (loc == loc2)) = 0; + int* _Array as19d _Bounds(loc, loc + (loc == loc2)) = 0; array_ptr as20a : count(i & j) = 0; array_ptr as20b : byte_count(i & j) = 0; @@ -236,8 +236,8 @@ void f2(int i, int* loc) { array_ptr as25a : count(i ? j : 0) = 0; array_ptr as25b : byte_count(i ? j : 0) = 0; - array_ptr as25c : bounds(i ? loc : loc2, loc) = 0; - array_ptr 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 as26a : count(u1.m1) = 0; array_ptr as26b : byte_count(u1.m1) = 0; @@ -247,12 +247,12 @@ void f2(int i, int* loc) { array_ptr as27a : count(s1.m1) = 0; array_ptr as27b : byte_count(s1.m1) = 0; array_ptr as27c : bounds(s1.m2, loc) = 0; - array_ptr as27d : bounds(loc, s1.m2) = 0; + int* _Array as27d _Bounds(loc, s1.m2) = 0; array_ptr as28a : count(ps1->m1) = 0; array_ptr as28b : byte_count(ps1->m1) = 0; array_ptr as28c : bounds(ps1->m2, loc) = 0; - array_ptr 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 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 p = &i; array_ptr> r : count(1) = &p; - array_ptr> 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 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. diff --git a/tests/static_checking/static_check_bounds_cast.c b/tests/static_checking/static_check_bounds_cast.c index 79c9912..de6001d 100644 --- a/tests/static_checking/static_check_bounds_cast.c +++ b/tests/static_checking/static_check_bounds_cast.c @@ -12,16 +12,16 @@ extern void f1() { int b[10]; int *p = 0; - array_ptr checkedc_p : bounds(checkedc_p, checkedc_p + 1) = 0; + int* _Array checkedc_p : bounds(checkedc_p, checkedc_p + 1) = 0; c = _Dynamic_bounds_cast>(p); // expected-error {{expression has unknown bounds}} c = _Dynamic_bounds_cast>(p); // expected-error {{expression has unknown bounds}} a = _Assume_bounds_cast>(p, count(4)); checkedc_p = _Assume_bounds_cast>(p, bounds(p, p + 1)); checkedc_p = _Dynamic_bounds_cast>(p, bounds(p, p + 1)); // expected-error {{expression has unknown bounds}} - a = _Assume_bounds_cast>(p, count(1)); + a = _Assume_bounds_cast(p, count(1)); a = _Assume_bounds_cast>(p, bounds(p, p + 1)); array_ptr d = _Assume_bounds_cast>(p, count(4)); - c = _Dynamic_bounds_cast>(p); // expected-error {{expression has unknown bounds}} + c = _Dynamic_bounds_cast(p); // expected-error {{expression has unknown bounds}} } struct S1 { @@ -31,7 +31,7 @@ struct S1 { } pair; array_ptr arr1 : bounds(pair.lower, pair.upper); struct { - array_ptr 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(r); // expected-error {{expression has unknown bounds}} q = _Assume_bounds_cast>(p); q = _Dynamic_bounds_cast>(p); // expected-error {{expression has unknown bounds}} - q = _Dynamic_bounds_cast>(r); // expected-error {{expression has unknown bounds}} - q = _Dynamic_bounds_cast>(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>(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>(t, count(3)))[3]; // expected-error {{out-of-bounds memory access}} s1 = _Dynamic_bounds_cast>(p, count(5)); // expected-error {{expression has unknown bounds}} - s2 = _Assume_bounds_cast>(r, count(5)); + s2 = _Assume_bounds_cast(r, count(5)); } extern ptr f4(int arr checked[]) { @@ -83,7 +83,7 @@ checked int *f5(int *p, ptr q, array_ptr r, array_ptr 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>(r, count(1))); // expected-error {{expression has unknown bounds}} + b[i][j] += *q + *(_Dynamic_bounds_cast(r, count(1))); // expected-error {{expression has unknown bounds}} } } } @@ -143,8 +143,8 @@ extern void f18(int i) { r = _Dynamic_bounds_cast>(p, count(1)); // expected-error {{expression has unknown bounds}} expected-error {{declared bounds for 'r' are invalid after assignment}} r = _Dynamic_bounds_cast>(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>(i, count(5)); // expected-error {{expression has unknown bounds}} - r = _Dynamic_bounds_cast>(i, bounds(i, i + 1)); // expected-error 2 {{expected expression with pointer}} + r = _Dynamic_bounds_cast(i, count(5)); // expected-error {{expression has unknown bounds}} + r = _Dynamic_bounds_cast(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>(b, bounds(p, p + 1)); // expected-error {{to have a pointer}} x = _Dynamic_bounds_cast>(p, count(b)); // expected-error {{invalid argument type}} - x = _Dynamic_bounds_cast>(p, bounds(p, 1)); // expected-error {{expected expression with}} + x = _Dynamic_bounds_cast(p, bounds(p, 1)); // expected-error {{expected expression with}} x = _Dynamic_bounds_cast>(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 buf : count(len), int len) { - array_ptr intbuf : count(12) = _Dynamic_bounds_cast>(buf, bounds(intbuf, intbuf + 12)); + int* _Array intbuf _Count(12) = _Dynamic_bounds_cast(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 buf : count(10) = _Assume_bounds_cast>(h7(), count(10)); + array_ptr buf _Count(10) = _Assume_bounds_cast>(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 buf : count(len), int len) { - array_ptr intbuf : count(6) = _Dynamic_bounds_cast>(buf + 5, count(6)); + int* _Array intbuf _Count(6) = _Dynamic_bounds_cast(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)'}} diff --git a/tests/typechecking/bounds.c b/tests/typechecking/bounds.c index 7faf3c8..adb01be 100644 --- a/tests/typechecking/bounds.c +++ b/tests/typechecking/bounds.c @@ -52,8 +52,8 @@ extern void count_exprs(void) { array_ptr t7 : count(c7) = 0; array_ptr t8 : count(c8) = 0; array_ptr t9 : count(c9) = 0; - array_ptr t10 : count(c10) = 0; - array_ptr 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 t12 : count(A) = 0; @@ -72,8 +72,8 @@ extern void count_exprs(void) { array_ptr t22 : byte_count(c7) = 0; array_ptr t23 : byte_count(c8) = 0; array_ptr t24 : byte_count(c9) = 0; - array_ptr t25 : byte_count(c10) = 0; - array_ptr 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 t27 : byte_count(A) = 0; @@ -93,8 +93,8 @@ extern void count_exprs(void) { nt_array_ptr t54 : byte_count(c7) = 0; nt_array_ptr t55 : byte_count(c8) = 0; - nt_array_ptr t56 : byte_count(c9) = 0; - nt_array_ptr 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 t1 : count(c1) = 0; array_ptr t2 : count(c2) = 0; array_ptr t3 : count(s.f) = 0; - nt_array_ptr 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 t9 : count(test_func) = 0; // expected-error {{invalid argument type}} array_ptr t10 : count(func_ptr) = 0; // expected-error {{invalid argument type}} array_ptr t11 : count("test") = 0; // expected-error {{invalid argument type}} - array_ptr t12 : count(5.0f) = 0; // expected-error {{invalid argument type}} - array_ptr 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 t14 : count(c8) = 0; // expected-error {{invalid argument type}} @@ -170,8 +170,8 @@ extern void invalid_count_exprs(void) { array_ptr t22 : byte_count(s.f) = 0; // expected-error {{invalid argument type}} array_ptr t23 : byte_count(func_ptr) = 0; // expected-error {{invalid argument type}} array_ptr t24 : byte_count("test") = 0; // expected-error {{invalid argument type}} - array_ptr t25 : byte_count(5.0f) = 0; // expected-error {{invalid argument type}} - array_ptr 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 t27 : byte_count(c8) = 0; // expected-error {{invalid argument type}} @@ -200,8 +200,8 @@ extern void bounds_exprs(void) { array_ptr t5 : bounds(array_ptr_lb, unchecked_ptr_ub) = i; array_ptr t6 : bounds(ptr_lb, ptr_ub) = i; array_ptr t7 : bounds(unchecked_ptr_lb, ptr_ub) = i; - array_ptr t8 : bounds(ptr_lb, unchecked_ptr_ub) = i; - array_ptr 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 t9a : bounds(nt_array_ptr_lb, ptr_ub) = i; @@ -213,8 +213,8 @@ extern void bounds_exprs(void) { array_ptr t10 : bounds(i, i + 1) = i; array_ptr t11 : bounds(i, array_ptr_ub) = i; - array_ptr t11a : bounds(i, nt_array_ptr_ub) = i; - array_ptr 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_array_ptr_lb = i, void_array_ptr_ub = i + 1; ptr void_ptr_lb = i, void_ptr_ub = i + 1; @@ -229,7 +229,7 @@ extern void bounds_exprs(void) { array_ptr t26 : bounds(void_ptr_lb, void_ptr_ub) = i; array_ptr t27 : bounds(void_unchecked_ptr_lb, void_ptr_ub) = i; array_ptr t28 : bounds(void_ptr_lb, void_unchecked_ptr_ub) = i; - array_ptr 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 t46 : bounds(array_ptr_lb, void_ptr_ub) = i; array_ptr t47 : bounds(unchecked_ptr_lb, void_array_ptr_ub) = i; array_ptr t48 : bounds(void_unchecked_ptr_lb, array_ptr_ub) = i; - array_ptr t49 : bounds(void_array_ptr_lb, unchecked_ptr_ub) = i; - array_ptr 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 t51 : bounds(void_ptr_lb, ptr_ub) = i; array_ptr t52 : bounds(ptr_lb, void_ptr_ub) = i; @@ -261,8 +261,8 @@ extern void bounds_exprs(void) { array_ptr t73 : bounds(unchecked_ptr_lb, ptr_ub) = (array_ptr) i; array_ptr t75 : bounds(void_array_ptr_lb, array_ptr_ub) = (array_ptr) i; array_ptr t76 : bounds(void_unchecked_ptr_lb, array_ptr_ub) = (array_ptr) i; - array_ptr t77 : bounds(array_ptr_lb, void_unchecked_ptr_ub) = (array_ptr) i; - array_ptr t77a : bounds(nt_array_ptr_lb, void_unchecked_ptr_ub) = (array_ptr) 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 t80 : bounds(i, nt_array_ptr_ub) = (array_ptr) i; // spot check that typechecking looks through typedefs - typedef array_ptr int_array_ptr; + typedef int* _Array int_array_ptr; typedef ptr int_ptr; typedef int *int_unchecked_ptr; typedef nt_array_ptr int_nt_array_ptr; @@ -292,7 +292,7 @@ extern void bounds_exprs(void) { array_ptr t98 : bounds(ptr_lb, typedef_unchecked_ptr_ub) = i; array_ptr t99 : bounds(typedef_unchecked_ptr_lb, unchecked_ptr_ub) = i; array_ptr t100 : bounds(typedef_nt_array_ptr_lb, unchecked_ptr_ub) = i; - array_ptr 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 t121 : bounds(array_ptr_const_lb, array_ptr_ub) = i; + int* _Array t121 _Bounds(array_ptr_const_lb, array_ptr_ub) = i; array_ptr t122 : bounds(const_array_ptr_lb, array_ptr_ub) = i; array_ptr t123 : bounds(const_array_ptr_const_lb, array_ptr_ub) = i; @@ -333,7 +333,7 @@ extern void bounds_exprs(void) { array_ptr t127 : bounds(const_array_ptr_lb, array_ptr_const_ub) = i; array_ptr t128 : bounds(array_ptr_const_lb, const_array_ptr_ub) = i; - array_ptr 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 t130 : bounds(ptr_lb, array_ptr_ub) = i; array_ptr 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 t140 : bounds(nt_array_ptr_lb, const_nt_array_ptr_ub) = i; - array_ptr 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 t13 : bounds(c13, c13) = 0; // expected-error 2 {{expected expression with pointer type}} array_ptr t14 : bounds(c14, c14) = 0; // expected-error 2 {{expected expression with pointer type}} array_ptr t15 : bounds(c15, c15) = 0; // expected-error 2 {{expected expression with pointer type}} - array_ptr 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 t17 : bounds(double_indir, c3) = 0; // expected-error {{expected expression with pointer type}} @@ -420,7 +420,7 @@ extern void bounds_exprs(void) { array_ptr t32 : bounds(int_unchecked_ptr_lb, char_ptr_ub) = i; // expected-error {{pointer type mismatch}} array_ptr t33 : bounds(char_array_ptr_lb, int_ptr_ub) = (array_ptr) i; // expected-error {{pointer type mismatch}} array_ptr t34 : bounds(char_ptr_lb, int_ptr_ub) = (array_ptr) i; // expected-error {{pointer type mismatch}} - array_ptr t35 : bounds(char_unchecked_ptr_lb, int_ptr_ub) = (array_ptr) 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 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 g54: count(1) = 0; // expected-error {{bounds declaration not allowed because 'g54' has a _Ptr type}} -array_ptr 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 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 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 t54 : count(1) = 0; // expected-error {{bounds declaration not allowed because 't54' has a _Ptr type}} - array_ptr t55 : count(1) = 0; // expected-error {{expected 't55' to have a non-void pointer type}} - array_ptr 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 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 t64 : byte_count(sizeof(int)) = 0; // expected-error {{bounds declaration not allowed because 't64' has a _Ptr type}} array_ptr 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 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 t4 : byte_count(5 * sizeof(int)), array_ptr 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 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 : 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 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 fn1(void) : count(5) { return 0; } +int* _Array fn1(void) _Count(5) { return 0; } nt_array_ptr 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 fn10(void) : bounds(s1, s1 + 5) { return 0; } -nt_array_ptr fn10a(void) : bounds(s1, s1 + 5) { return 0; } +int* _Nt_array fn10a(void) _Bounds(s1, s1 + 5) { return 0; } array_ptr 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 mid : bounds((char *)p1, (char *)p1 + (5 * sizeof(int // function pointers. // Unchecked function pointers -void fn200(void (*fnptr)(array_ptr 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 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 p1 : byte_count(5 * sizeof(int)))); void fn204(int (*fnptr)(int * : byte_count(5 * sizeof(int)))); @@ -1039,8 +1040,8 @@ void fn231(ptr p1 : bounds((char *)p1, (char *)p1 + (5 * s // Function pointers with multiple arguments. void fn240(ptr mid : bounds(p1, p1 + 5), array_ptr p1)> fnptr); -void fn241(ptr mid : bounds((char *)p1, (char *)p1 + (5 * sizeof(int))), - array_ptr p1)> fnptr); +void fn241(ptr 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 (*fnptr)(void) : count(5)); void fn261(array_ptr(*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 (*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 (*fnptr)(void) : count(5)); // expected-error {{count void function_pointers(void) { // Assignments to function pointers with return bounds on array_ptr types array_ptr(*t1)(void) : count(5) = fn1; - nt_array_ptr(*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 t7 = fn3; array_ptr(*t8)(void) : byte_count(5 * sizeof(int)) = fn4; - array_ptr(*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 t12 = fn6; array_ptr(*t13)(void) : bounds(s1, s1 + 5) = fn10; - nt_array_ptr(*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(void) : count(5)> t100 = fn1; // The reverse is not allowed - array_ptr(*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(*t1)(void) : count(4) = fn1; // expected-error {{incompatible type}} ptr(void) : count(4)> t1a = fn1; // expected-error {{incompatible type}} array_ptr(*t4)(void) : byte_count(6 * sizeof(int)) = fn4; // expected-error {{incompatible type}} - array_ptr(*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 f301(void) : bounds(return_value, return_value + 10); array_ptr f302(void) : bounds(return_value - 5, return_value + 5); array_ptr f303(void) : count(return_value); // expected-error {{invalid argument type}} array_ptr f304(void) : bounds(arr, arr + (return_value << 5)); // expected-error {{invalid operands to binary expression}} -array_ptr 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}} diff --git a/tests/typechecking/checked_arrays.c b/tests/typechecking/checked_arrays.c index 2fab01a..a14ddd7 100644 --- a/tests/typechecking/checked_arrays.c +++ b/tests/typechecking/checked_arrays.c @@ -147,8 +147,8 @@ extern void check_assign(int val, int p[10], int q[], int r checked[10], int s c array_ptr t10 = s; array_ptr t9b = w; array_ptr t11 = t; - array_ptr t11a = u; - array_ptr t12 = u; + int* _Array t11a = u; + int* _Array t12 = u; nt_array_ptr t12a = x; nt_array_ptr t12b = u; // expected-error {{expression of incompatible type 'int _Checked[10]'}} array_ptr 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 t14 = t2d[0]; array_ptr t15 = u2d[0]; array_ptr t15a = x2d[0]; - nt_array_ptr t15b : bounds(unknown) = x2d[0]; - nt_array_ptr 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 t2 = val ? p : r; // T[N] and T checked[M] OK - array_ptr t2a = val ? p : v; // T[N] and T nt_checked[M] OK. - nt_array_ptr 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 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 t4d = val ? v : r; // expected-error {{incompatible type}} // But they produce only array_ptr - nt_array_ptr 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 t5 = val ? r : 0; array_ptr t5a = val ? v : 0; array_ptr t6 = val ? 0 : r; - nt_array_ptr 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 t7 = val ? u : 0; - array_ptr 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 t32 = val ? r_const : r; // array_ptr and array_ptr OK array_ptr t33 = val ? r_const : r_const; // array_ptr and array_ptr OK - array_ptr t25a = val ? p : s_const; // int * and nt_array_ptr OK + const int* _Array t25a = val ? p : s_const; // int * and nt_array_ptr OK array_ptr t26a = val ? s_const : p; // nt_array_ptr and int * OK array_ptr t27a = val ? p_const : s; // const int * and nt_array_ptr OK array_ptr t28a = val ? s : p_const; // nt_array_ptr and const int * OK @@ -633,7 +633,7 @@ extern void check_condexpr_cv(void) array_ptr t33b = val ? r_const : s_const; // array_ptr and nt_array_ptr OK array_ptr t33c = val ? s : s_const; // nt_array_ptr and nt_array_ptr OK array_ptr t33d = val ? s_const : s; // nt_array_ptr and nt_array_ptr OK - array_ptr t33e = val ? s_const : s_const; // nt_array_ptr and nt_array_ptr OK + const int* _Array t33e = val ? s_const : s_const; // nt_array_ptr and nt_array_ptr OK array_ptr t34 = val ? p : r_const; // expected-warning {{discards qualifiers}} // int * and array_ptr produce array_ptr @@ -651,8 +651,8 @@ extern void check_condexpr_cv(void) // array_ptr and array_ptr produce array_ptr array_ptr t41 = val ? r_const : r; // expected-warning {{discards qualifiers}} // array_ptr and array_ptr produce array_ptr - array_ptr t42 = val ? r_const : r_const; // expected-warning {{discards qualifiers}} - // array_ptr and array_ptr produce array_ptr + int* _Array t42 = val ? r_const : r_const; // expected-warning {{discards qualifiers}} + // array_ptr and array_ptr produce array_ptr array_ptr t34a = val ? p : s_const; // expected-warning {{discards qualifiers}} // int * and nt_array_ptr produce array_ptr @@ -680,7 +680,7 @@ extern void check_condexpr_cv(void) // nt_array_ptr and nt_array_ptr produce array_ptr array_ptr t43d = val ? s_const : s; // expected-warning {{discards qualifiers}} // nt_array_ptr and nt_array_ptr produce array_ptr - array_ptr 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 and nt_array_ptr produce array_ptr // test different kinds of pointers with volatile modifers @@ -719,7 +719,7 @@ extern void check_condexpr_cv(void) array_ptr t82d = val ? s_volatile : s; // nt_array_ptr and nt_array_ptr OK array_ptr t82e = val ? s_volatile : s_volatile; // nt_array_ptr and nt_array_ptr OK - array_ptr t83 = val ? p : r_volatile; // expected-warning {{discards qualifiers}} + int* _Array t83 = val ? p : r_volatile; // expected-warning {{discards qualifiers}} // int * and array_ptr produce array_ptr array_ptr t84 = val ? r_volatile : p; // expected-warning {{discards qualifiers}} // array_ptr and int * produce array_ptr @@ -762,7 +762,7 @@ extern void check_condexpr_cv(void) // nt_array_ptr and nt_array_ptr produce array_ptr array_ptr t92d = val ? s_volatile : s; // expected-warning {{discards qualifiers}} // nt_array_ptr and nt_array_ptr produce array_ptr - array_ptr 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 and nt_array_ptr produce array_ptr } @@ -827,7 +827,7 @@ extern void f13(_Bool p, int y) { extern void f1_void(void *p, int y) { } -extern void f2_void(ptr p, int y) { +extern void f2_void(void* _Single p, int y) { } extern void f3_void(array_ptr p, int y) { @@ -1037,7 +1037,7 @@ extern void check_call_void(void) { // TODO: s will need bounds information void *s = 0; - ptr t = 0; + void* _Single t = 0; array_ptr 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), - char **interop_ptr : itype(nt_array_ptr>), +extern void check_nt_bounds_safe_interface(const char *interop_string : itype(const char* _Nt_array), + char **interop_ptr _Itype(nt_array_ptr>), char checked_arr nt_checked[3], char unchecked_arr[3]) { // LHS of assignment has nt_array_ptr type and RHS of assignment // is an unchecked pointer with nt_array_ptr bounds-safe interface. - nt_array_ptr checked_str = interop_string; - nt_array_ptr> 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 type and RHS of assigment // is an unchecked pointer with nt_array_ptr bounds-safe interface, diff --git a/tests/typechecking/checked_scope_basic.c b/tests/typechecking/checked_scope_basic.c index 6ca84d3..21af4a3 100644 --- a/tests/typechecking/checked_scope_basic.c +++ b/tests/typechecking/checked_scope_basic.c @@ -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 t41[10]; // expected-error {{local variable in a checked scope must have a checked type}} - array_ptr 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 *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 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 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(int, int)> t61 = 0; - ptr(int, int)> t62 = 0; + ptr t62 = 0; // Function with different kinds of pointer arguments. ptr 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 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 p) { } // Test for checked function specifier & checked block. -int* func11(array_ptr 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 a; +int* _Single a; int b; { return 1; } int KNR_func6(a, b) -ptr a; +char*_Single a; ptr b; { return 1; @@ -277,7 +277,7 @@ ptr b; #pragma CHECKED_SCOPE ON void KNR_test(void) { ptr px = 0; - ptr 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 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 pb; - ptr 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 pc; - array_ptr 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 *f : itype(int* _Single); char *g : itype(array_ptr); } a = {0}; } @@ -414,7 +414,7 @@ int func29(void) { void func30(void) { int a = 5; int len = 10; - array_ptr 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 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 q, array_ptr r, array_ptr 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 p, int *q) unchecked { int a = 5; int *upa; - array_ptr 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 p, int *q) unchecked { upa = &a; // expected-error {{local variable used in a checked scope must have a checked type}} pc = &a; } - ptr pb = p; + int* _Single pb = p; return *pb; } -SCOPE_KIND array_ptr 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 *g : itype(int* _Single); char *h : itype(array_ptr); } 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 q, array_ptr r, array_ptr s : count(2)) { +unchecked int * func51(int *p, int* _Single q, int* _Array r, array_ptr 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 q, array_ptr r, array_ptr s : return 0; } -unchecked int func52(ptr 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 expects source to have bounds}} - array_ptr ax = &a[i]; - array_ptr ay = &b[2]; - array_ptr 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 array_ptr px = &(*(b+i)); array_ptr py = &b[i]; - array_ptr 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 expects source to have bounds}} // checkSingleAssignmentConstraints(int * -> _Array_ptr implicit casting) - array_ptr ax = &a[i]; // ImplicitCastExpr _Array_ptr(UnaryOperator) - array_ptr ay = &b[0]; // ImplicitCastExpr _Array_ptr(UnaryOperator) - array_ptr az = &i; // ImplicitCastExpr _Array_ptr(UnaryOperator) + int* _Array ax = &a[i]; // ImplicitCastExpr _Array_ptr(UnaryOperator) + int* _Array ay = &b[0]; // ImplicitCastExpr _Array_ptr(UnaryOperator) + int* _Array az = &i; // ImplicitCastExpr _Array_ptr(UnaryOperator) ax = &a[i]; // ImplicitCastExpr _Array_ptr(UnaryOperator) ay = &b[0]; // ImplicitCastExpr _Array_ptr(UnaryOperator) @@ -935,8 +935,8 @@ void test_addrof_unchecked_scope(void) unchecked { pz = &(*(a+i)); // UnaryOperator _Array_ptr() } -int *gptr0 : itype(ptr); -int *gptr1 : itype(array_ptr); +int *gptr0 _Itype(ptr); +int *gptr1 _Itype(array_ptr); 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 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 p, int y) { +extern void f2_void(void* _Single p, int y) { } extern void f3_void(array_ptr 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 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 h10(void) { return global_arr1; // expected-error {{variable used in a checked scope must have a checked type}} } -SCOPE_KIND array_ptr 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 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 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 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 q_int = 0; + int* _Single q_int = 0; q_int = val_int; - ptr q_float = 0; + float* _Single q_float = 0; q_float = val_float; array_ptr r_int = val_int; - array_ptr 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) &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 vpa = 0; + int (* _Single vpa)(int,int) = 0; vpa = (ptr) &arr; // expected-error {{type in a checked scope cannot have variable arguments}} vpa = (ptr)>) &arr; // expected-error {{type in a checked scope cannot have variable arguments}} vpa = (ptr) &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 q = 0; - array_ptr r : count(5) = 0; + int* _Single q = 0; + int* _Array r _Count(5) = 0; SCOPE_KIND { p = _Dynamic_bounds_cast(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>(r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}} vpa = _Assume_bounds_cast)>>(r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}} - vpa = _Assume_bounds_cast>(r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}} - vpa = _Assume_bounds_cast, ...)>>(r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}} + vpa = _Assume_bounds_cast_M_N(ptr ,r); // expected-error {{_Assume_bounds_cast not allowed in a checked scope or function}} + vpa = _Assume_bounds_cast_M_N(ptr, ...)>, 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, ...)> e = 0; // expected-error {{variable in a checked scope cannot have variable arguments}} ptr, ...)> 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 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 var_b = 0; @@ -1660,7 +1662,7 @@ SCOPE_KIND void checked_check_variadic1(int (*fptr)(int, ptr, array_ptr, array_ptr, ...)) SCOPE_KIND { +void checked_check_variadic2(int (*fptr)(int, int* _Single, int* _Array, ...)) SCOPE_KIND { ptr a = 0; array_ptr 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 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 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)> fn8 = &id_checked_intp; - ptr(ptr)> 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 except for function type @@ -1740,8 +1742,8 @@ extern void test_cast_to_nt_array_ptr(void) checked { nt_array_ptr p6 = (nt_array_ptr)arr_i; // expected-error {{'_Array_ptr' cannot be cast to '_Nt_array_ptr' in a checked scope because '_Array_ptr' might not point to a null-terminated array}} p6 = (nt_array_ptr)p5; // expected-error {{'_Array_ptr' cannot be cast to '_Nt_array_ptr' in a checked scope because '_Array_ptr' might not point to a null-terminated array}} array_ptr p7 : count(5) = arr_c; - nt_array_ptr p8 = (nt_array_ptr)arr_c; // expected-error {{'_Array_ptr' cannot be cast to '_Nt_array_ptr' in a checked scope because '_Array_ptr' might not point to a null-terminated array}} - p8 = (nt_array_ptr)p7; // expected-error {{'_Array_ptr' cannot be cast to '_Nt_array_ptr' in a checked scope because '_Array_ptr' might not point to a null-terminated array}} + char* _Nt_array p8 = (char* _Nt_array)arr_c; // expected-error {{'_Array_ptr' cannot be cast to '_Nt_array_ptr' in a checked scope because '_Array_ptr' might not point to a null-terminated array}} + p8 = (char* _Nt_array)p7; // expected-error {{'_Array_ptr' cannot be cast to '_Nt_array_ptr' in a checked scope because '_Array_ptr' might not point to a null-terminated array}} // Test casting nt_array_ptr to nt_array_ptr nt_array_ptr 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)arr_i; // allowed here; disallowed in a checked scope. - p6 = (nt_array_ptr)p5; // allowed here; disallowed in a checked scope. - p8 = (nt_array_ptr)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)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)arr_i_unchecked; // allowed char arr_c_unchecked[5]; - p8 = (nt_array_ptr)arr_c_unchecked; // allowed + p8 = (char* _Nt_array)arr_c_unchecked; // allowed } } diff --git a/tests/typechecking/checked_scope_interfaces.c b/tests/typechecking/checked_scope_interfaces.c index df72ceb..96ead5f 100644 --- a/tests/typechecking/checked_scope_interfaces.c +++ b/tests/typechecking/checked_scope_interfaces.c @@ -22,7 +22,7 @@ #include // Parameters with simple types. -checked int f1(int *s : itype(ptr)) { +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'}} @@ -32,8 +32,8 @@ checked int f1(int *s : itype(ptr)) { array_ptr t4 : count(1) = s; s = t4; - array_ptr t5 : count(1) = s; // expected-error {{incompatible type}} - array_ptr 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 len) { +checked int f3(int *s _Itype(int *_Array), int len) { array_ptr 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 len) { return 0; } -checked int f4(int *s : itype(int checked[4])) { - array_ptr 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 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 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 p, int *q : itype(ptr)) : itype(ptr) { +checked int* func10(int *_Single p, int *q _Itype(int *_Single)) _Itype(int *_Single) { int a = 5; - ptr pa = &a; - ptr pb = p; - ptr 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 *_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'}} *(g1 + 4) = 0; // expected-error {{arithmetic on _Ptr type}} g1[4] = 0; // expected-error {{subscript of '_Ptr'}} - array_ptr t4 : count(1) = g1; + int *_Array t4 _Count(1) = g1; g1 = t4; - array_ptr t5 : count(1) = g1; // expected-error {{incompatible type}} - array_ptr t6 = 0; + float* _Array t5 _Count(1) = g1; // expected-error {{incompatible type}} + float* _Array t6 = 0; g1 = t6; // expected-error {{incompatible type}} - // array_ptr 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 without bounds - array_ptr 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 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 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)); void f11(int *p : count(4)); void f12(int *p : itype(array_ptr)); void f13(int *p : itype(int checked[])); -void f14(int *p : itype(int checked[4])); -void f15(ptr p, int *q : itype(ptr)); - +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 param1 = 0; array_ptr param2 : count(4) = 0; - array_ptr param3; + int *_Array param3; int arr1 checked[4]; f10(param1); f10(param2); @@ -243,8 +242,8 @@ checked void f11d(int *lower : itype(array_ptr), checked void f11e(char *buf : bounds(buf, end), char *end : itype(_Array_ptr)); checked void f12a(int *p : itype(array_ptr)); -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 p, int *q : itype(ptr)); @@ -255,13 +254,14 @@ checked int* f20(int a checked[][5], int b checked[][5]) : itype(ptr) { return 0; } -checked int* f21(int *a : itype(ptr), int *b : itype(array_ptr)) : itype(array_ptr) 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 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 t1 = f20(arr1, arr1); + int *_Single t1 = f20(arr1, arr1); int arr2 checked[4]; array_ptr t2 = f21(0, arr2); @@ -308,7 +308,7 @@ checked int* f22() : itype(array_ptr); // 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 *f30(void) _Itype(int *_Single) { checked{ ptr 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)) : itype(ptr) { +int *f32(int * p _Itype(int *_Single)) _Itype(ptr) { checked{ return p; } @@ -385,7 +385,7 @@ int *f36(void) : itype(ptr) { int ga = 5; -checked int * func37(void) : itype(array_ptr) _Unchecked { +checked int * func37(void) _Itype(int *_Array) _Unchecked { int *upa = &ga; return upa; } @@ -402,8 +402,8 @@ checked int * func38(void) : itype(ptr) _Unchecked { #pragma CHECKED_SCOPE ON struct S1 { int *f1 : itype(ptr); - 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 arr[5] : itype(int checked[5]); // pointer to function that returns a ptr> - int **((*fp1)(int *param : itype(ptr))) : - itype(ptr> (int *param : itype(ptr))>); + 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> int **((*fp2)(int *param : itype(ptr),int len)) : itype(ptr>(int *param : itype(ptr), int len) : count(len)>); }; -checked int test_struct3(struct S2 *p : itype(ptr)) { +checked int test_struct3(struct S2 *p _Itype(ptr)) { (*(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)) { } // Unchecked version - there should be no error messages. -unchecked int test_struct4(struct S2 *p : itype(ptr)) { +unchecked int test_struct4(struct S2 *p _Itype(ptr)) { (*(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 arg1, ptr> arg2, int num) { +checked void test1_array_of_function_pointers(int *_Single arg1, ptr arg2, int num) { ptr 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) // bound-safe interface for func - ) : itype(_Ptr) // bounds-safe interface for signal return - )(int); + itype(_Ptr) // bound-safe interface for func + ) _Itype(_Ptr) // bounds-safe interface for signal return + )(int); void handler(int); // for testing signal. void test_bounds_safe_interface(void) { - array_ptr 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 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 arr2 = checked_realloc(arr1, 20); - array_ptr 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); diff --git a/tests/typechecking/checked_scope_pragma.c b/tests/typechecking/checked_scope_pragma.c index 85575d4..f4d51e8 100644 --- a/tests/typechecking/checked_scope_pragma.c +++ b/tests/typechecking/checked_scope_pragma.c @@ -21,7 +21,7 @@ #include -int printf(const char * restrict format : itype(restrict _Nt_array_ptr), ...); +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 p, int *q : itype(ptr), int r[], array_ptr 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 pc = p; - array_ptr 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 p, int *q : itype(ptr), int r[], array_ptr 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 p, int *q : itype(ptr), int r[], ar } -array_ptr 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 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 unchecked_func1_checked_body(int *x, int *y) { return upb; } -unchecked array_ptr 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 *b : itype(array_ptr)) : itype(array_ptr) { +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 pb = checked_func2_checked_parm_checked_ret(e, e); - ptr 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 checked_func_u1(int *p, ptr q, array_ptr r, array_ptr 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 checked_func_u1(int *p, ptr q, array_ptr r, array_ptr s return q; } -ptr checked_func_u1_pragma(int *p, ptr q, array_ptr r, array_ptr 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 checked_func_u1_pragma(int *p, ptr q, array_ptr r, array_ptr< return q; } -int * checked_func_uc(void) : itype(array_ptr) 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) unchecked { return upa; } -int * checked_func_uc_pragma(void) : itype(array_ptr) { +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) { return upa; } -int checked_func_ucu1(int *p, int *q, int *r : itype(ptr), int *s : itype(array_ptr)) 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 *s : itype(a return sum; } -int checked_func_ucu1_pragma(int *p, int *q, int *r : itype(ptr), int *s : itype(array_ptr)) { // 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 *s : return sum; } -int checked_func_ucu2(ptr 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 pc; @@ -450,8 +450,8 @@ unchecked int * unchecked_func3_checked_body(int *p, int q[]) { unchecked array_ptr unchecked_func4_unchecked_body(int p[], int q[10], int r[][10]) { int *upa; int *upb; - array_ptr pb; - ptr pc = 0; + int* _Array pb; + int* _Single pc = 0; upa = pb; // expected-error {{assigning to 'int *' from incompatible type '_Array_ptr'}} upa = pc; // expected-error {{assigning to 'int *' from incompatible type '_Ptr'}} upb = pb; // expected-error {{assigning to 'int *' from incompatible type '_Array_ptr'}} @@ -468,7 +468,7 @@ unchecked array_ptr 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 pb; - ptr pc = 0; + int* _Single pc = 0; upa = pb; upa = pc; upb = pb; @@ -530,8 +530,8 @@ int **a4 : itype(ptr>) = 0; int **a5 : itype(array_ptr>) = 0; int **a6 : itype(array_ptr>) = 0; int ***a7 : itype(ptr>>) = 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 pc; - array_ptr 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 pc; - array_ptr 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 p, ...) { // expected-error {{vari #endif void checked_func_call_variadic(void) { ptr a = 0; - array_ptr b; + int* _Array b; printf("check function call variadic %d\n", *a); #pragma CHECKED_SCOPE OFF printf("check function call variadic %d\n", *a); diff --git a/tests/typechecking/existential_structs.c b/tests/typechecking/existential_structs.c index e5baf14..b672035 100644 --- a/tests/typechecking/existential_structs.c +++ b/tests/typechecking/existential_structs.c @@ -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) exist) { - _Exists(U, struct Foo) 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) exist) { - exist.elem = 0; // expected-error {{member reference base type 'Exists(T, struct Foo)' is not a structure or union}} -} - -// Test that pack returns an existential type. -void TestPackReturnType() { - struct Foo fooInt; - _Exists(T, struct Foo) foo = _Pack(fooInt, _Exists(U, struct Foo), 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 fooInt; - struct Foo > fooNested; - _Exists(T, struct Foo) foo = _Pack(fooInt, _Exists(T, struct Foo), int); // ok: witness and expected types match - _Pack(fooInt, _Exists(T, struct Foo), char); // expected-error {{witness type does not match existential type}} - _Pack(fooNested, _Exists(T, struct Foo), int); // expected-error {{witness type does not match existential type}} - _Exists(T, struct Foo >) e = _Pack(fooNested, _Exists(T, struct Foo >), int); // ok - _Exists(T, struct Foo) e2 = _Pack(fooNested, _Exists(T, struct Foo), struct Foo); // ok -} - -// Test that the same expression can be packed in different ways, -// if we change the substitution and return types. -void TestMultiplePacks() { - struct Foo > > fooInt3; - _Pack(fooInt3, _Exists(T, struct Foo), struct Foo >); // expected-warning {{expression result unused}} - _Pack(fooInt3, _Exists(T, struct Foo >), struct Foo); // expected-warning {{expression result unused}} - _Pack(fooInt3, _Exists(T, struct Foo), struct Foo >); // 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 bar; - _Pack(bar, _Exists(T, struct Bar), struct Cat); // expected-warning {{expression result unused}} - _Pack(bar, _Exists(T, struct Bar), struct Dog); // expected-warning {{expression result unused}} - _Pack(bar, _Exists(T, struct Bar), struct Sheep); // expected-warning {{expression result unused}} - - _Pack(bar, _Exists(T, struct Bar), 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 fooInt; - _Exists(T2, struct Foo) packedFoo = _Pack(fooInt, _Exists(T2, struct Foo), int); - - // TODO: the error message should reference 'struct Foo' and not 'struct Foo'. - // 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 incorrect = packedFoo; // expected-error {{initializing 'struct Foo' with an expression of incompatible type 'struct Foo'}} - - // Now let's try a correct unpack. - _Unpack (U) struct Foo unpackedFoo = packedFoo; - U *a2 = unpackedFoo.a; - unpackedFoo.op(a2); -} - -_Exists(A, struct Foo) foo1; -_Exists(A, _Exists(B, struct Foo)) foo2; -_Exists(A, _Exists(B, struct Foo)) foo3; -_Exists(A, _Exists(B, _Exists(C, struct Foo))) 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) bar1; - _Exists(A, _Exists(B, struct Foo)) bar2; - _Exists(A, _Exists(B, struct Foo)) bar3; - _Exists(A, _Exists(B, _Exists(C, struct Foo))) 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' in canonical types below after we've fixed canonicalization of type applications - bar1 = foo2; // expected-error {{assigning to 'Exists(A, struct Foo)' from incompatible type 'Exists(A, Exists(B, struct Foo))'}} - bar2 = foo3; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo))') from incompatible type 'Exists(A, Exists(B, struct Foo))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo))')}} - bar3 = foo4; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo))' from incompatible type 'Exists(A, Exists(B, Exists(C, struct Foo)))'}} - bar4 = foo1; // expected-error {{assigning to 'Exists(A, Exists(B, Exists(C, struct Foo)))' from incompatible type 'Exists(A, struct Foo)'}} - - _Exists(A, _Exists(B, struct Foo)) zoom1; - zoom1 = foo2; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo))' (aka 'Exists((1, 0), Exists((2, 0), struct Foo))') from incompatible type 'Exists(A, Exists(B, struct Foo))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo))')}} - zoom1 = foo3; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo))' from incompatible type 'Exists(A, Exists(B, struct Foo))'}} -} - -// 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) a1; - _Exists(B, struct Foo) a2; - a1 = a2; - a2 = a1; - - _Exists(A, _Exists(B, struct Pair)) b1; - _Exists(T1, _Exists(T2, struct Pair)) 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)>)) d1; - _Exists(T1, _Exists(T2, struct Foo<_Exists(T3, struct Foo)>)) 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 fooInt; - _Exists(T, struct Foo) fooExists = _Pack(fooInt, struct Foo, int); // expected-error {{return type of a pack expression must be an existential type, but got 'struct Foo' 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) fooExist; - _Unpack (A, B, C) struct Foo 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 fooInt; - _Exists(B, struct Foo) fooExist = _Pack(fooInt, _Exists(C, struct Foo), int); - _Unpack (A) struct Foo fooA = fooInt; // expected-error {{unpack specifer expects an initializer that has an existential type}} - _Unpack (B) struct Foo 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 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) exist) { + _Exists(U, struct Foo) 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) exist) { + exist.elem = 0; // expected-error {{member reference base type 'Exists(T, struct Foo)' is not a structure or union}} +} + +// Test that pack returns an existential type. +void TestPackReturnType() { + struct Foo fooInt; + _Exists(T, struct Foo) foo = _Pack(fooInt, _Exists(U, struct Foo), 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 fooInt; + struct Foo > fooNested; + _Exists(T, struct Foo) foo = _Pack(fooInt, _Exists(T, struct Foo), int); // ok: witness and expected types match + _Pack(fooInt, _Exists(T, struct Foo), char); // expected-error {{witness type does not match existential type}} + _Pack(fooNested, _Exists(T, struct Foo), int); // expected-error {{witness type does not match existential type}} + _Exists(T, struct Foo >) e = _Pack(fooNested, _Exists(T, struct Foo >), int); // ok + _Exists(T, struct Foo) e2 = _Pack(fooNested, _Exists(T, struct Foo), struct Foo); // ok +} + +// Test that the same expression can be packed in different ways, +// if we change the substitution and return types. +void TestMultiplePacks() { + struct Foo > > fooInt3; + _Pack(fooInt3, _Exists(T, struct Foo), struct Foo >); // expected-warning {{expression result unused}} + _Pack(fooInt3, _Exists(T, struct Foo >), struct Foo); // expected-warning {{expression result unused}} + _Pack(fooInt3, _Exists(T, struct Foo), struct Foo >); // 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 bar; + _Pack(bar, _Exists(T, struct Bar), struct Cat); // expected-warning {{expression result unused}} + _Pack(bar, _Exists(T, struct Bar), struct Dog); // expected-warning {{expression result unused}} + _Pack(bar, _Exists(T, struct Bar), struct Sheep); // expected-warning {{expression result unused}} + + _Pack(bar, _Exists(T, struct Bar), 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 fooInt; + _Exists(T2, struct Foo) packedFoo = _Pack(fooInt, _Exists(T2, struct Foo), int); + + // TODO: the error message should reference 'struct Foo' and not 'struct Foo'. + // 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 incorrect = packedFoo; // expected-error {{initializing 'struct Foo' with an expression of incompatible type 'struct Foo'}} + + // Now let's try a correct unpack. + _Unpack (U) struct Foo unpackedFoo = packedFoo; + U *a2 = unpackedFoo.a; + unpackedFoo.op(a2); +} + +_Exists(A, struct Foo) foo1; +_Exists(A, _Exists(B, struct Foo)) foo2; +_Exists(A, _Exists(B, struct Foo)) foo3; +_Exists(A, _Exists(B, _Exists(C, struct Foo))) 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) bar1; + _Exists(A, _Exists(B, struct Foo)) bar2; + _Exists(A, _Exists(B, struct Foo)) bar3; + _Exists(A, _Exists(B, _Exists(C, struct Foo))) 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' in canonical types below after we've fixed canonicalization of type applications + bar1 = foo2; // expected-error {{assigning to 'Exists(A, struct Foo)' from incompatible type 'Exists(A, Exists(B, struct Foo))'}} + bar2 = foo3; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo))') from incompatible type 'Exists(A, Exists(B, struct Foo))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo))')}} + bar3 = foo4; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo))' from incompatible type 'Exists(A, Exists(B, Exists(C, struct Foo)))'}} + bar4 = foo1; // expected-error {{assigning to 'Exists(A, Exists(B, Exists(C, struct Foo)))' from incompatible type 'Exists(A, struct Foo)'}} + + _Exists(A, _Exists(B, struct Foo)) zoom1; + zoom1 = foo2; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo))' (aka 'Exists((1, 0), Exists((2, 0), struct Foo))') from incompatible type 'Exists(A, Exists(B, struct Foo))' (aka 'Exists((0, 0), Exists((1, 0), struct Foo))')}} + zoom1 = foo3; // expected-error {{assigning to 'Exists(A, Exists(B, struct Foo))' from incompatible type 'Exists(A, Exists(B, struct Foo))'}} +} + +// 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) a1; + _Exists(B, struct Foo) a2; + a1 = a2; + a2 = a1; + + _Exists(A, _Exists(B, struct Pair)) b1; + _Exists(T1, _Exists(T2, struct Pair)) 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)>)) d1; + _Exists(T1, _Exists(T2, struct Foo<_Exists(T3, struct Foo)>)) 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 fooInt; + _Exists(T, struct Foo) fooExists = _Pack(fooInt, struct Foo, int); // expected-error {{return type of a pack expression must be an existential type, but got 'struct Foo' 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) fooExist; + _Unpack (A, B, C) struct Foo 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 fooInt; + _Exists(B, struct Foo) fooExist = _Pack(fooInt, _Exists(C, struct Foo), int); + _Unpack (A) struct Foo fooA = fooInt; // expected-error {{unpack specifer expects an initializer that has an existential type}} + _Unpack (B) struct Foo 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 fooA; // expected-error {{expected type variable identifier}} expected-error {{unknown type name 'A'}} } \ No newline at end of file diff --git a/tests/typechecking/interop.c b/tests/typechecking/interop.c index 8c49651..15125f3 100644 --- a/tests/typechecking/interop.c +++ b/tests/typechecking/interop.c @@ -14,7 +14,7 @@ // // -void f1(int *p : itype(ptr)) { +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 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 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 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 p) { f1(p); // expected-error {{incompatible type}} } -void g4(array_ptr 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)) { 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 p) { f1_const(p); } -void g11(array_ptr 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 p) { v1 = p; } -void g21(array_ptr ap : count(10)) { +void g21(int* _Array ap _Count(10)) { v2 = ap; v3 = ap; v4 = ap; @@ -363,7 +363,7 @@ void g22(ptr p) { v1 = p; // expected-error {{incompatible type}} } -void g23(array_ptr 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 p) { v1_void = p; } -void g27(array_ptr 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 p) { const_v1 = p; } -void g31(array_ptr 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 p) { v1_const = p; // expected-error {{cannot assign to variable}} } -void g35(array_ptr 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 p, ptr p1, array_ptr 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 p, ptr p1, array_ptr 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>) count(3), ptr checked_ptr) { +void g90(int **interop_ptr _Itype(array_ptr>) count(3), int* _Single checked_ptr) { *interop_ptr = checked_ptr; *(interop_ptr - 1) = checked_ptr; *(2 + interop_ptr) = checked_ptr; diff --git a/tests/typechecking/itype_generic_functions.c b/tests/typechecking/itype_generic_functions.c index 4563202..3029356 100644 --- a/tests/typechecking/itype_generic_functions.c +++ b/tests/typechecking/itype_generic_functions.c @@ -10,7 +10,7 @@ _Itype_for_any(T) void* oneTypeVariable(void* a : itype(_Ptr), void* b : ityp return a; } -_Itype_for_any(T, Q) void* manyTypeVariables(void* a : itype(_Ptr), void* b : itype(_Ptr)) : itype(_Ptr) { +_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), void* c : itype(_Ptr)) : itype(_Ptr); _Itype_for_any(T) -void* validItypeGenericFunction(int a, void* b : itype(_Ptr) , void* c : itype(_Ptr) ) : itype(_Ptr) { - _Ptr 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 ap = &a; diff --git a/tests/typechecking/malloc_free.c b/tests/typechecking/malloc_free.c index 6f1c741..930b8d1 100644 --- a/tests/typechecking/malloc_free.c +++ b/tests/typechecking/malloc_free.c @@ -37,7 +37,7 @@ void f4(void) unchecked { // Test you can always `free` a `malloc`d ptr void f11(void) { - ptr x = malloc(sizeof(int)); + int* _Single x = malloc _TyArgs(int) (sizeof(int)); free(x); } @@ -78,9 +78,9 @@ void f22(void) { // Test you can always `free` a `realloc`d array_ptr void f23(void) { - array_ptr x : count(4) = malloc(4 * sizeof(int)); - array_ptr y : count(8) = realloc(x, 8 * sizeof(int)); - free(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 diff --git a/tests/typechecking/no_prototype_functions.c b/tests/typechecking/no_prototype_functions.c index de39f45..030c064 100644 --- a/tests/typechecking/no_prototype_functions.c +++ b/tests/typechecking/no_prototype_functions.c @@ -81,7 +81,7 @@ union U7 { // embedded in objects. // -extern ptr 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 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); // expected-error {{function with no prototype c // Returns an unchecked pointer to a no-prototype function returning a checked // value (ptr) -extern ptr (*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) extern ptr)> f21(); // expected-error {{function with no prototype cannot have a return type that is a checked type}} @@ -120,7 +120,7 @@ extern ptr)> f21(); // expected-error {{function with no prototype // pointers to function types that take or return checked values. extern ptr *f30(); -extern array_ptr *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 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); +extern int *f53() _Itype(ptr); // 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); // 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); // 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 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)); // 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 (*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 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 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}} diff --git a/tests/typechecking/pointer-larger-int/bounds.c b/tests/typechecking/pointer-larger-int/bounds.c index 710cd48..045c14a 100644 --- a/tests/typechecking/pointer-larger-int/bounds.c +++ b/tests/typechecking/pointer-larger-int/bounds.c @@ -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 - -_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'}} - - // bounds - int t25 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} - long int t26 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} - unsigned long int t27 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} - enum E1 t28 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} -} +// 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 + +_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'}} + + // bounds + int t25 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} + long int t26 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} + unsigned long int t27 : bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} + enum E1 t28 _Bounds(a1, a1 + 5) = (int)a1; // expected-warning {{cast to smaller integer type 'int' from '_Array_ptr'}} +} diff --git a/tests/typechecking/pointer-larger-long/bounds.c b/tests/typechecking/pointer-larger-long/bounds.c index 685ab50..fce3bc4 100644 --- a/tests/typechecking/pointer-larger-long/bounds.c +++ b/tests/typechecking/pointer-larger-long/bounds.c @@ -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 - -_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'}} - 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'}} -} +// 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 + +_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'}} + 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'}} +} diff --git a/tests/typechecking/pointer-sized-long/function_casts.c b/tests/typechecking/pointer-sized-long/function_casts.c index ba521d5..6c64233 100644 --- a/tests/typechecking/pointer-sized-long/function_casts.c +++ b/tests/typechecking/pointer-sized-long/function_casts.c @@ -11,7 +11,7 @@ int f0(int a) { return a; } -void local_convert(int(*f1)(int), ptr 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 local_weird_unsafe1 = (ptr)~(long)f1; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr'}} @@ -24,7 +24,7 @@ void local_convert(int(*f1)(int), ptr f2) { ptr local_weird_unsafe8 = (ptr) + (long)f2; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr'}} ptr local_weird_unsafe9 = (ptr) + (long)f0; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr'}} ptr local_weird_unsafe10 = (ptr) - (long)f1; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr'}} - ptr local_weird_unsafe11 = (ptr) - (long)f2; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr'}} - ptr local_weird_unsafe12 = (ptr) - (long)f0; // expected-error {{can only cast function names or null pointers to checked function pointer type '_Ptr'}} + 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 (*_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'}} } \ No newline at end of file diff --git a/tests/typechecking/pointer-sized-long/pointer_casts.c b/tests/typechecking/pointer-sized-long/pointer_casts.c index 5fde145..48b58a5 100644 --- a/tests/typechecking/pointer-sized-long/pointer_casts.c +++ b/tests/typechecking/pointer-sized-long/pointer_casts.c @@ -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 b, // expected-warning 2 {{cast to '_Array_ptr' from smaller integer type 'short'}} \ // expected-warning 2 {{cast to smaller integer type 'short' from '_Array_ptr'}} -extern int f11(int a, _Array_ptr b, _Array_ptr p : bounds(b, b + a)); -extern int f11(int a, _Array_ptr b, - _Array_ptr p : bounds(b, (_Array_ptr) (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)); + diff --git a/tests/typechecking/pointer_types.c b/tests/typechecking/pointer_types.c index d9b888d..3ce0462 100644 --- a/tests/typechecking/pointer_types.c +++ b/tests/typechecking/pointer_types.c @@ -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 p, ptr 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 p : count(1), @@ -84,17 +84,17 @@ extern void check_subscript_nt_array_ptr(nt_array_ptr p : count(1), // Test restrictions on null-terminated pointer types. void check_nullterm_restrictions(void) { - nt_array_ptr t1 = 0; // integer types are OK. - nt_array_ptr> 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 t3 = 0; // enum types are OK + enum E* _Nt_array t3 = 0; // enum types are OK - nt_array_ptr t10 = 0; // expected-error {{only integer and pointer types are allowed}} - nt_array_ptr t11 = 0; // expected-error {{only integer and pointer types are allowed}} - nt_array_ptr t12 = 0; // expected-error {{only integer and pointer types are allowed}} - nt_array_ptr 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 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 q, array_ptr r, // T * = nt_array_ptr not OK ptr t8 = r; // expected-error {{expression has unknown bounds}} // ptr = array_ptr OK - ptr t8a = v; // ptr = nt_array_ptr OK. - array_ptr t9 = q; // array_ptr = ptr OK - array_ptr t10a = v; // array_ptr = nt_array_ptr OK. - nt_array_ptr t10b = q; // expected-error {{incompatible type}} - // nt_array_ptr = ptr not OK. - nt_array_ptr t10ca = r; // expected-error {{incompatible type}} - // nt_array_ptr = array_ptr not OK. + int* _Single t8a = v; // ptr = nt_array_ptr OK. + int* _Array t9 = q; // array_ptr = ptr OK + int* _Array t10a = v; // array_ptr = nt_array_ptr OK. + int* _Nt_array t10b = q; // expected-error {{incompatible type}} + // nt_array_ptr = ptr not OK. + int* _Nt_array t10ca = r; // expected-error {{incompatible type}} + // nt_array_ptr = array_ptr 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 q, array_ptr r, // array_ptr = S * not OK; array_ptr t25 = q; // expected-error {{incompatible type}} // array_ptr = ptr not OK; - array_ptr t26 = r; // expected-error {{incompatible type}} + float* _Array t26 = r; // expected-error {{incompatible type}} // array_ptr = array_ptr not OK // C compilers enforcing C99 conversion rules allow implicit @@ -210,8 +210,8 @@ extern void check_assign(int val, int *p, ptr q, array_ptr r, ptr t38 = (_Bool)(1); // expected-error {{incompatible type}} ptr t39 = (_Bool)(1); // expected-error {{incompatible type}} array_ptr t40 = (_Bool)(1); // expected-error {{incompatible type}} - array_ptr t41 = (_Bool)(1); // expected-error {{incompatible type}} - nt_array_ptr 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 t42 = 0; @@ -242,7 +242,7 @@ extern void check_assign(int val, int *p, ptr q, array_ptr r, array_ptr t53 = unchecked_ptr_to_checked_ptr; // expected-error {{incompatible type}} array_ptr t54 = checked_ptr_to_checked_ptr; // expected-error {{incompatible type}} - array_ptr 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 q, array_ptr t25 = u; nt_array_ptr t25a = (void *)&val; // expected-error {{incompatible type}} // nt_array_ptr = void * not OK. - nt_array_ptr t25b = s; // expected-error {{incompatible type}} - // nt_array_ptr = void * not OK, even with obunds - nt_array_ptr t25c = t; // expected-error {{incompatible type}} - // nt_array_ptr = ptr not OK. - nt_array_ptr t25d = u; // expected-error {{incompatible type}} - // nt_array_ptr = array_ptr 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 not OK; @@ -367,8 +367,8 @@ check_assign_void_unchecked(int val, int *p, ptr q, array_ptr t35 = (_Bool)(1); // expected-error {{incompatible type}} // Implicit conversion of 0 to a safe void pointer type is OK. - ptr t37 = 0; - array_ptr 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 q, // Checked scope struct CheckedData1 { int len; - array_ptr 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 q = 0; - array_ptr 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 q = 0; - array_ptr r : count(1) = 0; + int* _Single q = 0; + int* _Array r : count(1) = 0; ptr s = 0; - ptr t = 0; - array_ptr u : byte_count(sizeof(struct CheckedData1)) = 0; - nt_array_ptr 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 check_voidptr_return21(int *p) { return p; } -array_ptr 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 check_voidptr_return28(nt_array_ptr p : count(1)) { return p; } -array_ptr check_voidptr_return29(ptr p) { +void* _Array check_voidptr_return29(ptr p) { return p; } @@ -2483,8 +2483,8 @@ void check_pointer_equality_compare(void) array_ptr r_void = val_int; array_ptr r2_void = val_int; - nt_array_ptr s_int = 0; - nt_array_ptr s2_int = 0; + int* _Nt_array s_int = 0; + int* _Nt_array s2_int = 0; nt_array_ptr 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 q = &val[0]; - array_ptr r = val; - nt_array_ptr 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 str, - _Array_ptr arr : count(10), - _Ptr p) { + char* _Nt_array str, + char* _Array arr : count(10), + char* _Single p) { _Unchecked { test_sprintf(s); test_sprintf(&*s); diff --git a/tests/typechecking/static_variables_free_type_variables.c b/tests/typechecking/static_variables_free_type_variables.c index 90042f0..cee4829 100644 --- a/tests/typechecking/static_variables_free_type_variables.c +++ b/tests/typechecking/static_variables_free_type_variables.c @@ -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) gs; - -// -// Test that declarations of static variables cannot use free type variables. -// - -_For_any(T, U, V) void f1(_Ptr pt, struct S 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 p; // expected-error {{static variable 'p' has a type that uses a type variable bound in an enclosing scope (type is '_Ptr' and type variable is 'U')}} \ - // expected-note@15 {{type variable 'U' declared here}} - - static _Array_ptr a1; // expected-error {{static variable 'a1' has a type that uses a type variable bound in an enclosing scope (type is '_Array_ptr' and type variable is 'V')}} \ - // expected-note@15 {{type variable 'V' declared here}} - - static _Array_ptr<_Array_ptr> 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>' and type variable is 'T')}} \ - // expected-note@15 {{type variable 'T' declared here}} - - static struct S s1; // expected-error {{static variable 's1' has a type that uses a type variable bound in an enclosing scope (type is 'struct S' 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' and type variable is 'U')}} \ - // expected-note@15 {{type variable 'U' declared here}} - - static _Exists(T, _Ptr) e1; // expected-error {{static variable 'e1' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(T, _Ptr)' and type variable is 'U')}} \ - // expected-note@15 {{type variable 'U' declared here}} - - static _Exists(T, struct S) 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)' 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)' and type variable is 'V')}} \ - // expected-note@15 {{type variable 'V' declared here}} - - static _Exists(A, struct S) 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)' 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)' 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)' 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, double> s2; - static _Exists(T, _Ptr) e4; - static _Exists(A, struct S, _Array_ptr>) e5; - - // Non-static variable declarations can use free type variables. - _Ptr q = 0; - _Array_ptr<_Array_ptr> a3; - struct S s3; - _Exists(U, _Ptr) 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) gs; + +// +// Test that declarations of static variables cannot use free type variables. +// + +_For_any(T, U, V) void f1(_Ptr pt, struct S 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 p; // expected-error {{static variable 'p' has a type that uses a type variable bound in an enclosing scope (type is '_Ptr' and type variable is 'U')}} \ + // expected-note@15 {{type variable 'U' declared here}} + + static _Array_ptr a1; // expected-error {{static variable 'a1' has a type that uses a type variable bound in an enclosing scope (type is '_Array_ptr' and type variable is 'V')}} \ + // expected-note@15 {{type variable 'V' declared here}} + + static _Array_ptr<_Array_ptr> 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>' and type variable is 'T')}} \ + // expected-note@15 {{type variable 'T' declared here}} + + static struct S s1; // expected-error {{static variable 's1' has a type that uses a type variable bound in an enclosing scope (type is 'struct S' 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' and type variable is 'U')}} \ + // expected-note@15 {{type variable 'U' declared here}} + + static _Exists(T, _Ptr) e1; // expected-error {{static variable 'e1' has a type that uses a type variable bound in an enclosing scope (type is 'Exists(T, _Ptr)' and type variable is 'U')}} \ + // expected-note@15 {{type variable 'U' declared here}} + + static _Exists(T, struct S) 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)' 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)' and type variable is 'V')}} \ + // expected-note@15 {{type variable 'V' declared here}} + + static _Exists(A, struct S) 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)' 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)' 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)' 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, double> s2; + static _Exists(T, _Ptr) e4; + static _Exists(A, struct S, _Array_ptr>) e5; + + // Non-static variable declarations can use free type variables. + _Ptr q = 0; + _Array_ptr<_Array_ptr> a3; + struct S s3; + _Exists(U, _Ptr) e6; +} diff --git a/tests/typechecking/type_check_bounds_cast.c b/tests/typechecking/type_check_bounds_cast.c index 8156457..af855c3 100644 --- a/tests/typechecking/type_check_bounds_cast.c +++ b/tests/typechecking/type_check_bounds_cast.c @@ -6,15 +6,15 @@ #include extern void f1() { - array_ptr a : count(1) = 0; + int* _Array a _Count(1) = 0; int i; ptr c = 0; int b[10]; int p[10]; array_ptr checkedc_p : bounds(checkedc_p, checkedc_p + 1) = 0; - a = _Dynamic_bounds_cast>(b, count(10)); - c = _Dynamic_bounds_cast(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 c = 0; array_ptr a : count(2) = 0; - a = _Assume_bounds_cast>(p, count(p + 2)); // expected-error {{invalid argument type 'char *' to count expression}} - c = _Assume_bounds_cast>(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 h4(void) : count(3) { extern void f6() { int i[2]; - array_ptr int_array_ptr_lb = i, int_array_ptr_ub = i + 1; - ptr 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_array_ptr_lb = (array_ptr)i, - char_array_ptr_ub = (array_ptr)i + 1; - ptr char_ptr_lb = (ptr)i, char_ptr_ub = (ptr)(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 t20 : bounds(int_array_ptr_lb, char_array_ptr_ub) = // expected-error {{pointer type mismatch}} - _Assume_bounds_cast>(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 t21 : bounds(int_ptr_lb, char_array_ptr_ub) = // expected-error {{pointer type mismatch}} - _Assume_bounds_cast>(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 q = 0; - ptr r = 0; - ptr s = 0; - ptr> t = 0; - r = _Assume_bounds_cast>(q); - p = _Assume_bounds_cast(q); - r = _Dynamic_bounds_cast>(q); - p = _Dynamic_bounds_cast(q); - s = _Assume_bounds_cast>(q); - t = _Assume_bounds_cast>>(q); - t = _Dynamic_bounds_cast>>(q); - r = _Assume_bounds_cast>(q); - p = _Assume_bounds_cast(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>(rr, count(1)); // expected-error{{expected _Array_ptr type}} q = _Dynamic_bounds_cast>(rr, bounds(rr, rr + 1)); // expected-error{{expected _Array_ptr type}} - p = _Dynamic_bounds_cast(q, count(1)); // expected-error {{expected _Array_ptr type}} - q = _Dynamic_bounds_cast>(q, count(1)); // expected-error {{expected _Array_ptr type}} - q = _Dynamic_bounds_cast>(i, count(1)); // expected-error {{expected _Array_ptr type}} - p = _Dynamic_bounds_cast(i, count(1)); // expected-error {{expected _Array_ptr type}} - q = _Dynamic_bounds_cast>(i, bounds(i, i + 1)); // expected-error 2 {{expected expression with pointer type}} - p = _Dynamic_bounds_cast(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>(p, count(1)); // expected-error {{expected _Array_ptr type}} - p = _Dynamic_bounds_cast(p, count(1)); // expected-error {{expected _Array_ptr type}} - q = _Dynamic_bounds_cast>(p, bounds(p, p + 1)); // expected-error {{expected _Array_ptr type}} - p = _Dynamic_bounds_cast(p, bounds(p, p + 1)); // expected-error {{expected _Array_ptr type}} - - q = _Assume_bounds_cast>(r, count(1)) + 3; // expected-error{{expected _Array_ptr type}} - c = _Dynamic_bounds_cast>(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}} }