| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // RUN: %clang_cc1 -fexperimental-late-parse-attributes %s -ast-dump | FileCheck %s | ||
|
|
||
| #define __counted_by_or_null(f) __attribute__((counted_by_or_null(f))) | ||
|
|
||
| struct size_known { | ||
| int field; | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| // __counted_by_or_null on struct member pointer in decl attribute position | ||
| //============================================================================== | ||
|
|
||
| struct on_member_pointer_complete_ty { | ||
| struct size_known *buf __counted_by_or_null(count); | ||
| int count; | ||
| }; | ||
| // CHECK-LABEL: struct on_member_pointer_complete_ty definition | ||
| // CHECK-NEXT: |-FieldDecl {{.*}} buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: `-FieldDecl {{.*}} referenced count 'int' | ||
|
|
||
| struct on_pointer_anon_count { | ||
| struct size_known *buf __counted_by_or_null(count); | ||
| struct { | ||
| int count; | ||
| }; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: struct on_pointer_anon_count definition | ||
| // CHECK-NEXT: |-FieldDecl {{.*}} buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-RecordDecl {{.*}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.*}} count 'int' | ||
| // CHECK-NEXT: |-FieldDecl {{.*}} implicit 'struct on_pointer_anon_count::(anonymous at {{.*}})' | ||
| // CHECK-NEXT: `-IndirectFieldDecl {{.*}} implicit referenced count 'int' | ||
| // CHECK-NEXT: |-Field {{.*}} '' 'struct on_pointer_anon_count::(anonymous at {{.*}})' | ||
| // CHECK-NEXT: `-Field {{.*}} 'count' 'int' | ||
|
|
||
| //============================================================================== | ||
| // __counted_by_or_null on struct member pointer in type attribute position | ||
| //============================================================================== | ||
| // TODO: Correctly parse counted_by_or_null as a type attribute. Currently it is parsed | ||
| // as a declaration attribute and is **not** late parsed resulting in the `count` | ||
| // field being unavailable. | ||
| // | ||
| // See `clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c` for test | ||
| // cases. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| // RUN: %clang_cc1 %s -ast-dump | FileCheck %s | ||
|
|
||
| #define __counted_by_or_null(f) __attribute__((counted_by_or_null(f))) | ||
|
|
||
| struct size_unknown; | ||
| struct size_known { | ||
| int field; | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| // __counted_by_or_null on struct member pointer in decl attribute position | ||
| //============================================================================== | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| struct on_member_pointer_complete_ty { | ||
| int count; | ||
| struct size_known * buf __counted_by_or_null(count); | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: |-RecordDecl {{.+}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH:.+]])' | ||
| // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' | ||
| // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| struct on_pointer_anon_buf { | ||
| int count; | ||
| struct { | ||
| struct size_known *buf __counted_by_or_null(count); | ||
| }; | ||
| }; | ||
|
|
||
| struct on_pointer_anon_count { | ||
| struct { | ||
| int count; | ||
| }; | ||
| struct size_known *buf __counted_by_or_null(count); | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| // __counted_by_or_null on struct member pointer in type attribute position | ||
| //============================================================================== | ||
| // TODO: Correctly parse counted_by_or_null as a type attribute. Currently it is parsed | ||
| // as a declaration attribute | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty_ty_pos definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| struct on_member_pointer_complete_ty_ty_pos { | ||
| int count; | ||
| struct size_known *__counted_by_or_null(count) buf; | ||
| }; | ||
|
|
||
| // TODO: This should be forbidden but isn't due to counted_by_or_null being treated as a | ||
| // declaration attribute. The attribute ends up on the outer most pointer | ||
| // (allowed by sema) even though syntactically its supposed to be on the inner | ||
| // pointer (would not allowed by sema due to pointee being a function type). | ||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_fn_ptr_ty_ty_pos_inner definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} fn_ptr 'void (** __counted_by_or_null(count))(void)':'void (**)(void)' | ||
| struct on_member_pointer_fn_ptr_ty_ty_pos_inner { | ||
| int count; | ||
| void (* __counted_by_or_null(count) * fn_ptr)(void); | ||
| }; | ||
|
|
||
| // FIXME: The generated AST here is wrong. The attribute should be on the inner | ||
| // pointer. | ||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_inner definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __counted_by_or_null(count)':'struct size_known **' | ||
| struct on_nested_pointer_inner { | ||
| int count; | ||
| // TODO: This should be disallowed because in the `-fbounds-safety` model | ||
| // `__counted_by_or_null` can only be nested when used in function parameters. | ||
| struct size_known *__counted_by_or_null(count) *buf; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_outer definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __counted_by_or_null(count)':'struct size_known **' | ||
| struct on_nested_pointer_outer { | ||
| int count; | ||
| struct size_known **__counted_by_or_null(count) buf; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf_ty_pos definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: |-RecordDecl {{.+}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2:.+]])' | ||
| // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' | ||
| // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by_or_null(count)':'struct size_known *' | ||
| struct on_pointer_anon_buf_ty_pos { | ||
| int count; | ||
| struct { | ||
| struct size_known * __counted_by_or_null(count) buf; | ||
| }; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_count_ty_pos definition | ||
| // CHECK-NEXT: |-RecordDecl {{.+}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.+}} count 'int' | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3:.+]])' | ||
| // CHECK-NEXT: |-IndirectFieldDecl {{.+}} implicit referenced count 'int' | ||
| // CHECK-NEXT: | |-Field {{.+}} '' 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' | ||
| // CHECK-NEXT: | `-Field {{.+}} 'count' 'int' | ||
| struct on_pointer_anon_count_ty_pos { | ||
| struct { | ||
| int count; | ||
| }; | ||
| struct size_known *__counted_by_or_null(count) buf; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // RUN: %clang_cc1 -fexperimental-late-parse-attributes %s -ast-dump | FileCheck %s | ||
|
|
||
| #define __sized_by(f) __attribute__((sized_by(f))) | ||
|
|
||
| struct size_known { | ||
| int field; | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| // __sized_by on struct member pointer in decl attribute position | ||
| //============================================================================== | ||
|
|
||
| struct on_member_pointer_complete_ty { | ||
| struct size_known *buf __sized_by(count); | ||
| int count; | ||
| }; | ||
| // CHECK-LABEL: struct on_member_pointer_complete_ty definition | ||
| // CHECK-NEXT: |-FieldDecl {{.*}} buf 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| // CHECK-NEXT: `-FieldDecl {{.*}} referenced count 'int' | ||
|
|
||
| struct on_pointer_anon_count { | ||
| struct size_known *buf __sized_by(count); | ||
| struct { | ||
| int count; | ||
| }; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: struct on_pointer_anon_count definition | ||
| // CHECK-NEXT: |-FieldDecl {{.*}} buf 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-RecordDecl {{.*}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.*}} count 'int' | ||
| // CHECK-NEXT: |-FieldDecl {{.*}} implicit 'struct on_pointer_anon_count::(anonymous at {{.*}})' | ||
| // CHECK-NEXT: `-IndirectFieldDecl {{.*}} implicit referenced count 'int' | ||
| // CHECK-NEXT: |-Field {{.*}} '' 'struct on_pointer_anon_count::(anonymous at {{.*}})' | ||
| // CHECK-NEXT: `-Field {{.*}} 'count' 'int' | ||
|
|
||
| //============================================================================== | ||
| // __sized_by on struct member pointer in type attribute position | ||
| //============================================================================== | ||
| // TODO: Correctly parse sized_by as a type attribute. Currently it is parsed | ||
| // as a declaration attribute and is **not** late parsed resulting in the `count` | ||
| // field being unavailable. | ||
| // | ||
| // See `clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c` for test | ||
| // cases. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // RUN: %clang_cc1 -fexperimental-late-parse-attributes %s -ast-dump | FileCheck %s | ||
|
|
||
| #define __sized_by_or_null(f) __attribute__((sized_by_or_null(f))) | ||
|
|
||
| struct size_known { | ||
| int field; | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| // __sized_by_or_null on struct member pointer in decl attribute position | ||
| //============================================================================== | ||
|
|
||
| struct on_member_pointer_complete_ty { | ||
| struct size_known *buf __sized_by_or_null(count); | ||
| int count; | ||
| }; | ||
| // CHECK-LABEL: struct on_member_pointer_complete_ty definition | ||
| // CHECK-NEXT: |-FieldDecl {{.*}} buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: `-FieldDecl {{.*}} referenced count 'int' | ||
|
|
||
| struct on_pointer_anon_count { | ||
| struct size_known *buf __sized_by_or_null(count); | ||
| struct { | ||
| int count; | ||
| }; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: struct on_pointer_anon_count definition | ||
| // CHECK-NEXT: |-FieldDecl {{.*}} buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-RecordDecl {{.*}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.*}} count 'int' | ||
| // CHECK-NEXT: |-FieldDecl {{.*}} implicit 'struct on_pointer_anon_count::(anonymous at {{.*}})' | ||
| // CHECK-NEXT: `-IndirectFieldDecl {{.*}} implicit referenced count 'int' | ||
| // CHECK-NEXT: |-Field {{.*}} '' 'struct on_pointer_anon_count::(anonymous at {{.*}})' | ||
| // CHECK-NEXT: `-Field {{.*}} 'count' 'int' | ||
|
|
||
| //============================================================================== | ||
| // __sized_by_or_null on struct member pointer in type attribute position | ||
| //============================================================================== | ||
| // TODO: Correctly parse sized_by_or_null as a type attribute. Currently it is parsed | ||
| // as a declaration attribute and is **not** late parsed resulting in the `count` | ||
| // field being unavailable. | ||
| // | ||
| // See `clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c` for test | ||
| // cases. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| // RUN: %clang_cc1 %s -ast-dump | FileCheck %s | ||
|
|
||
| #define __sized_by_or_null(f) __attribute__((sized_by_or_null(f))) | ||
|
|
||
| struct size_unknown; | ||
| struct size_known { | ||
| int field; | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| // __sized_by_or_null on struct member pointer in decl attribute position | ||
| //============================================================================== | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| struct on_member_pointer_complete_ty { | ||
| int count; | ||
| struct size_known * buf __sized_by_or_null(count); | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: |-RecordDecl {{.+}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH:.+]])' | ||
| // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' | ||
| // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| struct on_pointer_anon_buf { | ||
| int count; | ||
| struct { | ||
| struct size_known *buf __sized_by_or_null(count); | ||
| }; | ||
| }; | ||
|
|
||
| struct on_pointer_anon_count { | ||
| struct { | ||
| int count; | ||
| }; | ||
| struct size_known *buf __sized_by_or_null(count); | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| // __sized_by_or_null on struct member pointer in type attribute position | ||
| //============================================================================== | ||
| // TODO: Correctly parse sized_by_or_null as a type attribute. Currently it is parsed | ||
| // as a declaration attribute | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty_ty_pos definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| struct on_member_pointer_complete_ty_ty_pos { | ||
| int count; | ||
| struct size_known *__sized_by_or_null(count) buf; | ||
| }; | ||
|
|
||
| // TODO: This should be forbidden but isn't due to sized_by_or_null being treated as a | ||
| // declaration attribute. The attribute ends up on the outer most pointer | ||
| // (allowed by sema) even though syntactically its supposed to be on the inner | ||
| // pointer (would not allowed by sema due to pointee being a function type). | ||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_fn_ptr_ty_ty_pos_inner definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} fn_ptr 'void (** __sized_by_or_null(count))(void)':'void (**)(void)' | ||
| struct on_member_pointer_fn_ptr_ty_ty_pos_inner { | ||
| int count; | ||
| void (* __sized_by_or_null(count) * fn_ptr)(void); | ||
| }; | ||
|
|
||
| // FIXME: The generated AST here is wrong. The attribute should be on the inner | ||
| // pointer. | ||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_inner definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __sized_by_or_null(count)':'struct size_known **' | ||
| struct on_nested_pointer_inner { | ||
| int count; | ||
| // TODO: This should be disallowed because in the `-fbounds-safety` model | ||
| // `__sized_by_or_null` can only be nested when used in function parameters. | ||
| struct size_known *__sized_by_or_null(count) *buf; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_outer definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __sized_by_or_null(count)':'struct size_known **' | ||
| struct on_nested_pointer_outer { | ||
| int count; | ||
| struct size_known **__sized_by_or_null(count) buf; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf_ty_pos definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: |-RecordDecl {{.+}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2:.+]])' | ||
| // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' | ||
| // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __sized_by_or_null(count)':'struct size_known *' | ||
| struct on_pointer_anon_buf_ty_pos { | ||
| int count; | ||
| struct { | ||
| struct size_known * __sized_by_or_null(count) buf; | ||
| }; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_count_ty_pos definition | ||
| // CHECK-NEXT: |-RecordDecl {{.+}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.+}} count 'int' | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3:.+]])' | ||
| // CHECK-NEXT: |-IndirectFieldDecl {{.+}} implicit referenced count 'int' | ||
| // CHECK-NEXT: | |-Field {{.+}} '' 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' | ||
| // CHECK-NEXT: | `-Field {{.+}} 'count' 'int' | ||
| struct on_pointer_anon_count_ty_pos { | ||
| struct { | ||
| int count; | ||
| }; | ||
| struct size_known *__sized_by_or_null(count) buf; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| // RUN: %clang_cc1 %s -ast-dump | FileCheck %s | ||
|
|
||
| #define __sized_by(f) __attribute__((sized_by(f))) | ||
|
|
||
| struct size_unknown; | ||
| struct size_known { | ||
| int field; | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| // __sized_by on struct member pointer in decl attribute position | ||
| //============================================================================== | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| struct on_member_pointer_complete_ty { | ||
| int count; | ||
| struct size_known * buf __sized_by(count); | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: |-RecordDecl {{.+}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH:.+]])' | ||
| // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' | ||
| // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| struct on_pointer_anon_buf { | ||
| int count; | ||
| struct { | ||
| struct size_known *buf __sized_by(count); | ||
| }; | ||
| }; | ||
|
|
||
| struct on_pointer_anon_count { | ||
| struct { | ||
| int count; | ||
| }; | ||
| struct size_known *buf __sized_by(count); | ||
| }; | ||
|
|
||
| //============================================================================== | ||
| // __sized_by on struct member pointer in type attribute position | ||
| //============================================================================== | ||
| // TODO: Correctly parse sized_by as a type attribute. Currently it is parsed | ||
| // as a declaration attribute | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty_ty_pos definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| struct on_member_pointer_complete_ty_ty_pos { | ||
| int count; | ||
| struct size_known *__sized_by(count) buf; | ||
| }; | ||
|
|
||
| // TODO: This should be forbidden but isn't due to sized_by being treated as a | ||
| // declaration attribute. The attribute ends up on the outer most pointer | ||
| // (allowed by sema) even though syntactically its supposed to be on the inner | ||
| // pointer (would not allowed by sema due to pointee being a function type). | ||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_fn_ptr_ty_ty_pos_inner definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} fn_ptr 'void (** __sized_by(count))(void)':'void (**)(void)' | ||
| struct on_member_pointer_fn_ptr_ty_ty_pos_inner { | ||
| int count; | ||
| void (* __sized_by(count) * fn_ptr)(void); | ||
| }; | ||
|
|
||
| // FIXME: The generated AST here is wrong. The attribute should be on the inner | ||
| // pointer. | ||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_inner definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __sized_by(count)':'struct size_known **' | ||
| struct on_nested_pointer_inner { | ||
| int count; | ||
| // TODO: This should be disallowed because in the `-fbounds-safety` model | ||
| // `__sized_by` can only be nested when used in function parameters. | ||
| struct size_known *__sized_by(count) *buf; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_outer definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __sized_by(count)':'struct size_known **' | ||
| struct on_nested_pointer_outer { | ||
| int count; | ||
| struct size_known **__sized_by(count) buf; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf_ty_pos definition | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' | ||
| // CHECK-NEXT: |-RecordDecl {{.+}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2:.+]])' | ||
| // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| // CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' | ||
| // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __sized_by(count)':'struct size_known *' | ||
| struct on_pointer_anon_buf_ty_pos { | ||
| int count; | ||
| struct { | ||
| struct size_known * __sized_by(count) buf; | ||
| }; | ||
| }; | ||
|
|
||
| // CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_count_ty_pos definition | ||
| // CHECK-NEXT: |-RecordDecl {{.+}} struct definition | ||
| // CHECK-NEXT: | `-FieldDecl {{.+}} count 'int' | ||
| // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3:.+]])' | ||
| // CHECK-NEXT: |-IndirectFieldDecl {{.+}} implicit referenced count 'int' | ||
| // CHECK-NEXT: | |-Field {{.+}} '' 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' | ||
| // CHECK-NEXT: | `-Field {{.+}} 'count' 'int' | ||
| struct on_pointer_anon_count_ty_pos { | ||
| struct { | ||
| int count; | ||
| }; | ||
| struct size_known *__sized_by(count) buf; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| // RUN: %clang_cc1 -verify -Wno-unused %s | ||
|
|
||
| struct A { | ||
| int y; | ||
| }; | ||
|
|
||
| struct B; // expected-note 4{{forward declaration of 'B'}} | ||
|
|
||
| void f(A *a, B *b) { | ||
| a->B::x; // expected-error {{incomplete type 'B' named in nested name specifier}} | ||
| a->A::x; // expected-error {{no member named 'x' in 'A'}} | ||
| a->A::y; | ||
| b->B::x; // expected-error {{member access into incomplete type 'B'}} | ||
| b->A::x; // expected-error {{member access into incomplete type 'B'}} | ||
| b->A::y; // expected-error {{member access into incomplete type 'B'}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // REQUIRES: aarch64-registered-target | ||
| // RUN: %clang_cc1 -triple arm64-apple-ios -S -o - %s | FileCheck %s | ||
|
|
||
| // CHECK: _restartable_function: | ||
| // CHECK-NEXT: ldr x11, [x0] | ||
| // CHECK-NEXT: add x11, x11, #1 | ||
| // CHECK-NEXT: str x11, [x0] | ||
| // CHECK-NEXT: Ltmp0: | ||
| // CHECK-NEXT: b Ltmp0 | ||
| // CHECK-NEXT: LExit_restartable_function: | ||
| // CHECK-NEXT: ret | ||
| asm(".align 4\n" | ||
| " .text\n" | ||
| " .private_extern _restartable_function\n" | ||
| "_restartable_function:\n" | ||
| " ldr x11, [x0]\n" | ||
| " add x11, x11, #1\n" | ||
| " str x11, [x0]\n" | ||
| "1:\n" | ||
| " b 1b\n" | ||
| "LExit_restartable_function:\n" | ||
| " ret\n" | ||
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| // REQUIRES: nvptx-registered-target | ||
| // | ||
| // RUN: %clang_cc1 -ffp-contract=off -triple nvptx-unknown-unknown -target-cpu \ | ||
| // RUN: sm_86 -target-feature +ptx72 -fcuda-is-device -x cuda -emit-llvm -o - %s \ | ||
| // RUN: | FileCheck %s | ||
|
|
||
| #define __device__ __attribute__((device)) | ||
| typedef __fp16 __fp16v2 __attribute__((ext_vector_type(2))); | ||
|
|
||
| // CHECK: call half @llvm.nvvm.ex2.approx.f16(half {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.ex2.approx.f16x2(<2 x half> {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fma.rn.relu.f16(half {{.*}}, half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fma.rn.ftz.relu.f16(half {{.*}}, half {{.*}}, half {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fma.rn.relu.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fma.rn.ftz.relu.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fma.rn.ftz.f16(half {{.*}}, half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fma.rn.sat.f16(half {{.*}}, half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fma.rn.ftz.sat.f16(half {{.*}}, half {{.*}}, half {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fma.rn.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fma.rn.ftz.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fma.rn.sat.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fma.rn.ftz.sat.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmin.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmin.ftz.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmin.nan.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmin.ftz.nan.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmin.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmin.ftz.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmin.nan.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmin.ftz.nan.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmin.xorsign.abs.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmin.ftz.xorsign.abs.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmin.nan.xorsign.abs.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmin.ftz.nan.xorsign.abs.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmin.xorsign.abs.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmin.ftz.xorsign.abs.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmin.nan.xorsign.abs.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmin.ftz.nan.xorsign.abs.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmax.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmax.ftz.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmax.nan.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmax.ftz.nan.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmax.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmax.ftz.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmax.nan.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmax.ftz.nan.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmax.xorsign.abs.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmax.ftz.xorsign.abs.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmax.nan.xorsign.abs.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.fmax.ftz.nan.xorsign.abs.f16(half {{.*}}, half {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmax.xorsign.abs.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmax.ftz.xorsign.abs.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmax.nan.xorsign.abs.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call <2 x half> @llvm.nvvm.fmax.ftz.nan.xorsign.abs.f16x2(<2 x half> {{.*}}, <2 x half> {{.*}}) | ||
| // CHECK: call half @llvm.nvvm.ldg.global.f.f16.p0(ptr {{.*}}, i32 2) | ||
| // CHECK: call <2 x half> @llvm.nvvm.ldg.global.f.v2f16.p0(ptr {{.*}}, i32 4) | ||
| // CHECK: call half @llvm.nvvm.ldu.global.f.f16.p0(ptr {{.*}}, i32 2) | ||
| // CHECK: call <2 x half> @llvm.nvvm.ldu.global.f.v2f16.p0(ptr {{.*}}, i32 4) | ||
| __device__ void nvvm_native_half_types(void *a, void*b, void*c, __fp16* out) { | ||
| __fp16v2 resv2 = {0, 0}; | ||
| *out += __nvvm_ex2_approx_f16(*(__fp16 *)a); | ||
| resv2 = __nvvm_ex2_approx_f16x2(*(__fp16v2*)a); | ||
|
|
||
| *out += __nvvm_fma_rn_relu_f16(*(__fp16*)a, *(__fp16*)b, *(__fp16*)c); | ||
| *out += __nvvm_fma_rn_ftz_relu_f16(*(__fp16*)a, *(__fp16*)b, *(__fp16 *)c); | ||
| resv2 += __nvvm_fma_rn_relu_f16x2(*(__fp16v2*)a, *(__fp16v2*)b, *(__fp16v2*)c); | ||
| resv2 += __nvvm_fma_rn_ftz_relu_f16x2(*(__fp16v2*)a, *(__fp16v2*)b, *(__fp16v2*)c); | ||
| *out += __nvvm_fma_rn_ftz_f16(*(__fp16*)a, *(__fp16*)b, *(__fp16*)c); | ||
| *out += __nvvm_fma_rn_sat_f16(*(__fp16*)a, *(__fp16*)b, *(__fp16*)c); | ||
| *out += __nvvm_fma_rn_ftz_sat_f16(*(__fp16*)a, *(__fp16*)b, *(__fp16*)c); | ||
| resv2 += __nvvm_fma_rn_f16x2(*(__fp16v2*)a, *(__fp16v2*)b, *(__fp16v2*)c); | ||
| resv2 += __nvvm_fma_rn_ftz_f16x2(*(__fp16v2*)a, *(__fp16v2*)b, *(__fp16v2*)c); | ||
| resv2 += __nvvm_fma_rn_sat_f16x2(*(__fp16v2*)a, *(__fp16v2*)b, *(__fp16v2*)c); | ||
| resv2 += __nvvm_fma_rn_ftz_sat_f16x2(*(__fp16v2*)a, *(__fp16v2*)b, *(__fp16v2*)c); | ||
|
|
||
| *out += __nvvm_fmin_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmin_ftz_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmin_nan_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmin_ftz_nan_f16(*(__fp16*)a, *(__fp16*)b); | ||
| resv2 += __nvvm_fmin_f16x2(*(__fp16v2*)a , *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmin_ftz_f16x2(*(__fp16v2*)a , *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmin_nan_f16x2(*(__fp16v2*)a , *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmin_ftz_nan_f16x2(*(__fp16v2*)a , *(__fp16v2*)b); | ||
| *out += __nvvm_fmin_xorsign_abs_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmin_ftz_xorsign_abs_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmin_nan_xorsign_abs_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmin_ftz_nan_xorsign_abs_f16(*(__fp16*)a, *(__fp16*)b); | ||
| resv2 += __nvvm_fmin_xorsign_abs_f16x2(*(__fp16v2*)a, *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmin_ftz_xorsign_abs_f16x2(*(__fp16v2*)a, *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmin_nan_xorsign_abs_f16x2(*(__fp16v2*)a, *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmin_ftz_nan_xorsign_abs_f16x2(*(__fp16v2*)a, *(__fp16v2*)b); | ||
|
|
||
| *out += __nvvm_fmax_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmax_ftz_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmax_nan_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmax_ftz_nan_f16(*(__fp16*)a, *(__fp16*)b); | ||
| resv2 += __nvvm_fmax_f16x2(*(__fp16v2*)a , *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmax_ftz_f16x2(*(__fp16v2*)a , *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmax_nan_f16x2(*(__fp16v2*)a , *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmax_ftz_nan_f16x2(*(__fp16v2*)a , *(__fp16v2*)b); | ||
| *out += __nvvm_fmax_xorsign_abs_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmax_ftz_xorsign_abs_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmax_nan_xorsign_abs_f16(*(__fp16*)a, *(__fp16*)b); | ||
| *out += __nvvm_fmax_ftz_nan_xorsign_abs_f16(*(__fp16*)a, *(__fp16*)b); | ||
| resv2 += __nvvm_fmax_xorsign_abs_f16x2(*(__fp16v2*)a, *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmax_ftz_xorsign_abs_f16x2(*(__fp16v2*)a, *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmax_nan_xorsign_abs_f16x2(*(__fp16v2*)a, *(__fp16v2*)b); | ||
| resv2 += __nvvm_fmax_ftz_nan_xorsign_abs_f16x2(*(__fp16v2*)a, *(__fp16v2*)b); | ||
|
|
||
| *out += __nvvm_ldg_h((__fp16 *)a); | ||
| resv2 += __nvvm_ldg_h2((__fp16v2 *)a); | ||
|
|
||
| *out += __nvvm_ldu_h((__fp16 *)a); | ||
| resv2 += __nvvm_ldu_h2((__fp16v2 *)a); | ||
|
|
||
| *out += resv2[0] + resv2[1]; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| // RUN: not %clang_cc1 -triple amdgcn -target-feature +wavefrontsize32 -target-feature +wavefrontsize64 -o /dev/null %s 2>&1 | FileCheck %s | ||
| // RUN: not %clang_cc1 -triple amdgcn -target-cpu gfx1103 -target-feature +wavefrontsize32 -target-feature +wavefrontsize64 -o /dev/null %s 2>&1 | FileCheck %s | ||
| // RUN: not %clang_cc1 -triple amdgcn -target-cpu gfx900 -target-feature +wavefrontsize32 -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=GFX9 | ||
|
|
||
| // CHECK: error: invalid feature combination: 'wavefrontsize32' and 'wavefrontsize64' are mutually exclusive | ||
| // GFX9: error: option 'wavefrontsize32' cannot be specified on this target | ||
|
|
||
| kernel void test() {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // RUN: %clang -fraw-string-literals -fsyntax-only -std=c++03 %s 2>&1 | FileCheck --check-prefix=CHECK-PRE-CXX11 --allow-empty %s | ||
| // RUN: %clang -fraw-string-literals -fsyntax-only -std=gnu++03 %s 2>&1 | FileCheck --check-prefix=CHECK-PRE-CXX11 --allow-empty %s | ||
| // RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++03 %s 2>&1 | FileCheck --check-prefix=CHECK-PRE-CXX11 --allow-empty %s | ||
| // RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++03 %s 2>&1 | FileCheck --check-prefix=CHECK-PRE-CXX11 --allow-empty %s | ||
| // RUN: %clang -fraw-string-literals -fsyntax-only -std=c++11 %s 2>&1 | FileCheck --check-prefix=CHECK-POS %s | ||
| // RUN: %clang -fraw-string-literals -fsyntax-only -std=gnu++11 %s 2>&1 | FileCheck --check-prefix=CHECK-POS %s | ||
| // RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++11 %s 2>&1 | FileCheck --check-prefix=CHECK-NEG %s | ||
| // RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++11 %s 2>&1 | FileCheck --check-prefix=CHECK-NEG %s | ||
| // RUN: %clang -fraw-string-literals -fsyntax-only -std=c++20 %s 2>&1 | FileCheck --check-prefix=CHECK-POS %s | ||
| // RUN: %clang -fraw-string-literals -fsyntax-only -std=gnu++20 %s 2>&1 | FileCheck --check-prefix=CHECK-POS %s | ||
| // RUN: %clang -fno-raw-string-literals -fsyntax-only -std=c++20 %s 2>&1 | FileCheck --check-prefix=CHECK-NEG %s | ||
| // RUN: %clang -fno-raw-string-literals -fsyntax-only -std=gnu++20 %s 2>&1 | FileCheck --check-prefix=CHECK-NEG %s | ||
|
|
||
| // CHECK-PRE-CXX11-NOT: ignoring '-fraw-string-literals' | ||
| // CHECK-PRE-CXX11-NOT: ignoring '-fno-raw-string-literals' | ||
| // CHECK-POS: ignoring '-fraw-string-literals', which is only valid for C and C++ standards before C++11 | ||
| // CHECK-NEG: ignoring '-fno-raw-string-literals', which is only valid for C and C++ standards before C++11 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| // REQUIRES: arm-registered-target | ||
|
|
||
| // RUN: %clang_cc1 -triple=thumbv7m-unknown-unknown-eabi -msign-return-address=non-leaf %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SIGN | ||
| // RUN: %clang_cc1 -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=BTE | ||
| // RUN: %clang_cc1 -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -msign-return-address=all %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALL | ||
|
|
||
| // RUN: %clang_cc1 -flto -triple=thumbv7m-unknown-unknown-eabi -msign-return-address=non-leaf %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SIGN | ||
| // RUN: %clang_cc1 -flto -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=BTE | ||
| // RUN: %clang_cc1 -flto -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -msign-return-address=all %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALL | ||
|
|
||
| // RUN: %clang_cc1 -flto=thin -triple=thumbv7m-unknown-unknown-eabi -msign-return-address=non-leaf %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SIGN | ||
| // RUN: %clang_cc1 -flto=thin -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=BTE | ||
| // RUN: %clang_cc1 -flto=thin -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -msign-return-address=all %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALL | ||
|
|
||
| void foo() {} | ||
|
|
||
| // Check there are branch protection function attributes. | ||
| // CHECK-LABEL: @foo() #[[#ATTR:]] | ||
|
|
||
| // SIGN-NOT: attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement" | ||
| // SIGN: attributes #[[#ATTR]] = { {{.*}} "sign-return-address"="non-leaf" | ||
| // BTE-NOT: attributes #[[#ATTR]] = { {{.*}} "sign-return-address" | ||
| // BTE: attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement" | ||
| // ALL: attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"{{.*}} "sign-return-address"="all" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,304 @@ | ||
| ; RUN: rm -rf %t | ||
| ; RUN: split-file %s %t | ||
|
|
||
| ; RUN: yaml2obj %t/umbrella.yaml -o %t/System/Library/Frameworks/Umbrella.framework/Umbrella | ||
|
|
||
| ; RUN: clang-installapi -target arm64-apple-macosx14 -install_name \ | ||
| ; RUN: /System/Library/Frameworks/Umbrella.framework/Versions/A/Umbrella \ | ||
| ; RUN: --verify-against=%t/System/Library/Frameworks/Umbrella.framework/Umbrella \ | ||
| ; RUN: -L%t/usr/lib -F%t/System/Library/Frameworks \ | ||
| ; RUN: %t/System/Library/Frameworks/Umbrella.framework --verify-mode=Pedantic -reexport-lBar \ | ||
| ; RUN: -o %t/Umbrella.tbd 2>&1 | FileCheck -allow-empty %s | ||
| ; RUN: llvm-readtapi -compare %t/Umbrella.tbd %t/expected.tbd 2>&1 | FileCheck -allow-empty %s | ||
|
|
||
| ; CHECK-NOT: error | ||
| ; CHECK-NOT: warning | ||
|
|
||
| ;--- System/Library/Frameworks/Umbrella.framework/Headers/Umbrella.h | ||
| extern const char ld_previous __asm("$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$"); | ||
| extern void function(); | ||
|
|
||
| ;--- umbrella.yaml | ||
| --- !mach-o | ||
| FileHeader: | ||
| magic: 0xFEEDFACF | ||
| cputype: 0x100000C | ||
| cpusubtype: 0x0 | ||
| filetype: 0x6 | ||
| ncmds: 16 | ||
| sizeofcmds: 856 | ||
| flags: 0x85 | ||
| reserved: 0x0 | ||
| LoadCommands: | ||
| - cmd: LC_SEGMENT_64 | ||
| cmdsize: 312 | ||
| segname: __TEXT | ||
| vmaddr: 0 | ||
| vmsize: 16384 | ||
| fileoff: 0 | ||
| filesize: 16384 | ||
| maxprot: 5 | ||
| initprot: 5 | ||
| nsects: 3 | ||
| flags: 0 | ||
| Sections: | ||
| - sectname: __text | ||
| segname: __TEXT | ||
| addr: 0x3FB0 | ||
| size: 4 | ||
| offset: 0x3FB0 | ||
| align: 2 | ||
| reloff: 0x0 | ||
| nreloc: 0 | ||
| flags: 0x80000400 | ||
| reserved1: 0x0 | ||
| reserved2: 0x0 | ||
| reserved3: 0x0 | ||
| content: C0035FD6 | ||
| - sectname: __const | ||
| segname: __TEXT | ||
| addr: 0x3FB4 | ||
| size: 1 | ||
| offset: 0x3FB4 | ||
| align: 0 | ||
| reloff: 0x0 | ||
| nreloc: 0 | ||
| flags: 0x0 | ||
| reserved1: 0x0 | ||
| reserved2: 0x0 | ||
| reserved3: 0x0 | ||
| content: '00' | ||
| - sectname: __unwind_info | ||
| segname: __TEXT | ||
| addr: 0x3FB8 | ||
| size: 72 | ||
| offset: 0x3FB8 | ||
| align: 2 | ||
| reloff: 0x0 | ||
| nreloc: 0 | ||
| flags: 0x0 | ||
| reserved1: 0x0 | ||
| reserved2: 0x0 | ||
| reserved3: 0x0 | ||
| content: 010000001C000000000000001C000000000000001C00000002000000B03F00003400000034000000B53F00000000000034000000030000000C000100100001000000000000000002 | ||
| - cmd: LC_SEGMENT_64 | ||
| cmdsize: 72 | ||
| segname: __LINKEDIT | ||
| vmaddr: 16384 | ||
| vmsize: 16384 | ||
| fileoff: 16384 | ||
| filesize: 584 | ||
| maxprot: 1 | ||
| initprot: 1 | ||
| nsects: 0 | ||
| flags: 0 | ||
| - cmd: LC_ID_DYLIB | ||
| cmdsize: 96 | ||
| dylib: | ||
| name: 24 | ||
| timestamp: 1 | ||
| current_version: 0 | ||
| compatibility_version: 0 | ||
| Content: '/System/Library/Frameworks/Umbrella.framework/Versions/A/Umbrella' | ||
| ZeroPadBytes: 7 | ||
| - cmd: LC_DYLD_CHAINED_FIXUPS | ||
| cmdsize: 16 | ||
| dataoff: 16384 | ||
| datasize: 48 | ||
| - cmd: LC_DYLD_EXPORTS_TRIE | ||
| cmdsize: 16 | ||
| dataoff: 16432 | ||
| datasize: 104 | ||
| - cmd: LC_SYMTAB | ||
| cmdsize: 24 | ||
| symoff: 16560 | ||
| nsyms: 2 | ||
| stroff: 16592 | ||
| strsize: 96 | ||
| - cmd: LC_DYSYMTAB | ||
| cmdsize: 80 | ||
| ilocalsym: 0 | ||
| nlocalsym: 0 | ||
| iextdefsym: 0 | ||
| nextdefsym: 2 | ||
| iundefsym: 2 | ||
| nundefsym: 0 | ||
| tocoff: 0 | ||
| ntoc: 0 | ||
| modtaboff: 0 | ||
| nmodtab: 0 | ||
| extrefsymoff: 0 | ||
| nextrefsyms: 0 | ||
| indirectsymoff: 0 | ||
| nindirectsyms: 0 | ||
| extreloff: 0 | ||
| nextrel: 0 | ||
| locreloff: 0 | ||
| nlocrel: 0 | ||
| - cmd: LC_UUID | ||
| cmdsize: 24 | ||
| uuid: CCD7F304-D97B-3521-A980-CC936CCD34E8 | ||
| - cmd: LC_BUILD_VERSION | ||
| cmdsize: 32 | ||
| platform: 1 | ||
| minos: 917504 | ||
| sdk: 983040 | ||
| ntools: 1 | ||
| Tools: | ||
| - tool: 3 | ||
| version: 62525440 | ||
| - cmd: LC_SOURCE_VERSION | ||
| cmdsize: 16 | ||
| version: 0 | ||
| - cmd: LC_SEGMENT_SPLIT_INFO | ||
| cmdsize: 16 | ||
| dataoff: 16536 | ||
| datasize: 16 | ||
| - cmd: LC_REEXPORT_DYLIB | ||
| cmdsize: 48 | ||
| dylib: | ||
| name: 24 | ||
| timestamp: 2 | ||
| current_version: 65536 | ||
| compatibility_version: 65536 | ||
| Content: '/usr/lib/libBar.dylib' | ||
| ZeroPadBytes: 3 | ||
| - cmd: LC_LOAD_DYLIB | ||
| cmdsize: 56 | ||
| dylib: | ||
| name: 24 | ||
| timestamp: 2 | ||
| current_version: 88539136 | ||
| compatibility_version: 65536 | ||
| Content: '/usr/lib/libSystem.B.dylib' | ||
| ZeroPadBytes: 6 | ||
| - cmd: LC_FUNCTION_STARTS | ||
| cmdsize: 16 | ||
| dataoff: 16552 | ||
| datasize: 8 | ||
| - cmd: LC_DATA_IN_CODE | ||
| cmdsize: 16 | ||
| dataoff: 16560 | ||
| datasize: 0 | ||
| - cmd: LC_CODE_SIGNATURE | ||
| cmdsize: 16 | ||
| dataoff: 16688 | ||
| datasize: 280 | ||
| LinkEditData: | ||
| ExportTrie: | ||
| TerminalSize: 0 | ||
| NodeOffset: 0 | ||
| Name: '' | ||
| Flags: 0x0 | ||
| Address: 0x0 | ||
| Other: 0x0 | ||
| ImportName: '' | ||
| Children: | ||
| - TerminalSize: 3 | ||
| NodeOffset: 94 | ||
| Name: '$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$' | ||
| Flags: 0x0 | ||
| Address: 0x3FB4 | ||
| Other: 0x0 | ||
| ImportName: '' | ||
| - TerminalSize: 3 | ||
| NodeOffset: 99 | ||
| Name: _function | ||
| Flags: 0x0 | ||
| Address: 0x3FB0 | ||
| Other: 0x0 | ||
| ImportName: '' | ||
| NameList: | ||
| - n_strx: 2 | ||
| n_type: 0xF | ||
| n_sect: 2 | ||
| n_desc: 0 | ||
| n_value: 16308 | ||
| - n_strx: 82 | ||
| n_type: 0xF | ||
| n_sect: 1 | ||
| n_desc: 0 | ||
| n_value: 16304 | ||
| StringTable: | ||
| - ' ' | ||
| - '$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$' | ||
| - _function | ||
| - '' | ||
| - '' | ||
| - '' | ||
| - '' | ||
| FunctionStarts: [ 0x3FB0 ] | ||
| ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x2C, 0x0, | ||
| 0x0, 0x0, 0x2C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | ||
| 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | ||
| 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | ||
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ] | ||
| ... | ||
|
|
||
| ;--- /usr/lib/libBar.dylib | ||
| { | ||
| "main_library": { | ||
| "exported_symbols": [ | ||
| { | ||
| "text": { | ||
| "global": [ | ||
| "$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$" | ||
| ] | ||
| } | ||
| } | ||
| ], | ||
| "flags": [ | ||
| { | ||
| "attributes": [ | ||
| "not_app_extension_safe" | ||
| ] | ||
| } | ||
| ], | ||
| "install_names": [ | ||
| { | ||
| "name": "/usr/lib/libBar.dylib" | ||
| } | ||
| ], | ||
| "target_info": [ | ||
| { | ||
| "min_deployment": "13", | ||
| "target": "arm64-macos" | ||
| } | ||
| ] | ||
| }, | ||
| "tapi_tbd_version": 5 | ||
| } | ||
|
|
||
| ;--- expected.tbd | ||
| { | ||
| "main_library": { | ||
| "compatibility_versions": [ { "version": "0" } ], | ||
| "current_versions": [ { "version": "0" } ], | ||
| "exported_symbols": [ | ||
| { | ||
| "data": { | ||
| "global": [ | ||
| "$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$" | ||
| ] | ||
| }, | ||
| "text": { "global": [ "_function" ] } | ||
| } | ||
| ], | ||
| "flags": [ | ||
| { "attributes": [ "not_app_extension_safe" ] } | ||
| ], | ||
| "install_names": [ | ||
| { "name": "/System/Library/Frameworks/Umbrella.framework/Versions/A/Umbrella" } | ||
| ], | ||
| "reexported_libraries": [ | ||
| { "names": [ "/usr/lib/libBar.dylib" ] } | ||
| ], | ||
| "target_info": [ | ||
| { | ||
| "min_deployment": "14", | ||
| "target": "arm64-macos" | ||
| } | ||
| ] | ||
| }, | ||
| "tapi_tbd_version": 5 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| // RUN: %clang_cc1 -fsyntax-only -std=gnu11 -verify=supported %s | ||
| // RUN: %clang_cc1 -fsyntax-only -std=c11 -DUNICODE -fraw-string-literals -verify=supported %s | ||
| // RUN: %clang_cc1 -fsyntax-only -std=gnu89 -verify=unsupported %s | ||
| // RUN: %clang_cc1 -fsyntax-only -std=c11 -DUNICODE -verify=unsupported %s | ||
| // RUN: %clang_cc1 -fsyntax-only -std=gnu11 -DUNICODE -fno-raw-string-literals -verify=unsupported %s | ||
|
|
||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++03 -verify=unsupported,cxx-unsupported %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++03 -verify=unsupported,cxx-unsupported %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++03 -fraw-string-literals -verify=supported %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++03 -fraw-string-literals -verify=supported %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 -DUNICODE -verify=supported,cxx %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 -DUNICODE -verify=supported,cxx %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 -DUNICODE -fraw-string-literals -verify=supported,yes %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 -DUNICODE -fraw-string-literals -verify=supported,yes %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=c++11 -DUNICODE -fno-raw-string-literals -verify=supported,no %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -Wno-unused -std=gnu++11 -DUNICODE -fno-raw-string-literals -verify=supported,no %s | ||
|
|
||
| // GCC supports raw string literals in C99 and later in '-std=gnuXY' mode; we | ||
| // additionally provide '-f[no-]raw-string-literals' to enable/disable them | ||
| // explicitly in C. | ||
| // | ||
| // We do not allow disabling raw string literals in C++ mode if they’re enabled | ||
| // by the language standard, i.e. in C++11 or later. | ||
|
|
||
| // Driver warnings. | ||
| // yes-warning@* {{ignoring '-fraw-string-literals'}} | ||
| // no-warning@* {{ignoring '-fno-raw-string-literals'}} | ||
|
|
||
| void f() { | ||
| (void) R"foo()foo"; // unsupported-error {{use of undeclared identifier 'R'}} cxx-unsupported-error {{expected ';' after expression}} | ||
| (void) LR"foo()foo"; // unsupported-error {{use of undeclared identifier 'LR'}} cxx-unsupported-error {{expected ';' after expression}} | ||
|
|
||
| #ifdef UNICODE | ||
| (void) uR"foo()foo"; // unsupported-error {{use of undeclared identifier 'uR'}} cxx-unsupported-error {{expected ';' after expression}} | ||
| (void) u8R"foo()foo"; // unsupported-error {{use of undeclared identifier 'u8R'}} cxx-unsupported-error {{expected ';' after expression}} | ||
| (void) UR"foo()foo"; // unsupported-error {{use of undeclared identifier 'UR'}} cxx-unsupported-error {{expected ';' after expression}} | ||
| #endif | ||
| } | ||
|
|
||
| // supported-error@* {{missing terminating delimiter}} | ||
| // supported-error@* {{expected expression}} | ||
| // supported-error@* {{expected ';' after top level declarator}} | ||
| #define R "bar" | ||
| const char* s = R"foo("; |