[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 Martin Sebor changed: What|Removed |Added Resolution|--- |FIXED Status|ASSIGNED|RESOLVED --- Comment #31 from Martin Sebor --- Done for GCC 11.
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 --- Comment #30 from CVS Commits --- The master branch has been updated by Martin Sebor : https://gcc.gnu.org/g:b825a22890740f341eae566af27e18e528cd29a7 commit r11-959-gb825a22890740f341eae566af27e18e528cd29a7 Author: Martin Sebor Date: Thu Jun 4 16:06:10 2020 -0600 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
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 Martin Sebor changed: What|Removed |Added Keywords||patch Last reconfirmed|2008-03-30 20:45:14 |2020-5-15 Target Milestone|--- |11.0 --- Comment #29 from Martin Sebor --- Patch: https://gcc.gnu.org/pipermail/gcc-patches/2020-May/545856.html
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 Martin Sebor changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot gnu.org --- Comment #28 from Martin Sebor --- The patch I developed for pr80806 introduces the read_only and read_write attributes that both enable this warning and also make optimizations possible: $ cat pr10138.c && gcc -O -S -Wall pr10138.c __attribute__ ((read_only)) int atoi (const char *); int foo() { char buf[10]; return atoi (buf); } pr10138.c: In function ‘foo’: pr10138.c:6:10: warning: ‘buf’ is used uninitialized in this function [-Wuninitialized] 6 | return atoi (buf); | ^~ For read-only functions like atoi it would be easy to issue the warning even in the absence of the attribute. There's some potential for false positives, such as in C++ and mutable members, but I expect those would be rare and more than offset by the bugs the warning would find. Let me see about it.
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 Bug 10138 depends on bug 33086, which changed state. Bug 33086 Summary: warn for read-only uninitialized variables passed as arguments https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33086 What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |DUPLICATE
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 --- Comment #27 from Martin Sebor --- *** Bug 33086 has been marked as a duplicate of this bug. ***
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 --- Comment #26 from Martin Sebor --- It seems that it should be possible to enhance the warn_uninitialized_vars function in tree-ssa-uninit.c to detect this case by iterating over a callee's arguments and warn on uninitialized variables whose address is passed to it via a const pointer parameter.
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 Martin Sebor changed: What|Removed |Added CC||msebor at gcc dot gnu.org --- Comment #25 from Martin Sebor --- *** Bug 70987 has been marked as a duplicate of this bug. ***
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 Manuel López-Ibáñez changed: What|Removed |Added CC||developm...@faf-ltd.com --- Comment #24 from Manuel López-Ibáñez --- *** Bug 69925 has been marked as a duplicate of this bug. ***
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138 Bug 10138 depends on bug 27120, which changed state. Bug 27120 Summary: Should warn about uninitialized use of variable array element https://gcc.gnu.org/bugzilla/show_bug.cgi?id=27120 What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #23 from matt at use dot net 2009-12-31 01:44 --- I just ran into a bug that this feature would have found for me at compile-time. Instead, it required exercising the code under valgrind, which took quite some time. If voting were enabled, I would vote for this bug. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #22 from h dot b dot furuseth at usit dot uio dot no 2007-08-20 22:45 --- Subject: Re: warn for uninitialized arrays passed as const* arguments manu at gcc dot gnu dot org writes: > But it seems that the current policy of GCC is to not assume that such > functions actually take this into account, since when optimizing > constants are not propagated beyond a call to such function. This is > either the intended behaviour or a missed-optimisation. > It would be nice if it would be a missed-optimisation. A "const" in a function parameter in C is not a promise to the compiler; it would break the C standard to optimize on it. > Otherwise, if this > is the intended behaviour, then both PRs are invalid as Andrew said. They are requests for warning messages, not error messages, because they are _likely_ to be programmer errors. That's what warnings are for. -Wuninitialized is giving false positives anyway, on code which the compiler cannot tell is correct but the programmer can. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #21 from gdr at cs dot tamu dot edu 2007-08-20 18:50 --- Subject: Re: warn for uninitialized arrays passed as const* arguments "manu at gcc dot gnu dot org" <[EMAIL PROTECTED]> writes: | When I say "constant are not propagated" I mean "the constant value of a | variable" such as: | | int i=0; | use(&i); | foo(i); | | Here, GCC does not propagate the value of i to do foo(0). Remove the call to | use and then it will. Which is all it can do, assuming the body is not "available". -- Gaby -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #20 from manu at gcc dot gnu dot org 2007-08-20 17:12 --- (In reply to comment #19) > > What if you had "const int i=0"? As I said before, use() may do a const-cast > to get rid of the constness of its argument, but the result is only > well-defined > if the object pointed to is actually non-const. That is the case here, so > use() > may do exactly this and clobber 'i'. On the other hand, if 'i' was const, then > the result of any const-cast use() may do on its argument are undefined, and > it would seem legitimate to propagate the initial value of 'i' into the call > to foo(). > Wolfgang, I understand perfectly what you explain. Yet, from the point of view of Wuninitialized, only local non-const objects are interesting. And it seems that for those, GCC does not assume that the function is not going to modify the object. Thus, it doesn't make much sense for Wuninitialized to assume it. And, from a technical point of view, it would be difficult to maintain such dichotomy, since Wuninitialized relies on the SSA representation and the work of the optimisation passes. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #19 from bangerth at dealii dot org 2007-08-20 16:58 --- (In reply to comment #18) > When I say "constant are not propagated" I mean "the constant value of a > variable" such as: > > int i=0; > use(&i); > foo(i); > > Here, GCC does not propagate the value of i to do foo(0). Remove the call to > use and then it will. What if you had "const int i=0"? As I said before, use() may do a const-cast to get rid of the constness of its argument, but the result is only well-defined if the object pointed to is actually non-const. That is the case here, so use() may do exactly this and clobber 'i'. On the other hand, if 'i' was const, then the result of any const-cast use() may do on its argument are undefined, and it would seem legitimate to propagate the initial value of 'i' into the call to foo(). W. I think that in -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #18 from manu at gcc dot gnu dot org 2007-08-20 16:46 --- When I say "constant are not propagated" I mean "the constant value of a variable" such as: int i=0; use(&i); foo(i); Here, GCC does not propagate the value of i to do foo(0). Remove the call to use and then it will. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #17 from manu at gcc dot gnu dot org 2007-08-20 16:44 --- (In reply to comment #16) > (In reply to comment #15) > > > Of course, the output is '5' and not '0'. So yes, atoi() seems perfectly > > able > > to initialize buf. (or perhaps, I am still confused). > > Since use() (like atoi) can't know whether its argument is a local automatic > or a global variable, there is no way for it to reliably initialize its > argument. Casting away constness invokes undefined behavior if the static > type of the object is const. But it seems that the current policy of GCC is to not assume that such functions actually take this into account, since when optimizing constants are not propagated beyond a call to such function. This is either the intended behaviour or a missed-optimisation. It would be nice if it would be a missed-optimisation. Fixing that will probably fix PR33086 and help to fix this one. Otherwise, if this is the intended behaviour, then both PRs are invalid as Andrew said. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #16 from bangerth at dealii dot org 2007-08-20 16:21 --- (In reply to comment #15) > Of course, the output is '5' and not '0'. So yes, atoi() seems perfectly able > to initialize buf. (or perhaps, I am still confused). I think you are. This program here segfaults: - #include const int i=0; void use(const int *a) { int * b = (int *)a; b[0] = 5; } int main(void) { use(&i); printf("%d\n", i); return 0; } Since use() (like atoi) can't know whether its argument is a local automatic or a global variable, there is no way for it to reliably initialize its argument. Casting away constness invokes undefined behavior if the static type of the object is const. W. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #15 from manu at gcc dot gnu dot org 2007-08-20 16:15 --- (In reply to comment #14) > This is meant to only counter your point that: > > 'const' does not mean read-only in C++ at all, and much less in C. > > atoi(const > > char *) could always initialize buf[]. > This simply isn't true. In C++, atoi can't do that. > Please, take a look at the example given by Andrew http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33086#c3. I can compile and run a similar example: #include void use(const int *a) { int * b = (int *)a; b[0] = 5; } int main(void) { int i=0; use(&i); printf("%d\n", i); return 0; } Of course, the output is '5' and not '0'. So yes, atoi() seems perfectly able to initialize buf. (or perhaps, I am still confused). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #14 from bangerth at dealii dot org 2007-08-20 15:54 --- (In reply to comment #12) > This testcase has nothing to do with uninitialized variables. No, of course. I only meant to reply to your assertion that there could be cases where a function initializes an object that is passed as a const pointer. That may work in C, but not in C++. I agree that my example may have been confusing, so take this slight variant of it ('a' is here non-const and uninitialized): --- char a[3]; int main () { return atoi (a); } --- It is my understanding that C++ allows 'a' to be put into read-only memory because the only access is read-only. What that means is that functions like atoi that take constant arguments have no legitimate way to initialize the objects they get, and every uninitialized object passed to them is necessarily a source of bugs. This is meant to only counter your point that: > 'const' does not mean read-only in C++ at all, and much less in C. atoi(const > char *) could always initialize buf[]. This simply isn't true. In C++, atoi can't do that. W. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #13 from manu at gcc dot gnu dot org 2007-08-20 15:08 --- (In reply to comment #12) > > This testcase has nothing to do with uninitialized variables. If the variable > is 'const' already, then there will never be a warning. Will it produce > segmentation fault for a local automatic uninitialized pointer? > Of course, I mean pointer to (or array of, in this case) uninitialized data, not that the pointer itself is uninitialized. Sorry for the confusion. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #12 from manu at gcc dot gnu dot org 2007-08-20 15:03 --- (In reply to comment #11) > (In reply to comment #10) > > I now think that Andrew is right and that PR33086 and this one are INVALID. > > 'const' does not mean read-only in C++ at all, and much less in C. > > atoi(const > > char *) could always initialize buf[]. > > Uh, no, it can't. If it did (by casting away the 'const' from its argument > and then writing into the array), this would lead to a segfault: > - > const char a[3] = "10"; > int main () { > return atoi (a); > } > - This testcase has nothing to do with uninitialized variables. If the variable is 'const' already, then there will never be a warning. Will it produce segmentation fault for a local automatic uninitialized pointer? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #11 from bangerth at dealii dot org 2007-08-20 14:56 --- (In reply to comment #10) > I now think that Andrew is right and that PR33086 and this one are INVALID. > 'const' does not mean read-only in C++ at all, and much less in C. atoi(const > char *) could always initialize buf[]. Uh, no, it can't. If it did (by casting away the 'const' from its argument and then writing into the array), this would lead to a segfault: - const char a[3] = "10"; int main () { return atoi (a); } - The reason being that compilers will typically place 'a' into a read-only memory section. Passing an uninitialized object as a const reference or pointer is a bad idea in C++ and should get a warning as a rule. I can't see reasons that would warrant exceptions from this rule. W. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #10 from manu at gcc dot gnu dot org 2007-08-20 14:49 --- I now think that Andrew is right and that PR33086 and this one are INVALID. 'const' does not mean read-only in C++ at all, and much less in C. atoi(const char *) could always initialize buf[]. However, perhaps it can apply to functions marked as "pure"... -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138
[Bug middle-end/10138] warn for uninitialized arrays passed as const* arguments
--- Comment #9 from manu at gcc dot gnu dot org 2007-08-16 10:57 --- Let's simplify this report. This one is now about int atoi(const char *); int foo() { char buf[10]; return atoi(buf); } As comment #3 mentions, this is a combination of 1) Report use of uninitialized array elements (PR27120). 2) Report pointers to uninitialized variables passed as const* arguments (PR33086). I guess that if we achieve both things, we will have a chance to achieve this one. In other words, both PRs are blocking this one. -- manu at gcc dot gnu dot org changed: What|Removed |Added CC||manu at gcc dot gnu dot org BugsThisDependsOn||27120 OtherBugsDependingO|27120 | nThis|| Summary|-Wuninitialized could catch |warn for uninitialized |uninitialized arrays|arrays passed as const* ||arguments http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10138