aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2018-11-15 22:53:57 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2018-11-15 15:53:57 -0700
commit1d24950977c730f5e955060057b1dd0b5c051adb (patch)
treeaecd56593f283b79ac0939bd57a5555c6b93239f /gcc/tree.c
parentcd5da9837b26d77136d3a9394747ce4325a95118 (diff)
downloadgcc-1d24950977c730f5e955060057b1dd0b5c051adb.zip
gcc-1d24950977c730f5e955060057b1dd0b5c051adb.tar.gz
gcc-1d24950977c730f5e955060057b1dd0b5c051adb.tar.bz2
PR c++/87541 - ICE using a constant decl as an attribute alloc_size argument
PR c++/87541 - ICE using a constant decl as an attribute alloc_size argument PR c++/87542 - bogus error on attribute format with a named constant argument gcc/ChangeLog: PR c++/87541 PR c++/87542 * tree.c (type_argument_type): New function. * tree.h (type_argument_type): Declare it. * gcc/doc/extend.texi (alloc_align): Update and clarify. (alloc_size, nonnull, sentinel): Same. gcc/c-family/ChangeLog: PR c++/87541 PR c++/87542 * c-attribs.c (positional_argument): New function. (handle_alloc_size_attribute): Use it and simplify. (handle_alloc_align_attribute): Same. (handle_assume_aligned_attribute): Same. (handle_nonnull_attribute): Same. * c-common.c (check_function_arguments): Pass fntype to check_function_format. * c-common.h (check_function_format): Add an argument. (PosArgFlags, positional_argument): Declare new type and function. * c-format.c (decode_format_attr): Add arguments. (check_format_string, get_constant): Same. (convert_format_name_to_system_name): Adjust. gcc/testsuite/ChangeLog: PR c++/87541 PR c++/87542 * g++.dg/ext/attr-alloc_size.C: New test. * c-c++-common/pr71574.c: Adjust diagnostics. * c-c++-common/attributes-1.c: Same. * gcc.dg/attr-alloc_align-2.c: Same. * gcc.dg/attr-alloc_align-4.c: New test. * gcc.dg/attr-alloc_size-2.c: Adjust diagnostics. * gcc.dg/attr-alloc_size.c: Same. * gcc.dg/attr-assume_aligned-4.c: New test. * gcc.dg/format/attr-3.c: Adjust diagnostics. * gcc.dg/nonnull-2.c: Same. * gcc.dg/torture/pr80612.c: Same. * obj-c++.dg/attributes/method-format-1.mm: Same. * obj-c++.dg/attributes/method-nonnull-1.mm: Same. * objc.dg/attributes/method-format-1.m: same. * objc.dg/attributes/method-nonnull-1.m: Same. From-SVN: r266195
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index db680a9..be89897 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -4955,7 +4955,8 @@ build_nt_call_vec (tree fn, vec<tree, va_gc> *args)
return ret;
}
-/* Create a DECL_... node of code CODE, name NAME and data type TYPE.
+/* Create a DECL_... node of code CODE, name NAME (if non-null)
+ and data type TYPE.
We do NOT enter this node in any sort of symbol table.
LOC is the location of the decl.
@@ -6944,12 +6945,11 @@ type_list_equal (const_tree l1, const_tree l2)
then this function counts only the ordinary arguments. */
int
-type_num_arguments (const_tree type)
+type_num_arguments (const_tree fntype)
{
int i = 0;
- tree t;
- for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
+ for (tree t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
/* If the function does not take a variable number of arguments,
the last element in the list will have type `void'. */
if (VOID_TYPE_P (TREE_VALUE (t)))
@@ -6960,6 +6960,40 @@ type_num_arguments (const_tree type)
return i;
}
+/* Return the type of the function TYPE's argument ARGNO if known.
+ For vararg function's where ARGNO refers to one of the variadic
+ arguments return null. Otherwise, return a void_type_node for
+ out-of-bounds ARGNO. */
+
+tree
+type_argument_type (const_tree fntype, unsigned argno)
+{
+ /* Treat zero the same as an out-of-bounds argument number. */
+ if (!argno)
+ return void_type_node;
+
+ function_args_iterator iter;
+
+ tree argtype;
+ unsigned i = 1;
+ FOREACH_FUNCTION_ARGS (fntype, argtype, iter)
+ {
+ /* A vararg function's argument list ends in a null. Otherwise,
+ an ordinary function's argument list ends with void. Return
+ null if ARGNO refers to a vararg argument, void_type_node if
+ it's out of bounds, and the formal argument type otherwise. */
+ if (!argtype)
+ break;
+
+ if (i == argno || VOID_TYPE_P (argtype))
+ return argtype;
+
+ ++i;
+ }
+
+ return NULL_TREE;
+}
+
/* Nonzero if integer constants T1 and T2
represent the same constant value. */