-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bad code on shared assignment of anon struct #83
Comments
The following 1-line change almost worked:
It adds tags to any unnames structs or unions within any transformed decl. However, I then realized that it cannot help for structures that might appear in system headers. |
AMDG On 03/20/2014 01:26 AM, Paul H. Hargrove wrote:
struct A { struct { int x; } *ptr };
In Christ, |
I /think/ that this problem can only happen for anonymous |
Steven, Thanks for the review.
As you observe in your second comment we are (I agree) only dealing with a struct or union contained within an outer one. So, I suppose it is possible to create a spill with the outer type, though I have no clue how to discover what that type is, and fear building the A.b.c.d.e.f.g expression needed to access its appropriate member. Please note that this problem with assignment was discovered while working on issue #78 by trying to emit calls to sizeof() and offsetof() in lieu of integer literals (in Load, Store and MemberExpr for now, but maybe everywhere eventually). With the use of a spill of the outer type, I believe one can write the sizeof() expression because one can use the field name: sizeof(spill.b). However, offsetof() needs a type name and I don't see a way to get one other than the path I've taken with the current attempt. At this point I feel that I am reaching beyond my abilities in this code base. I am willing to continue work if given some guidance. I can address #1, and will address #2 if somebody reassures me that multiple-transformation is not a problem. However, I simply don't know enough about how Clang's AST Classes work to address any of the other issues. FWIW: I don't see this bug as representing a common usage. |
AMDG On 03/20/2014 10:46 AM, Paul H. Hargrove wrote:
Is casting to void * guaranteed to be safe?
Ah, right. TransformExpr and TransformType should
Checking getAs() != NULL should be enough.
We'd need to create an auxiliary table that maps
Agreed.
I think the most important thing is to work out what
In Christ, |
To respond to Steven's points in the previous comment (but with pruned context):
My recollection is that the standard requires certain classes of pointers be interchangeable, but that there are at least two classes: objects and functions. Since we are talking only about anonymous record types, I am 99% certain that interchangeability w/ void* is required by the standard.
In that case it would be simple to have a bool paramater to the factored function that controlled the hand full of calls to transformedLocalDecl(). Unlike the Transform*() calls they are on lines by themselves, not in inconvenient places like the parameter lists for other calls.
OK. I don't think we reach the current path for a typedef but will add the check if/when I get back to this code. [To reconstruct A.b.c.d to reach a member inside a nested anon struct or union inside a named one]
That is pretty much what I feared.
I'd be relieved to have you take over on this issue. |
Some specification: The inputs:
The result:
Expected usage cases for the new or rewritten type:
The first two cases on that list (sizeof in Load/Store and offsetof in MemberExpr) were already prototyped via new createSizeOf() and createOffsetOf() functions (lines 640 to 659 in https://github.com/PHHargrove/upc2c/blob/issue-78-v2/Transform.cpp ). When implemented, the fourth case would use that same createSizeOf(). So, the new code might have exactly three callers: create{TmpVar,SizeOf,OffsetOf}() |
It may be worth noting again that I tried a variant on that that idea (one-line patch in #83 (comment)) that unconditionally rewrote all records types as they were initially processed, by inserting tags on any that lacked one. The problem with that approach is lack of coverage for structs or unions defined in system headers. Even though clang's AST may now have a tag for the type, the backend compiler won't have it. That still might turn out to be the best approach available, though it just makes the bug "smaller" rather than eliminating it. |
Given this 2-line UPC code:
The translation of baz() looks like:
The problem is the type for the spill:
struct <anonymous struct at newbug.upc:1:12>
Two observations:
q->b
is a lvalue and therefore&(q->b)
would be legal in the communication call.I will be adding this test code to Berkeley test suite shortly.
The text was updated successfully, but these errors were encountered: