You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sometimes C code generator fails "forgets" about qualifiers as shown in #431. One such example is mixing _Atomic with const and auto. Consider the following code:
This code would fail as it would generate auto int * _Atomic a; losing const. In particular, the issue is that CGenerator does not print quals for Decl. I.e. the following AST is generated:
An obvious fix is to add quals printing in def _generate_decl(self, n):.
diff --git a/pycparser/c_generator.py b/pycparser/c_generator.py
index ded8c65..5a977e5 100644
--- a/pycparser/c_generator.py+++ b/pycparser/c_generator.py@@ -418,6 +418,7 @@ class CGenerator(object):
s = ''
if n.funcspec: s = ' '.join(n.funcspec) + ' '
if n.storage: s += ' '.join(n.storage) + ' '
+ if n.quals: s += ' '.join(n.quals) + ' '
s += self._generate_type(n.type)
return s
But that route is a bit complicated as it leads to duplicating quals, e.g. _Atomic int x; gives _Atomic _Atomic int x; now. This feels wrong in the source, because I see the _Atomic qualifier is already present twice in the AST in the first place:
However, it is not clear what was the original intention:
To duplicate quals in both Decl and TypeDecl but use Decl for user interaction only for extra verbosity?
To have different notions, with duplicated quals in some places being accidental?
I tried prototyping writing a fix assuming it is (1), but it was not immediately successful as rather many tests started to fail, and the comparison did not work in the first place:
diff --git a/pycparser/ast_transforms.py b/pycparser/ast_transforms.py
index 367dcf5..f4f4786 100644
--- a/pycparser/ast_transforms.py+++ b/pycparser/ast_transforms.py@@ -134,9 +134,16 @@ def fix_atomic_specifiers(decl):
if typ.declname is None:
typ.declname = decl.name
+ return _fix_const_qualifiers(decl)++def _fix_const_qualifiers(decl):+ if isinstance(decl, c_ast.Decl) and decl.quals:+ for qual in decl.quals:+ if qual not in decl.type.quals:+ decl.type.quals.append(qual)+ # decl.quals = []
return decl
The text was updated successfully, but these errors were encountered:
Indeed, this requires deeper investigation/thought. I'm not sure the quals on Decl are necessary, but maybe I'm missing something. In a perfect world there would be no reason for the duplication.
Sometimes C code generator fails "forgets" about qualifiers as shown in #431. One such example is mixing
_Atomic
withconst
andauto
. Consider the following code:This code would fail as it would generate
auto int * _Atomic a;
losingconst
. In particular, the issue is thatCGenerator
does not print quals forDecl
. I.e. the following AST is generated:and then the generator turns it into:
An obvious fix is to add
quals
printing indef _generate_decl(self, n):
.But that route is a bit complicated as it leads to duplicating quals, e.g.
_Atomic int x;
gives_Atomic _Atomic int x;
now. This feels wrong in the source, because I see the_Atomic
qualifier is already present twice in the AST in the first place:However, it is not clear what was the original intention:
Decl
andTypeDecl
but use Decl for user interaction only for extra verbosity?I tried prototyping writing a fix assuming it is (1), but it was not immediately successful as rather many tests started to fail, and the comparison did not work in the first place:
The text was updated successfully, but these errors were encountered: