This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] pthread_cleanup_push macro generates warning when -Wclobbered is set


On Wed, 2017-11-22 at 13:12 +0100, Florian Weimer wrote:
> On 11/21/2017 11:28 PM, Paul Eggert wrote:
> > On 11/21/2017 03:00 AM, Florian Weimer wrote:
> >>
> >> I think the standard assumes that storage for all local variables is 
> >> allocated when the function is entered (or when a scope is entered 
> >> with which contains a variable of variably modified type).  This is 
> >> certainly an odd requirement.
> > 
> > It would be an odd requirement, and I don't see such a requirement in 
> > the standard. C11 section 6.8.2 says that a compound statement { ... } 
> > is a block, and section 6.2.4 paragraph 6 says that an auto object's 
> > lifetime is from block entry until execution of that block ends in any 
> > way. In this case, the block's execution ends each time through the 
> > loop, so the variables in question do not survive from one loop 
> > iteration to the next.
> 
> I'm deriving this from the wording for longjmp:
> 
> “
> […] if the function containing the invocation of the  setjmp macro has 
> terminated execution in the interim, or if the invocation of the setjmp 
> macro was within the scope of an identifier with variably modified type 
> and execution has left that scope in the interim, the behavior is undefined.
> ”
> 
> I read that it's permitted to jump into a scope which has ceased to exist.

It doesn't say that this would be allowed.  Even if it is, then which
objects still exist is a different question.

> And further on:
> 

The first part of this paragraph is:
"All accessible objects have values, and all other components of the
abstract machine 249)
have state, as of the time the longjmp function was called,"

"var" in the example below has per-loop-iteration lifetime, so the state
of objects of earlier iterations than the longjmp call is that they
don't exist anymore.

> “
> except that the values of objects of automatic storage duration that are 
> local to the function containing the invocation of the corresponding 
> setjmp macro that do not have volatile-qualified type and have been 
> changed between the setjmp invocation and longjmp call are
> indeterminate.
> ”
> 
> Note: The object values become indeterminate, which means that the 
> objects themselves still exist.

*Iff* it is valid to access them, they will have an indeterminate value.
IOW, longjmp may or may not restore the values of these particular
objects (if they are still accessible, anyways).

> This implies to me that if you longjmp into a body of a loop like this:
> 
>     while (true)
>       {
>         int var;
>         …  // setjmp and longjmp here
>       }
> 
> then var has the same address as when the setjmp call occurred,

var is not one object, it's multiple ones.  That's what Paul is saying
too.

> even if 
> it happened in a different iteration of the loop.  This makes all kinds 
> of optimizations invalid, of course.
> 
> Furthermore, with a volatile qualifier
> 
>     while (true)
>       {
>         volatile int var;
>         …  // setjmp and longjmp here
>       }
> 
> even the value is preserved.

The value is not preserved, but is as of right before the call to
longjmp (see the first part of the paragraph, which I cited).  IOW,
longjmp will never restore volatile-qualified objects that are still
allowed to be accessed.
But in the example, there are still several "var" objects.

This example would be different:

void bla()
{
  volatile int var = 1;
  while (true) { /* setjmp/longjmp*/ }
  foo = var;
}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]