From b825a22890740f341eae566af27e18e528cd29a7 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 4 Jun 2020 16:06:10 -0600 Subject: Implement a solution for PR middle-end/10138 and PR middle-end/95136. PR middle-end/10138 - warn for uninitialized arrays passed as const arguments PR middle-end/95136 - missing -Wuninitialized on an array access with a variable offset gcc/c-family/ChangeLog: PR middle-end/10138 PR middle-end/95136 * c-attribs.c (append_access_attrs): Handle attr_access::none. (handle_access_attribute): Same. gcc/ChangeLog: PR middle-end/10138 PR middle-end/95136 * attribs.c (init_attr_rdwr_indices): Move function here. * attribs.h (rdwr_access_hash, rdwr_map): Define. (attr_access): Add 'none'. (init_attr_rdwr_indices): Declared function. * builtins.c (warn_for_access)): New function. (check_access): Call it. * builtins.h (checK-access): Add an optional argument. * calls.c (rdwr_access_hash, rdwr_map): Move to attribs.h. (init_attr_rdwr_indices): Declare extern. (append_attrname): Handle attr_access::none. (maybe_warn_rdwr_sizes): Same. (initialize_argument_information): Update comments. * doc/extend.texi (attribute access): Document 'none'. * tree-ssa-uninit.c (struct wlimits): New. (maybe_warn_operand): New function. (maybe_warn_pass_by_reference): Same. (warn_uninitialized_vars): Refactor code into maybe_warn_operand. Also call for function calls. (pass_late_warn_uninitialized::execute): Adjust comments. (execute_early_warn_uninitialized): Same. gcc/testsuite/ChangeLog: PR middle-end/10138 PR middle-end/95136 * c-c++-common/Wsizeof-pointer-memaccess1.c: Prune out valid Wuninitialized. * c-c++-common/uninit-pr51010.c: Adjust expected warning format. * c-c++-common/goacc/uninit-dim-clause.c: Same. * c-c++-common/goacc/uninit-firstprivate-clause.c: Same. * c-c++-common/goacc/uninit-if-clause.c: Same. * c-c++-common/gomp/pr70550-1.c: Same. * c-c++-common/gomp/pr70550-2.c: Adjust. * g++.dg/20090107-1.C: Same. * g++.dg/20090121-1.C: Same. * g++.dg/ext/attr-access.C: Avoid -Wuninitialized. * gcc.dg/tree-ssa/forwprop-6.c: Prune out -Wuninitialized. * gcc.dg/Warray-bounds-52.c: Prune out valid -Wuninitialized. * gcc.dg/Warray-bounds-53.c: Same. * gcc.dg/Warray-bounds-54.c: Same. * gcc.dg/Wstringop-overflow-33.c: New test. * gcc.dg/attr-access-none.c: New test. * gcc.dg/attr-access-read-only.c: Adjust. * gcc.dg/attr-access-read-write.c: Same. * gcc.dg/attr-access-write-only.c: Same. * gcc.dg/pr71581.c: Adjust text of expected warning. * gcc.dg/uninit-15.c: Same. * gcc.dg/uninit-32.c: New test. * gcc.dg/uninit-33.c: New test. * gcc.dg/uninit-34.c: New test. * gcc.dg/uninit-36.c: New test. * gcc.dg/uninit-B-O0.c: Adjust text of expected warning. * gcc.dg/uninit-I-O0.c: Same. * gcc.dg/uninit-pr19430-O0.c: Same. * gcc.dg/uninit-pr19430.c: Same. * gcc.dg/uninit-pr95136.c: New test. * gfortran.dg/assignment_4.f90: Expect -Wuninitialized. * gfortran.dg/goacc/uninit-dim-clause.f95: Adjust text of expected warning. * gfortran.dg/goacc/uninit-firstprivate-clause.f95 * gfortran.dg/goacc/uninit-if-clause.f95 * gfortran.dg/pr66545_2.f90 --- gcc/calls.c | 83 ++++++++----------------------------------------------------- 1 file changed, 11 insertions(+), 72 deletions(-) (limited to 'gcc/calls.c') diff --git a/gcc/calls.c b/gcc/calls.c index 8041388..d1c9c0b 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1865,70 +1865,6 @@ maybe_complain_about_tail_call (tree call_expr, const char *reason) error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", reason); } -/* Used to define rdwr_map below. */ -struct rdwr_access_hash: int_hash { }; - -/* A mapping between argument number corresponding to attribute access - mode (read_only, write_only, or read_write) and operands. */ -typedef hash_map rdwr_map; - -/* Initialize a mapping for a call to function FNDECL declared with - attribute access. Each attribute positional operand inserts one - entry into the mapping with the operand number as the key. */ - -static void -init_attr_rdwr_indices (rdwr_map *rwm, tree fntype) -{ - if (!fntype) - return; - - for (tree access = TYPE_ATTRIBUTES (fntype); - (access = lookup_attribute ("access", access)); - access = TREE_CHAIN (access)) - { - /* The TREE_VALUE of an attribute is a TREE_LIST whose TREE_VALUE - is the attribute argument's value. */ - tree mode = TREE_VALUE (access); - gcc_assert (TREE_CODE (mode) == TREE_LIST); - mode = TREE_VALUE (mode); - gcc_assert (TREE_CODE (mode) == STRING_CST); - - const char *modestr = TREE_STRING_POINTER (mode); - for (const char *m = modestr; *m; ) - { - attr_access acc = { }; - - switch (*m) - { - case 'r': acc.mode = acc.read_only; break; - case 'w': acc.mode = acc.write_only; break; - default: acc.mode = acc.read_write; break; - } - - char *end; - acc.ptrarg = strtoul (++m, &end, 10); - m = end; - if (*m == ',') - { - acc.sizarg = strtoul (++m, &end, 10); - m = end; - } - else - acc.sizarg = UINT_MAX; - - acc.ptr = NULL_TREE; - acc.size = NULL_TREE; - - /* Unconditionally add an entry for the required pointer - operand of the attribute, and one for the optional size - operand when it's specified. */ - rwm->put (acc.ptrarg, acc); - if (acc.sizarg != UINT_MAX) - rwm->put (acc.sizarg, acc); - } - } -} - /* Returns the type of the argument ARGNO to function with type FNTYPE or null when the typoe cannot be determined or no such argument exists. */ @@ -1959,11 +1895,13 @@ append_attrname (const std::pair &access, appends the attribute pointer operand even when none was specified. */ size_t len = strlen (attrstr); - const char *atname + const char* const atname = (access.second.mode == attr_access::read_only ? "read_only" : (access.second.mode == attr_access::write_only - ? "write_only" : "read_write")); + ? "write_only" + : (access.second.mode == attr_access::read_write + ? "read_write" : "none"))); const char *sep = len ? ", " : ""; @@ -2131,11 +2069,13 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree exp) /* For read-only and read-write attributes also set the source size. */ srcsize = objsize; - if (access.second.mode == attr_access::read_only) + if (access.second.mode == attr_access::read_only + || access.second.mode == attr_access::none) { /* For a read-only attribute there is no destination so clear OBJSIZE. This emits "reading N bytes" kind of - diagnostics instead of the "writing N bytes" kind. */ + diagnostics instead of the "writing N bytes" kind, + unless MODE is none. */ objsize = NULL_TREE; } } @@ -2145,7 +2085,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree exp) diagnosed. */ TREE_NO_WARNING (exp) = false; check_access (exp, NULL_TREE, NULL_TREE, size, /*maxread=*/ NULL_TREE, - srcsize, objsize); + srcsize, objsize, access.second.mode != attr_access::none); if (TREE_NO_WARNING (exp)) /* If check_access issued a warning above, append the relevant @@ -2285,8 +2225,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, /* Array for up to the two attribute alloc_size arguments. */ tree alloc_args[] = { NULL_TREE, NULL_TREE }; - /* Map of attribute read_only, write_only, or read_write specifications - for function arguments. */ + /* Map of attribute accewss specifications for function arguments. */ rdwr_map rdwr_idx; init_attr_rdwr_indices (&rdwr_idx, fntype); @@ -2559,7 +2498,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, nul-terminated strings. */ maybe_warn_nonstring_arg (fndecl, exp); - /* Check read_only, write_only, and read_write arguments. */ + /* Check attribute access arguments. */ maybe_warn_rdwr_sizes (&rdwr_idx, exp); } -- cgit v1.1