Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug
Bug#: 10138
Product:  
Component:  
Status: NEW
Resolution:
Assigned To: Not yet assigned to anyone <unassigned@gcc.gnu.org>
Host:
Reported against  
Priority:  
Severity:  
Target Milestone:  
 
 
Target:
Reporter: Hallvard B Furuseth <h.b.furuseth@usit.uio.no>
Add CC:
CC:
Remove selected CCs
Build:
URL:
Summary:
Keywords:
Known to work:
Known to fail:

Attachment Description Type Created Size Actions
10138.c reduced testcase with one extra case text/plain 2003-05-24 14:37 93 bytes Edit
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 10138 depends on: 27120 33086 Show dependency tree
Show dependency graph
Bug 10138 blocks: 24639

Additional Comments:





Mark bug as waiting for feedback
Mark bug as suspended




View Bug Activity   |   Format For Printing   |   Clone This Bug


Description:   Last confirmed: 2008-03-30 20:45 Opened: 2003-03-18 17:46
	A pointer to const parameter is almost always an input parameter
	to a function, so -Wuninitialized could warn if it has not been
	initialized.  (The function could cast away const on the parameter,
	but I've never seen the parameter being modified afterwards.)

Release:
3.2

Environment:
System: SunOS bombur.uio.no 5.8 Generic_108528-13 sun4u sparc SUNW,Ultra-5_10
Architecture: sun4

	
host: sparc-sun-solaris2.8
build: sparc-sun-solaris2.8
target: sparc-sun-solaris2.8
configured with: ../gcc-3.2/configure --prefix=/usit/bombur/hbf --enable-threads --enable-version-specific-runtime-libs --enable-languages=c

How-To-Repeat:
	gcc -Wuninitialized -O -S a.c

	int atoi(const char *);
	int foo()
	{
	    char buf[10];
	    return atoi(buf);
	}

------- Comment #1 From Andrew Pinski 2003-05-24 14:37 -------
Created an attachment (id=4065) [edit]
reduced testcase with one extra case

------- Comment #2 From Andrew Pinski 2003-05-24 14:40 -------
confirmed on mainline (20030524). Change title to reflect real bug.
Added another case to the testcases.
gcc should warn about buf in foo and a in g when -Wuninitialized is on.

------- Comment #3 From Hallvard B Furuseth 2003-05-26 16:38 -------
Subject: Re: [Bug other/10138] -Wuninitialized could catch uninitialized arrays

pinskia@physics.uc.edu writes:

> Change title to reflect real bug.

Oops, I have reported several suggestions which should be split up:

1) It could report use of uninitialized arrays as you say,

2) it could report pointers to uninitialized variables passed
   as const* arguments - as I said, that's almost always an error:

   void use(const int *);

   void foo(void)
   {
       int i;
       use(&i);
   }

3) Finally it could report the combination, as in my original example.


------- Comment #4 From Andrew Pinski 2003-05-26 16:48 -------
The second suggestion is already a different bug, and that is why I just
changed it to this 
one(see bug 179).

------- Comment #5 From Hallvard B Furuseth 2003-05-26 19:05 -------
Subject: Re: [Bug other/10138] -Wuninitialized could catch uninitialized arrays

pinskia@physics.uc.edu writes:

> The second suggestion is already a different bug, and that is why I
> just changed it to this one(see bug 179).

No, bug 179 is a another bug, where - use(&i) would actually prevent
a preceding -Wuninitialized warning.  What I'd like is for use(&i)
itself to give a warning.


------- Comment #6 From Andrew Pinski 2004-06-08 19:39 -------
*** Bug 15880 has been marked as a duplicate of this bug. ***

------- Comment #7 From Andrew Pinski 2004-09-07 16:57 -------
Actually in both cases in this report we don't know if it is really used as an
input parameter at all so this 
is invalid (even though there is a cast but still).

------- Comment #8 From Wolfgang Bangerth 2004-09-07 22:41 -------
I disagree -- the question whether an argument is actually used or not is
secondary, 
the fact that we pass an uninitialized variable to which only read access is
possible 
is definitely worth a warning. 

W. 

------- Comment #9 From Manuel López-Ibáñez 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.

------- Comment #10 From Manuel López-Ibáñez 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"...

------- Comment #11 From Wolfgang Bangerth 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.

------- Comment #12 From Manuel López-Ibáñez 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?

------- Comment #13 From Manuel López-Ibáñez 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.

------- Comment #14 From Wolfgang Bangerth 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.

------- Comment #15 From Manuel López-Ibáñez 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 <cstdio>
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).

------- Comment #16 From Wolfgang Bangerth 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 <cstdio>

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.

------- Comment #17 From Manuel López-Ibáñez 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.

------- Comment #18 From Manuel López-Ibáñez 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.

------- Comment #19 From Wolfgang Bangerth 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 

------- Comment #20 From Manuel López-Ibáñez 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.

------- Comment #21 From gdr@cs.tamu.edu 2007-08-20 18:50 -------
Subject: Re:  warn for uninitialized arrays passed as const* arguments

"manu at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> 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

------- Comment #22 From Hallvard B Furuseth 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.

------- Comment #23 From Matt Hargett 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.

Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug