Michael Matz <[EMAIL PROTECTED]> writes: >> This program appears to me to be invalid according to C99 6.7.3.1, >> which is the only definition of restrict that we have. >> >> If P is assigned the value of a pointer expression E that is based >> on another restricted pointer object P2, associated with block B2, >> then either the execution of B2 shall begin before the execution >> of B, or the execution of B2 shall end prior to the assignment. >> If these requirements are not met, then the behavior is undefined. >> >> In your program, P is q and P2 is p. Block B and B2 are the same >> block: the only block in foo. It is obviously not the case that the >> block executes before itself. So I believe the assignment "q = p + 1" >> is undefined behaviour. > > But the testcases in the PR can easily be transformed to fulfill this > requirement. E.g.: > > int __attribute__((noinline)) > foo (int *__restrict p, int i) > { > if (1) > { > int *__restrict q = p + 1; > if (1) > { > int *__restrict r = q - i; > int v, w; > v = *r; > *p = 1; > w = *r; > return v + w; > } > } > } > extern void abort (void); > int main() > { > int i = 0; > if (foo (&i, 1) != 1) > abort (); > return 0; > } > > This (and the other testcases similarly changed) still break.
OK, let me quote the whole paragraph: During each execution of B, let L be any lvalue that has &L based on P. If L is used to access the value of the object X that it designates, and X is also modified (by any means), then the following requirements apply: T shall not be const-qualified. Every other lvalue used to access the value of X shall also have its address based on P. Every access that modifies X shall be considered also to modify P, for the purposes of this subclause. If P is assigned the value of a pointer expression E that is based on another restricted pointer object P2, associated with block B2, then either the execution of B2 shall begin before the execution of B, or the execution of B2 shall end prior to the assignment. If these requirements are not met, then the behavior is undefined. The object X is *r. You are accessing the object as *r, so in this paragraph P is r. The paragraph says that every lvalue used to access the object must be based on P, which is r. Your program violates that, because you are accessing it via p, which is not based on r. Your argument is presumably that the value of r is based on p, which it is. But I don't see how that helps. Can you walk through that paragraph in terms of your program and show how it meets the requirements of that paragraph? >> More generally, as I understand the restrict qualifier, it means that >> if two pointers both have the restrict qualifier, and you use one of >> the pointers to modify an object, you may not use the other pointer to >> access that object. > > Can you deduce this from the standard? The standard is very obscure, but the rationale, while not normative, is at least more clear: A translator can assume that a restrict-qualified pointer declared with block scope is, during each execution of the block, the sole initial means of access to an object. So I guess the question is whether the rationale is incorrect in its paraphrasing of the standard. Ian