diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-11-30 18:50:06 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-11-30 18:50:06 +0000 |
commit | 65ef05d0b7fb429c5760189e638c441dc3da33f4 (patch) | |
tree | 0f798da78b2315a23be7f7f79b6a7fa0380a0ecf /gcc/target.h | |
parent | b74d8dc4cf11da599b5c18d77a5039bc800d6871 (diff) | |
download | gcc-65ef05d0b7fb429c5760189e638c441dc3da33f4.zip gcc-65ef05d0b7fb429c5760189e638c441dc3da33f4.tar.gz gcc-65ef05d0b7fb429c5760189e638c441dc3da33f4.tar.bz2 |
[C] Add a target hook that allows targets to verify type usage
This patch adds a new target hook to check whether there are any
target-specific reasons why a type cannot be used in a certain
source-language context. It works in a similar way to existing
hooks like TARGET_INVALID_CONVERSION and TARGET_INVALID_UNARY_OP.
The reason for adding the hook is to report invalid uses of SVE types.
Throughout a TU, the SVE vector and predicate types represent values
that can be stored in an SVE vector or predicate register. At certain
points in the TU we might be able to generate code that assumes the
registers have a particular size, but often we can't. In some cases
we might even make multiple different assumptions in the same TU
(e.g. when implementing an ifunc for multiple vector lengths).
But SVE types themselves are the same type throughout. The register
size assumptions change how we generate code, but they don't change
the definition of the types.
This means that the types do not have a fixed size at the C level
even when -msve-vector-bits=N is in effect. It also means that the
size does not work in the same way as for C VLAs, where the abstract
machine evaluates the size at a particular point and then carries that
size forward to later code.
The SVE ACLE deals with this by making it invalid to use C and C++
constructs that depend on the size or layout of SVE types. The spec
refers to the types as "sizeless" types and defines their semantics as
edits to the standards. See:
https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00868.html
for a fuller description and:
https://gcc.gnu.org/ml/gcc/2019-11/msg00088.html
for a recent update on the status.
However, since all current sizeless types are target-specific built-in
types, there's no real reason for the frontends to handle them directly.
They can just hand off the checks to target code instead. It's then
possible for the errors to refer to "SVE types" rather than "sizeless
types", which is likely to be more meaningful to users.
There is a slight overlap between the new tests and the ones for
gnu_vector_type_p in r277950, but here the emphasis is on testing
sizelessness.
2019-11-30 Richard Sandiford <richard.sandiford@arm.com>
gcc/
* target.h (type_context_kind): New enum.
(verify_type_context): Declare.
* target.def (verify_type_context): New target hook.
* doc/tm.texi.in (TARGET_VERIFY_TYPE_CONTEXT): Likewise.
* doc/tm.texi: Regenerate.
* tree.c (verify_type_context): New function.
* config/aarch64/aarch64-protos.h (aarch64_sve::verify_type_context):
Declare.
* config/aarch64/aarch64-sve-builtins.cc (verify_type_context):
New function.
* config/aarch64/aarch64.c (aarch64_verify_type_context): Likewise.
(TARGET_VERIFY_TYPE_CONTEXT): Define.
gcc/c-family/
* c-common.c (pointer_int_sum): Use verify_type_context to check
whether the target allows pointer arithmetic for the types involved.
(c_sizeof_or_alignof_type, c_alignof_expr): Use verify_type_context
to check whether the target allows sizeof and alignof operations
for the types involved.
gcc/c/
* c-decl.c (start_decl): Allow initialization of variables whose
size is a POLY_INT_CST.
(finish_decl): Use verify_type_context to check whether the target
allows variables with a particular type to have static or thread-local
storage duration. Don't raise a second error if such variables do
not have a constant size.
(grokdeclarator): Use verify_type_context to check whether the
target allows fields or array elements to have a particular type.
* c-typeck.c (pointer_diff): Use verify_type_context to test whether
the target allows pointer difference for the types involved.
(build_unary_op): Likewise for pointer increment and decrement.
gcc/testsuite/
* gcc.target/aarch64/sve/acle/general-c/sizeless-1.c: New test.
* gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Likewise.
From-SVN: r278877
Diffstat (limited to 'gcc/target.h')
-rw-r--r-- | gcc/target.h | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/gcc/target.h b/gcc/target.h index 2c5b59b..973d743 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -226,6 +226,35 @@ enum omp_device_kind_arch_isa { will choose the first mode that works. */ const unsigned int VECT_COMPARE_COSTS = 1U << 0; +/* The contexts in which the use of a type T can be checked by + TARGET_VERIFY_TYPE_CONTEXT. */ +enum type_context_kind { + /* Directly measuring the size of T. */ + TCTX_SIZEOF, + + /* Directly measuring the alignment of T. */ + TCTX_ALIGNOF, + + /* Creating objects of type T with static storage duration. */ + TCTX_STATIC_STORAGE, + + /* Creating objects of type T with thread-local storage duration. */ + TCTX_THREAD_STORAGE, + + /* Creating a field of type T. */ + TCTX_FIELD, + + /* Creating an array with elements of type T. */ + TCTX_ARRAY_ELEMENT, + + /* Adding to or subtracting from a pointer to T, or computing the + difference between two pointers when one of them is a pointer to T. */ + TCTX_POINTER_ARITH +}; + +extern bool verify_type_context (location_t, type_context_kind, const_tree, + bool = false); + /* The target structure. This holds all the backend hooks. */ #define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME; #define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS; |