Commit 02a32ab4 by Richard Sandiford Committed by Richard Sandiford

[C++] Pass type uses through the verify_type_context hook

This patch makes the C++ frontend work with the verify_type_context hook.
We need some new type contexts for features that don't exist in C, but
otherwise the patch is very similar to the C one.

TCTX_CAPTURE_BY_COPY could really be treated as an instance of
TCTX_FIELD, but the error message is better if we split it out.

2019-12-06  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* target.h (TCTX_ALLOCATION, TCTX_DEALLOCATION, TCTX_EXCEPTIONS)
	(TCTX_CAPTURE_BY_COPY): New type_context_kinds.
	* config/aarch64/aarch64-sve-builtins.cc (verify_type_context):
	Handle them.

gcc/cp/
	* decl.c (start_decl_1): Use verify_type_context to check whether
	the target allows variables of a particular type to have static
	or thread-local storage duration.
	(check_array_initializer): Use verify_type_context to check whether
	the target allows a particular type to be used as an array element.
	(create_array_type_for_decl): Likewise.
	(cp_finish_decl): Use verify_type_context to check whether
	the target allows static member variables of a particular type.
	(grokdeclarator): Likewise.  Also use verify_type_context to check
	whether the target allows non-static member variables of a particular
	type.
	* except.c: Include target.h.
	(is_admissible_throw_operand_or_catch_parameter): Use
	verify_type_context to check whether the target allows particular
	types to be thrown and caught.
	* typeck2.c (add_exception_specifier): Likewise.
	* init.c (build_new_1): Use verify_type_context to check whether
	the target allows particular types to be dynamically allocated.
	(build_vec_delete_1, build_delete): Use verify_type_context to check
	whether the target allows particular types to be deleted.
	* lambda.c (add_capture): Use verify_type_context to check
	whether the target allows particular types to be captured by copy.
	* pt.c: Include target.h.
	(instantiate_class_template_1): Use verify_type_context to check
	whether the target allows non-static member variables of a particular
	type.
	* typeck.c (cxx_alignof_expr): Use verify_type_context to check
	whether the target allows the alignment of a particular type
	to be measured.
	(pointer_diff, cp_build_unary_op): Use verify_type_context to check
	whether the target allows arithmetic involving pointers to particular
	types.

gcc/testsuite/
	* g++.dg/ext/sve-sizeless-1.C: New test.
	* g++.dg/ext/sve-sizeless-2.C: Likewise.

