-
Notifications
You must be signed in to change notification settings - Fork 24
Fix typedef/variable name conflict parsing error #219
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
base: develop
Are you sure you want to change the base?
Changes from 3 commits
3494d12
98004a6
f9a7b12
d8822cc
160543c
d977be5
363114d
5960536
aa40855
66f8d59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -388,7 +388,7 @@ let transformOffsetOf (speclist, dtype) member = | |
|
|
||
| %type <Cabs.init_name> init_declarator | ||
| %type <Cabs.init_name list> init_declarator_list | ||
| %type <Cabs.name> declarator | ||
| %type <Cabs.name> declarator declarator_init_start | ||
| %type <Cabs.name * expression option> field_decl | ||
| %type <(Cabs.name * expression option) list> field_decl_list | ||
| %type <string * Cabs.decl_type> direct_decl | ||
|
|
@@ -1037,8 +1037,15 @@ init_declarator_attr: | |
| ; | ||
| init_declarator: /* ISO 6.7 */ | ||
| declarator { ($1, NO_INIT) } | ||
| | declarator EQ init_expression location | ||
| { let (n, d, a, l) = $1 in ((n, d, a, joinLoc l $4), $3) } | ||
| | declarator_init_start init_expression location | ||
| { let (n, d, a, l) = $1 in ((n, d, a, joinLoc l $3), $2) } | ||
| ; | ||
|
|
||
| /* (* Parses "declarator =" and adds the declared name as a variable identifier | ||
| in the lexer hack, so that in the initializer the name shadows any typedef | ||
| with the same name (C11 6.2.1.7: scope begins after completion of declarator). *) */ | ||
| declarator_init_start: | ||
| declarator EQ { let (n, _, _, _) = $1 in !Lexerhack.add_identifier n; $1 } | ||
|
Comment on lines
+1053
to
+1065
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not do the lexer hack in
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moving the registration into
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An interesting question here is: where exactly in the C standard is it stated that
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apparently, the grammar doesn't explicitly ban it, but one can get some kind of semantic ban out of
C11 draft as typedefs do not define objects.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still, there's no need for two new grammar rules. The Having Instead, I would expect
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what exactly you suggest here. If you're happy with the rest of it feel free to push directly to this branch. I'll have a look at it and then we can merge. |
||
| ; | ||
|
|
||
| decl_spec_list_common: /* ISO 6.7 */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| /* Test for typedef and variable name conflict (issue #114). | ||
| A variable with the same name as a typedef should shadow it in its initializer, | ||
| per C11 6.2.1.7: "Any other identifier has scope that begins just after the | ||
| completion of its declarator." */ | ||
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
|
|
||
| typedef struct raxNode { | ||
| uint32_t iskey:1; | ||
| uint32_t isnull:1; | ||
| uint32_t iscompr:1; | ||
| uint32_t size:29; | ||
| unsigned char data[]; | ||
| } raxNode; | ||
|
|
||
| typedef struct rax { | ||
| raxNode *head; | ||
| uint64_t numele; | ||
| uint64_t numnodes; | ||
| } rax; | ||
|
|
||
| int main() { | ||
| rax *rax = malloc(sizeof(*rax)); /* variable rax shadows typedef rax in initializer */ | ||
| return rax == 0; | ||
| } | ||
|
michael-schwarz marked this conversation as resolved.
|
||
Uh oh!
There was an error while loading. Please reload this page.