From 67f545dd27c00e73545ec34169bcb866d47020c5 Mon Sep 17 00:00:00 2001 From: Zecong Hu Date: Tue, 3 Mar 2020 09:33:11 -0500 Subject: Fix #363 incorrect AST when parsing offsetof (#364) --- pycparser/c_parser.py | 3 +-- tests/test_c_parser.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/pycparser/c_parser.py b/pycparser/c_parser.py index 4cf96fa..744ede8 100644 --- a/pycparser/c_parser.py +++ b/pycparser/c_parser.py @@ -1740,8 +1740,7 @@ class CParser(PLYParser): if len(p) == 2: p[0] = p[1] elif len(p) == 4: - field = c_ast.ID(p[3], self._token_coord(p, 3)) - p[0] = c_ast.StructRef(p[1], p[2], field, p[1].coord) + p[0] = c_ast.StructRef(p[1], p[2], p[3], p[1].coord) elif len(p) == 5: p[0] = c_ast.ArrayRef(p[1], p[3], p[1].coord) else: diff --git a/tests/test_c_parser.py b/tests/test_c_parser.py index 49cada3..b6ecdd5 100755 --- a/tests/test_c_parser.py +++ b/tests/test_c_parser.py @@ -529,6 +529,18 @@ class TestCParser_fundamentals(TestCParser_base): ['IdentifierType', ['int']]]]]]) def test_offsetof(self): + def expand_ref(n): + if isinstance(n, StructRef): + return ['StructRef', expand_ref(n.name), expand_ref(n.field)] + elif isinstance(n, ArrayRef): + return ['ArrayRef', expand_ref(n.name), expand_ref(n.subscript)] + elif isinstance(n, ID): + return ['ID', n.name] + elif isinstance(n, Constant): + return ['Constant', n.type, n.value] + else: + raise TypeError("Unexpected type " + n.__class__.__name__) + e = """ void foo() { int a = offsetof(struct S, p); @@ -546,8 +558,20 @@ class TestCParser_fundamentals(TestCParser_base): self.assertIsInstance(s1.args.exprs[1], ID) s3 = compound.block_items[2].init self.assertIsInstance(s3.args.exprs[1], StructRef) + self.assertEqual(expand_ref(s3.args.exprs[1]), + ['StructRef', + ['StructRef', ['ID', 'p'], ['ID', 'q']], + ['ID', 'r']]) s4 = compound.block_items[3].init self.assertIsInstance(s4.args.exprs[1], ArrayRef) + self.assertEqual(expand_ref(s4.args.exprs[1]), + ['ArrayRef', + ['ArrayRef', + ['StructRef', + ['ArrayRef', ['ID', 'p'], ['Constant', 'int', '5']], + ['ID', 'q']], + ['Constant', 'int', '4']], + ['Constant', 'int', '5']]) def test_compound_statement(self): e = """ -- cgit v1.2.3