diff options
author | Martin Sebor <msebor@redhat.com> | 2018-11-15 22:53:57 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2018-11-15 15:53:57 -0700 |
commit | 1d24950977c730f5e955060057b1dd0b5c051adb (patch) | |
tree | aecd56593f283b79ac0939bd57a5555c6b93239f /gcc/tree.c | |
parent | cd5da9837b26d77136d3a9394747ce4325a95118 (diff) | |
download | gcc-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.c | 42 |
1 files changed, 38 insertions, 4 deletions
@@ -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. */ |