diff options
author | Vitaly Cheptsov <4348897+vit9696@users.noreply.github.com> | 2021-10-04 16:20:47 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-04 06:20:47 -0700 |
commit | 14ffe7bc486805c568403757d8634211f8458451 (patch) | |
tree | 991da5b6498df6bd37d1bc855dbf325c33f96ad4 /tests | |
parent | 007e79e5ba45d3f3c4325578a91f7786a7b88cfb (diff) | |
download | pycparser-14ffe7bc486805c568403757d8634211f8458451.tar.gz |
Implement _Alignas and _Alignof support with tests (#435)
* Implement _Alignas and _Alignof support with tests
* Improve testing and avoid unnecessary alignas for typedef
* Add more tests
* Drop legacy artifact
* Remove extra _add_declaration_specifier call
* Drop custom equality comparators for now
Co-authored-by: vit9696 <vit9696@users.noreply.github.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/c_files/c11.c | 6 | ||||
-rw-r--r-- | tests/test_c_generator.py | 21 | ||||
-rw-r--r-- | tests/test_c_lexer.py | 1 | ||||
-rwxr-xr-x | tests/test_c_parser.py | 34 |
4 files changed, 59 insertions, 3 deletions
diff --git a/tests/c_files/c11.c b/tests/c_files/c11.c index 3c57f55..4f97a87 100644 --- a/tests/c_files/c11.c +++ b/tests/c_files/c11.c @@ -4,6 +4,7 @@ #include <threads.h> #include <assert.h> #include <stdatomic.h> +#include <stdalign.h> /* C11 thread locals */ _Thread_local int flag; @@ -12,6 +13,9 @@ _Atomic int flag3; _Atomic(int) flag4; _Atomic(_Atomic(int) *) flag5; atomic_bool flag6; +_Alignas(32) int q32; +_Alignas(long long) int qll; +alignas(64) int qqq; static_assert(sizeof(flag) == sizeof(flag2), "Really unexpected size difference"); @@ -31,6 +35,8 @@ int main() static_assert(sizeof(flag) == sizeof(flag2), "Unexpected size difference"); static_assert(sizeof(flag) == sizeof(flag3), "Unexpected size difference"); static_assert(sizeof(flag) == sizeof(flag4), "Unexpected size difference"); + static_assert(_Alignof(int) == sizeof(int), "Unexpected int alignment"); + static_assert(alignof(int) == sizeof(int), "Unexpected int alignment"); printf("Flag: %d\n", flag); printf("Flag2: %d\n", flag2); diff --git a/tests/test_c_generator.py b/tests/test_c_generator.py index fb9499a..2095e63 100644 --- a/tests/test_c_generator.py +++ b/tests/test_c_generator.py @@ -96,6 +96,27 @@ class TestCtoC(unittest.TestCase): self._assert_ctoc_correct('int test(const char* const* arg);') self._assert_ctoc_correct('int test(const char** const arg);') + # FIXME: These require custom equality comparison. + # def test_alignment(self): + # self._assert_ctoc_correct('_Alignas(32) int b;') + # self._assert_ctoc_correct('int _Alignas(32) a;') + # self._assert_ctoc_correct('_Alignas(32) _Atomic(int) b;') + # self._assert_ctoc_correct('_Atomic(int) _Alignas(32) b;') + # self._assert_ctoc_correct('_Alignas(long long) int a;') + # self._assert_ctoc_correct('int _Alignas(long long) a;') + # self._assert_ctoc_correct(r''' + # typedef struct node_t { + # _Alignas(64) void* next; + # int data; + # } node; + # ''') + # self._assert_ctoc_correct(r''' + # typedef struct node_t { + # void _Alignas(64) * next; + # int data; + # } node; + # ''') + def test_ternary(self): self._assert_ctoc_correct(''' int main(void) diff --git a/tests/test_c_lexer.py b/tests/test_c_lexer.py index e446434..1d3c39b 100644 --- a/tests/test_c_lexer.py +++ b/tests/test_c_lexer.py @@ -94,6 +94,7 @@ class TestCLexerNoErrors(unittest.TestCase): def test_new_keywords(self): self.assertTokensTypes('_Bool', ['_BOOL']) self.assertTokensTypes('_Atomic', ['_ATOMIC']) + self.assertTokensTypes('_Alignas _Alignof', ['_ALIGNAS', '_ALIGNOF']) def test_floating_constants(self): self.assertTokensTypes('1.5f', ['FLOAT_CONST']) diff --git a/tests/test_c_parser.py b/tests/test_c_parser.py index 7e6a648..5b9d916 100755 --- a/tests/test_c_parser.py +++ b/tests/test_c_parser.py @@ -40,16 +40,21 @@ def expand_decl(decl): assert isinstance(decl.values, EnumeratorList) values = [enum.name for enum in decl.values.enumerators] return ['Enum', decl.name, values] + elif typ == Alignas: + return ['Alignas', expand_init(decl.alignment)] elif typ == StaticAssert: return ['StaticAssert', decl.cond.value, decl.message.value] else: nested = expand_decl(decl.type) if typ == Decl: + r = ['Decl'] if decl.quals: - return ['Decl', decl.quals, decl.name, nested] - else: - return ['Decl', decl.name, nested] + r.append(decl.quals) + if decl.align: + r.append(expand_decl(decl.align[0])) + r.extend([decl.name, nested]) + return r elif typ == Typename: # for function parameters if decl.quals: return ['Typename', decl.quals, nested] @@ -98,6 +103,8 @@ def expand_init(init): if init.block_items: blocks = [expand_init(i) for i in init.block_items] return ['Compound', blocks] + elif typ == Typename: + return expand_decl(init) else: # Fallback to type name return [typ.__name__] @@ -618,6 +625,27 @@ class TestCParser_fundamentals(TestCParser_base): ['TypeDecl', ['IdentifierType', ['int']]]]]]) + def test_alignof(self): + r = self.parse('int a = _Alignof(int);') + self.assertEqual(expand_decl(r.ext[0]), ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]]) + self.assertEqual(expand_init(r.ext[0].init), ['UnaryOp', '_Alignof', + ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]]) + + self.assertEqual(expand_decl(self.parse('_Alignas(_Alignof(int)) char a;').ext[0]), + ['Decl', ['Alignas', + ['UnaryOp', '_Alignof', ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]]], + 'a', ['TypeDecl', ['IdentifierType', ['char']]]]) + + self.assertEqual(expand_decl(self.parse('_Alignas(4) char a;').ext[0]), + ['Decl', ['Alignas', + ['Constant', 'int', '4']], + 'a', ['TypeDecl', ['IdentifierType', ['char']]]]) + + self.assertEqual(expand_decl(self.parse('_Alignas(int) char a;').ext[0]), + ['Decl', ['Alignas', + ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]], + 'a', ['TypeDecl', ['IdentifierType', ['char']]]]) + def test_offsetof(self): def expand_ref(n): if isinstance(n, StructRef): |