From-SVN: r279058
parent 1e8f5d49
2019-12-06 Richard Sandiford <richard.sandiford@arm.com>
* target.h (TCTX_ALLOCATION, TCTX_DEALLOCATION, TCTX_EXCEPTIONS)
(TCTX_CAPTURE_BY_COPY): New type_context_kinds.
* config/aarch64/aarch64-sve-builtins.cc (verify_type_context):
Handle them.
2019-12-06 Andrew Stubbs <ams@codesourcery.com>
* config/gcn/gcn-valu.md (gather<mode>_insn_1offset<exec>): Use %o
......@@ -3352,6 +3352,26 @@ verify_type_context (location_t loc, type_context_kind context,
if (!silent_p)
error_at (loc, "array elements cannot have SVE type %qT", type);
return false;
case TCTX_ALLOCATION:
if (!silent_p)
error_at (loc, "cannot allocate objects with SVE type %qT", type);
return false;
case TCTX_DEALLOCATION:
if (!silent_p)
error_at (loc, "cannot delete objects with SVE type %qT", type);
return false;
case TCTX_EXCEPTIONS:
if (!silent_p)
error_at (loc, "cannot throw or catch SVE type %qT", type);
return false;
case TCTX_CAPTURE_BY_COPY:
if (!silent_p)
error_at (loc, "capture by copy of SVE type %qT", type);
return false;
}
gcc_unreachable ();
}
......
2019-12-06 Richard Sandiford <richard.sandiford@arm.com>
* decl.c (start_decl_1): Use verify_type_context to check whether
the target allows variables of a particular type to have static
or thread-local storage duration.
(check_array_initializer): Use verify_type_context to check whether
the target allows a particular type to be used as an array element.
(create_array_type_for_decl): Likewise.
(cp_finish_decl): Use verify_type_context to check whether
the target allows static member variables of a particular type.
(grokdeclarator): Likewise. Also use verify_type_context to check
whether the target allows non-static member variables of a particular
type.
* except.c: Include target.h.
(is_admissible_throw_operand_or_catch_parameter): Use
verify_type_context to check whether the target allows particular
types to be thrown and caught.
* typeck2.c (add_exception_specifier): Likewise.
* init.c (build_new_1): Use verify_type_context to check whether
the target allows particular types to be dynamically allocated.
(build_vec_delete_1, build_delete): Use verify_type_context to check
whether the target allows particular types to be deleted.
* lambda.c (add_capture): Use verify_type_context to check
whether the target allows particular types to be captured by copy.
* pt.c: Include target.h.
(instantiate_class_template_1): Use verify_type_context to check
whether the target allows non-static member variables of a particular
type.
* typeck.c (cxx_alignof_expr): Use verify_type_context to check
whether the target allows the alignment of a particular type
to be measured.
(pointer_diff, cp_build_unary_op): Use verify_type_context to check
whether the target allows arithmetic involving pointers to particular
types.
2019-12-05 Marek Polacek <polacek@redhat.com>
Jakub Jelinek <jakub@redhat.com>
......
......@@ -5470,6 +5470,13 @@ start_decl_1 (tree decl, bool initialized)
cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
}
if (is_global_var (decl))
{
type_context_kind context = (DECL_THREAD_LOCAL_P (decl)
? TCTX_THREAD_STORAGE
: TCTX_STATIC_STORAGE);
verify_type_context (input_location, context, TREE_TYPE (decl));
}
if (initialized)
/* Is it valid for this decl to have an initializer at all? */
{
......@@ -6535,6 +6542,11 @@ check_array_initializer (tree decl, tree type, tree init)
error ("elements of array %q#T have incomplete type", type);
return true;
}
location_t loc = (decl ? location_of (decl) : input_location);
if (!verify_type_context (loc, TCTX_ARRAY_ELEMENT, element_type))
return true;
/* A compound literal can't have variable size. */
if (init && !decl
&& ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
......@@ -7482,6 +7494,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
if (VAR_P (decl)
&& DECL_CLASS_SCOPE_P (decl)
&& verify_type_context (DECL_SOURCE_LOCATION (decl),
TCTX_STATIC_STORAGE, type)
&& DECL_INITIALIZED_IN_CLASS_P (decl))
check_static_variable_definition (decl, type);
......@@ -10550,6 +10564,10 @@ create_array_type_for_decl (tree name, tree type, tree size, location_t loc)
break;
}
if (!verify_type_context (name ? loc : input_location,
TCTX_ARRAY_ELEMENT, type))
return error_mark_node;
/* [dcl.array]
The constant expressions that specify the bounds of the arrays
......@@ -13254,6 +13272,14 @@ grokdeclarator (const cp_declarator *declarator,
decl = NULL_TREE;
}
}
else if (!verify_type_context (input_location,
staticp
? TCTX_STATIC_STORAGE
: TCTX_FIELD, type))
{
type = error_mark_node;
decl = NULL_TREE;
}
else
{
if (friendp)
......
......@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "trans-mem.h"
#include "attribs.h"
#include "tree-iterator.h"
#include "target.h"
static void push_eh_cleanup (tree);
static tree prepare_eh_type (tree);
......@@ -927,6 +928,10 @@ is_admissible_throw_operand_or_catch_parameter (tree t, bool is_throw)
if (!complete_ptr_ref_or_void_ptr_p (type, expr))
return false;
tree nonref_type = non_reference (type);
if (!verify_type_context (input_location, TCTX_EXCEPTIONS, nonref_type))
return false;
/* 10.4/3 An abstract class shall not be used as a parameter type,
as a function return type or as type of an explicit
conversion. */
......
......@@ -3058,6 +3058,10 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
complain);
}
if (!verify_type_context (input_location, TCTX_ALLOCATION, elt_type,
!(complain & tf_error)))
return error_mark_node;
if (variably_modified_type_p (elt_type, NULL_TREE) && (complain & tf_error))
{
error ("variably modified type not allowed in new-expression");
......@@ -3942,6 +3946,10 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
if (base == error_mark_node || maxindex == error_mark_node)
return error_mark_node;
if (!verify_type_context (input_location, TCTX_DEALLOCATION, type,
!(complain & tf_error)))
return error_mark_node;
if (!COMPLETE_TYPE_P (type))
{
if (complain & tf_warning)
......@@ -4827,6 +4835,11 @@ build_delete (tree otype, tree addr, special_function_kind auto_delete,
if (!VOID_TYPE_P (type))
{
complete_type (type);
if (deleting
&& !verify_type_context (input_location, TCTX_DEALLOCATION, type,
!(complain & tf_error)))
return error_mark_node;
if (!COMPLETE_TYPE_P (type))
{
if (complain & tf_warning)
......
......@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "toplev.h"
#include "gimplify.h"
#include "target.h"
/* Constructor for a lambda expression. */
......@@ -579,6 +580,9 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
cxx_incomplete_type_inform (type);
return error_mark_node;
}
else if (!verify_type_context (input_location,
TCTX_CAPTURE_BY_COPY, type))
return error_mark_node;
}
}
......
......@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h"
#include "gcc-rich-location.h"
#include "selftest.h"
#include "target.h"
/* The type of functions taking a tree, and some additional data, and
returning an int. */
......@@ -11815,6 +11816,9 @@ instantiate_class_template_1 (tree type)
error ("flexible array member %qD in union", r);
TREE_TYPE (r) = error_mark_node;
}
else if (!verify_type_context (input_location,
TCTX_FIELD, rtype))
TREE_TYPE (r) = error_mark_node;
}
/* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE,
......
......@@ -1824,7 +1824,14 @@ cxx_alignof_expr (tree e, tsubst_flags_t complain)
e = mark_type_use (e);
if (VAR_P (e))
if (!verify_type_context (input_location, TCTX_ALIGNOF, TREE_TYPE (e),
!(complain & tf_error)))
{
if (!(complain & tf_error))
return error_mark_node;
t = size_one_node;
}
else if (VAR_P (e))
t = size_int (DECL_ALIGN_UNIT (e));
else if (bitfield_p (e))
{
......@@ -5778,6 +5785,13 @@ pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype,
else
return error_mark_node;
}
else if (!verify_type_context (loc, TCTX_POINTER_ARITH,
TREE_TYPE (TREE_TYPE (op0)),
!(complain & tf_error))
|| !verify_type_context (loc, TCTX_POINTER_ARITH,
TREE_TYPE (TREE_TYPE (op1)),
!(complain & tf_error)))
return error_mark_node;
/* Determine integer type result of the subtraction. This will usually
be the same as the result type (ptrdiff_t), but may need to be a wider
......@@ -6572,6 +6586,10 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
else
return error_mark_node;
}
else if (!verify_type_context (location, TCTX_POINTER_ARITH,
TREE_TYPE (argtype),
!(complain & tf_error)))
return error_mark_node;
inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
}
......
......@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "varasm.h"
#include "intl.h"
#include "gcc-rich-location.h"
#include "target.h"
static tree
process_init_constructor (tree type, tree init, int nested, int flags,
......@@ -2401,6 +2402,9 @@ add_exception_specifier (tree list, tree spec, tsubst_flags_t complain)
ok = true;
else if (processing_template_decl)
ok = true;
else if (!verify_type_context (input_location, TCTX_EXCEPTIONS, core,
!(complain & tf_error)))
return error_mark_node;
else
{
ok = true;
......
......@@ -249,7 +249,19 @@ enum type_context_kind {
/* 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
TCTX_POINTER_ARITH,
/* Dynamically allocating objects of type T. */
TCTX_ALLOCATION,
/* Dynamically deallocating objects of type T. */
TCTX_DEALLOCATION,
/* Throwing or catching an object of type T. */
TCTX_EXCEPTIONS,
/* Capturing objects of type T by value in a closure. */
TCTX_CAPTURE_BY_COPY
};
extern bool verify_type_context (location_t, type_context_kind, const_tree,
......
2019-12-06 Richard Sandiford <richard.sandiford@arm.com>
* g++.dg/ext/sve-sizeless-1.C: New test.
* g++.dg/ext/sve-sizeless-2.C: Likewise.
2019-12-06 Christophe Lyon <christophe.lyon@linaro.org>
PR c/36941
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment