brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 0fd739c Raw
225 lines · c
1// RUN: %clang_cc1 -fsyntax-only -Wpointer-arith -verify %s2// RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -Wpointer-arith -verify %s3 4#define __counted_by_or_null(f)  __attribute__((counted_by_or_null(f)))5#define __counted_by(f)  __attribute__((counted_by(f)))6 7struct size_unknown;8struct size_known {9  int field;10};11 12typedef void(*fn_ptr_ty)(void);13 14//==============================================================================15// __counted_by_or_null on struct member pointer in decl attribute position16//==============================================================================17 18struct on_member_pointer_complete_ty {19  int count;20  struct size_known * buf __counted_by_or_null(count);21};22 23struct on_member_pointer_incomplete_ty {24  int count;25  struct size_unknown * buf __counted_by_or_null(count); // ok26};27 28struct on_member_pointer_const_incomplete_ty {29  int count;30  const struct size_unknown * buf __counted_by_or_null(count); // ok31};32 33struct on_member_pointer_void_ty {34  int count;35  // expected-warning@+2{{'counted_by_or_null' on a pointer to void is a GNU extension, treated as 'sized_by_or_null'}}36  // expected-note@+1{{use '__sized_by_or_null' to suppress this warning}}37  void* buf __counted_by_or_null(count);38};39 40struct on_member_pointer_fn_ptr_ty {41  int count;42  // buffer of `count` function pointers is allowed43  void (**fn_ptr)(void) __counted_by_or_null(count);44};45 46struct on_member_pointer_fn_ptr_ty_ptr_ty {47  int count;48  // buffer of `count` function pointers is allowed49  fn_ptr_ty* fn_ptr __counted_by_or_null(count);50};51 52struct on_member_pointer_fn_ty {53  int count;54  // buffer of `count` functions is not allowed55  // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}}56  void (*fn_ptr)(void) __counted_by_or_null(count);57};58 59struct on_member_pointer_fn_ptr_ty_ty {60  int count;61  // buffer of `count` functions is not allowed62  // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}}63  fn_ptr_ty fn_ptr __counted_by_or_null(count);64};65 66struct has_unannotated_vla {67  int count;68  int buffer[];69};70 71struct on_member_pointer_struct_with_vla {72  int count;73  // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct has_unannotated_vla' is a struct type with a flexible array member}}74  struct has_unannotated_vla* objects __counted_by_or_null(count);75};76 77struct has_annotated_vla {78  int count;79  int buffer[] __counted_by(count);80};81 82// Currently prevented because computing the size of `objects` at runtime would83// require an O(N) walk of `objects` to take into account the length of the VLA84// in each struct instance.85struct on_member_pointer_struct_with_annotated_vla {86  int count;87  // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct has_annotated_vla' is a struct type with a flexible array member}}88  struct has_annotated_vla* objects __counted_by_or_null(count);89};90 91struct on_pointer_anon_buf {92  int count;93  struct {94    struct size_known *buf __counted_by_or_null(count);95  };96};97 98struct on_pointer_anon_count {99  struct {100    int count;101  };102  struct size_known *buf __counted_by_or_null(count);103};104 105//==============================================================================106// __counted_by_or_null on struct member pointer in type attribute position107//==============================================================================108// TODO: Correctly parse counted_by_or_null as a type attribute. Currently it is parsed109// as a declaration attribute110 111struct on_member_pointer_complete_ty_ty_pos {112  int count;113  struct size_known *__counted_by_or_null(count) buf;114};115 116struct on_member_pointer_incomplete_ty_ty_pos {117  int count;118  struct size_unknown * __counted_by_or_null(count) buf; // ok119};120 121struct on_member_pointer_const_incomplete_ty_ty_pos {122  int count;123  const struct size_unknown * __counted_by_or_null(count) buf; // ok124};125 126struct on_member_pointer_void_ty_ty_pos {127  int count;128  // expected-warning@+2{{'counted_by_or_null' on a pointer to void is a GNU extension, treated as 'sized_by_or_null'}}129  // expected-note@+1{{use '__sized_by_or_null' to suppress this warning}}130  void *__counted_by_or_null(count) buf;131};132 133// -134 135struct on_member_pointer_fn_ptr_ty_pos {136  int count;137  // buffer of `count` function pointers is allowed138  void (** __counted_by_or_null(count) fn_ptr)(void);139};140 141struct on_member_pointer_fn_ptr_ty_ptr_ty_pos {142  int count;143  // buffer of `count` function pointers is allowed144  fn_ptr_ty* __counted_by_or_null(count) fn_ptr;145};146 147struct on_member_pointer_fn_ty_ty_pos {148  int count;149  // buffer of `count` functions is not allowed150  // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}}151  void (* __counted_by_or_null(count) fn_ptr)(void);152};153 154struct on_member_pointer_fn_ptr_ty_ty_pos {155  int count;156  // buffer of `count` functions is not allowed157  // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}}158  fn_ptr_ty __counted_by_or_null(count) fn_ptr;159};160 161// TODO: This should be forbidden but isn't due to counted_by_or_null being treated162// as a declaration attribute.163struct on_member_pointer_fn_ptr_ty_ty_pos_inner {164  int count;165  void (* __counted_by_or_null(count) * fn_ptr)(void);166};167 168struct on_member_pointer_struct_with_vla_ty_pos {169  int count;170  // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct has_unannotated_vla' is a struct type with a flexible array member}}171  struct has_unannotated_vla *__counted_by_or_null(count) objects;172};173 174// Currently prevented because computing the size of `objects` at runtime would175// require an O(N) walk of `objects` to take into account the length of the VLA176// in each struct instance.177struct on_member_pointer_struct_with_annotated_vla_ty_pos {178  int count;179  // expected-error@+1{{counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct has_annotated_vla' is a struct type with a flexible array member}}180  struct has_annotated_vla* __counted_by_or_null(count) objects;181};182 183struct on_nested_pointer_inner {184  // TODO: This should be disallowed because in the `-fbounds-safety` model185  // `__counted_by_or_null` can only be nested when used in function parameters.186  int count;187  struct size_known *__counted_by_or_null(count) *buf;188};189 190struct on_nested_pointer_outer {191  int count;192  struct size_known **__counted_by_or_null(count) buf;193};194 195struct on_pointer_anon_buf_ty_pos {196  int count;197  struct {198    struct size_known * __counted_by_or_null(count) buf;199  };200};201 202struct on_pointer_anon_count_ty_pos {203  struct {204    int count;205  };206  struct size_known *__counted_by_or_null(count) buf;207};208 209//==============================================================================210// __counted_by_or_null on struct non-pointer members211//==============================================================================212 213struct on_pod_ty {214  int count;215  // expected-error-re@+1{{'counted_by_or_null' only applies to pointers{{$}}}}216  int wrong_ty __counted_by_or_null(count);217};218 219struct on_void_ty {220  int count;221  // expected-error-re@+2{{'counted_by_or_null' only applies to pointers{{$}}}}222  // expected-error@+1{{field has incomplete type 'void'}}223  void wrong_ty __counted_by_or_null(count);224};225