119 lines · c
1// RUN: %clang_cc1 %s -ast-dump | FileCheck %s2// RUN: %clang_cc1 -fexperimental-late-parse-attributes %s -ast-dump | FileCheck %s3 4#define __counted_by(f) __attribute__((counted_by(f)))5 6struct size_unknown;7struct size_known {8 int field;9};10 11//==============================================================================12// __counted_by on struct member pointer in decl attribute position13//==============================================================================14 15// CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty definition16// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int'17// CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *'18struct on_member_pointer_complete_ty {19 int count;20 struct size_known * buf __counted_by(count);21};22 23// CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf definition24// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int'25// CHECK-NEXT: |-RecordDecl {{.+}} struct definition26// CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *'27// CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH:.+]])'28// CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by(count)':'struct size_known *'29// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])'30// CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by(count)':'struct size_known *'31struct on_pointer_anon_buf {32 int count;33 struct {34 struct size_known *buf __counted_by(count);35 };36};37 38struct on_pointer_anon_count {39 struct {40 int count;41 };42 struct size_known *buf __counted_by(count);43};44 45//==============================================================================46// __counted_by on struct member pointer in type attribute position47//==============================================================================48// TODO: Correctly parse counted_by as a type attribute. Currently it is parsed49// as a declaration attribute50 51// CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty_ty_pos definition52// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int'53// CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *'54struct on_member_pointer_complete_ty_ty_pos {55 int count;56 struct size_known *__counted_by(count) buf;57};58 59// TODO: This should be forbidden but isn't due to counted_by being treated as a60// declaration attribute. The attribute ends up on the outer most pointer61// (allowed by sema) even though syntactically its supposed to be on the inner62// pointer (would not allowed by sema due to pointee being a function type).63// CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_fn_ptr_ty_ty_pos_inner definition64// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int'65// CHECK-NEXT: `-FieldDecl {{.+}} fn_ptr 'void (** __counted_by(count))(void)':'void (**)(void)'66struct on_member_pointer_fn_ptr_ty_ty_pos_inner {67 int count;68 void (* __counted_by(count) * fn_ptr)(void);69};70 71// FIXME: The generated AST here is wrong. The attribute should be on the inner72// pointer.73// CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_inner definition74// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int'75// CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __counted_by(count)':'struct size_known **'76struct on_nested_pointer_inner {77 int count;78 // TODO: This should be disallowed because in the `-fbounds-safety` model79 // `__counted_by` can only be nested when used in function parameters.80 struct size_known *__counted_by(count) *buf;81};82 83// CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_outer definition84// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int'85// CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __counted_by(count)':'struct size_known **'86struct on_nested_pointer_outer {87 int count;88 struct size_known **__counted_by(count) buf;89};90 91// CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf_ty_pos definition92// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int'93// CHECK-NEXT: |-RecordDecl {{.+}} struct definition94// CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *'95// CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2:.+]])'96// CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by(count)':'struct size_known *'97// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])'98// CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by(count)':'struct size_known *'99struct on_pointer_anon_buf_ty_pos {100 int count;101 struct {102 struct size_known * __counted_by(count) buf;103 };104};105 106// CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_count_ty_pos definition107// CHECK-NEXT: |-RecordDecl {{.+}} struct definition108// CHECK-NEXT: | `-FieldDecl {{.+}} count 'int'109// CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3:.+]])'110// CHECK-NEXT: |-IndirectFieldDecl {{.+}} implicit referenced count 'int'111// CHECK-NEXT: | |-Field {{.+}} field_index 0 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])'112// CHECK-NEXT: | `-Field {{.+}} 'count' 'int'113struct on_pointer_anon_count_ty_pos {114 struct {115 int count;116 };117 struct size_known *__counted_by(count) buf;118};119