Skip to content
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

Struct declarations must be defined before non pointer use #124

Open
pattersonz opened this issue Nov 11, 2020 · 1 comment
Open

Struct declarations must be defined before non pointer use #124

pattersonz opened this issue Nov 11, 2020 · 1 comment

Comments

@pattersonz
Copy link
Contributor

Due to where we are placing our forward reference declarations, it's possible for structs to attempt to be used as a type within another struct before they are defined.

typedef struct X509_algor_st X509_ALGOR;
struct X509_algor_st {
    int *algorithm;
    char *parameter;
} ;
typedef struct Netscape_spki_st {
    X509_ALGOR sig_algor;
} NETSCAPE_SPKI;

The above code is a replica of what causes the error in rsa-sign. This is valid code, and is properly parsed by both superC and gcc. The output is the following:

#include <stdbool.h>
extern void __static_type_error(char *msg);
extern void __static_renaming(char *renaming, char *original);
extern void __static_condition_renaming(char *expression, char *renaming);
void __static_initializer_default();
void __static_initializer_default() {
__static_renaming("__X509_ALGOR_1", "X509_ALGOR");
__static_renaming("__NETSCAPE_SPKI_7", "NETSCAPE_SPKI");
};
typedef struct __forward_tag_reference_0  __X509_ALGOR_1;
struct __X509_algor_st_2 {
int  (* __algorithm_3);
char  (* __parameter_4);
};
struct __Netscape_spki_st_5 {
__X509_ALGOR_1  __sig_algor_6;
};
typedef struct __Netscape_spki_st_5  __NETSCAPE_SPKI_7;
struct __forward_tag_reference_0 { // generated union of struct variations                              
union {
struct __X509_algor_st_2 __X509_algor_st_2;
};
};
// typedef moved to top of scope                                                                        
struct __X509_algor_st_2 ;
// typedef moved to top of scope

this gets an error on the line
__X509_ALGOR_1 __sig_algor_6;
in the struct. Specifically it says that it is an incomplete type. The error isn't present if the field is a pointer.

This error can be fixed by moving the struct definition of __forward_tag_reference_0 to immediately after the definition of struct __X509_algor_st_2

@paulgazz
Copy link
Member

There's a subtle ordering going on here that isn't captured completely by the current algorithm. The current one replaces any forward references, e.g., struct X509_algor_st, with a fresh tag. This fresh tag will then contain all members of the struct and be declared later in the scope. In this case, that behavior seems to be interacting with the typedef, since the typedef name (X509_ALGOR) is getting used before this special tag is defined. That causes C's type checker to complain, because it wants to know the size of types without having to look ahead. Pointers to forward references to undefined struct types are okay, because the compiler knows the size of a pointer. In this case it's not a pointer.

Perhaps there is still an algorithm to handle this, where SugarC checks what kind of forward reference is being made to a type, and ensures that it's definition is emitted before the reference. Currently it outputs all the fresh tags after it processes all structs/typedefs in the whole scope. Another option would be to give up on trying to do this in a single pass, or provide some special objects in the desugared output that can be replaced once the whole scope is processed. The latter option might be good anyway, since it is still mostly a single pass. Plus, the desugared output is currently just a string, but by replacing it with objects for tokens/syntax trees, we can preserve more information about the original file right on the desugared output object, e.g., location info, text of predesugared source, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants