diff options
author | Martin Sebor <msebor@redhat.com> | 2020-06-04 16:06:10 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2020-06-04 16:08:32 -0600 |
commit | b825a22890740f341eae566af27e18e528cd29a7 (patch) | |
tree | b614b6b24e6395784b9eb80af79352ce9bca555f /gcc/calls.c | |
parent | 2cbc99d18dc411ac3fdef94e22ce86859806e63c (diff) | |
download | gcc-b825a22890740f341eae566af27e18e528cd29a7.zip gcc-b825a22890740f341eae566af27e18e528cd29a7.tar.gz gcc-b825a22890740f341eae566af27e18e528cd29a7.tar.bz2 |
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
Diffstat (limited to 'gcc/calls.c')
-rw-r--r-- | gcc/calls.c | 83 |
1 files changed, 11 insertions, 72 deletions
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<int, -1> { }; - -/* A mapping between argument number corresponding to attribute access - mode (read_only, write_only, or read_write) and operands. */ -typedef hash_map<rdwr_access_hash, attr_access> 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<int, attr_access> &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); } |