pycparser icon indicating copy to clipboard operation
pycparser copied to clipboard

Generator generates incorrect code for 1-line type aliases

Open vlovich opened this issue 7 years ago • 4 comments

The following code gets mis-generated & causes a compiler warning:

struct a {};

union {
        struct a b;
} u, *uu = &u;

becomes

struct a;
union 
{
  struct a b;
} u;
union 
{
  struct a b;
} *uu = & u;

Snippet: import sys from pycparserext.ext_c_parser import GnuCParser as CParser from pycparserext.ext_c_generator import GnuCGenerator as CGenerator

source_parser = CParser()
ast = source_parser.parse(sys.stdin.read())
generator = CGenerator()
print generator.visit(ast)

The problem with this is that if you try to compile this code the compiler will generate a warning that the variable uu is initialized from an incompatible pointer type because we've now generated 2 anonymous union names.

This is probably related (same root cause?) with structure aliases getting their own types too:

typedef struct
{
    int a;
} B, C;

becomes:

typedef struct 
{
  int a;
} B;
typedef struct 
{
  int a;
} C;

which means that B & C are their own types instead of aliases to the same underlying type.

vlovich avatar Jul 01 '17 23:07 vlovich

Thanks for the report; I don't have an objection to fixing this, though it may turn out to be a bit tricky since the parser will create different AST entries.

PRs welcome

eliben avatar Jul 02 '17 16:07 eliben

Are empty structs valid in C99? I thought not, despite many compilers accepting them. For me, pycparserext (I believe correctly) rejects this as a parse error. Not really the core of this issue, but just nitpicking the reproducer. The issue is reproducible without an empty struct:

struct a { int x; };

union {
    struct a b;
} u, *uu = &u;

becomes

struct a
{
  int x;
};
union
{
  struct a b;
} u;
union
{
  struct a b;
} *uu = & u;

In this case you get a valid struct definition, as opposed to the original example that emitted something that looked like a forward declaration of the struct.

Smattr avatar Jul 28 '17 05:07 Smattr

This issue also causes errors when using a named struct in the typedef. For example:

typedef struct MyStruct {
  int a;
} myType, *pMyType;

compiles fine, but once once transformed to

typedef struct MyStruct {
  int a;
} myType;
typedef struct MyStruct {
  int a;
} *pMyType;

causes a compilation error:

error: redefinition of MyStruct

ldore avatar Mar 15 '18 22:03 ldore

I'm a bit confused, as the code piece

typedef struct MyStruct {
  int a;
} myType, *pMyType;

doesn't compile either on my gcc(Apple clang), with command gcc -std=c99, and the error is also redefinition. Thus it's just working perfectly on this named struct example, isn't it?

Nemowang2003 avatar Oct 18 '23 10:10 Nemowang2003