Skip to content

Commit

Permalink
Check the TagDecl in TypedefNameDecl for extra attributes
Browse files Browse the repository at this point in the history
Some typedef definitions have attributes that are applied to the
TagDecl it defines to. For example:
```
typedef union {
  struct sockaddr *__restrict __sockaddr__;
} __SOCKADDR_ARG __attribute__((__transparent_union__));

```

Here, __attribute__((__transparent_union__)) is applied to the union,
not the typedef. Hence we also need to search for the TagDecl (the
union in this case) for the extra attributes.

Signed-off-by: Giuliano Belinassi <[email protected]>
  • Loading branch information
giulianobelinassi committed Jul 8, 2024
1 parent 9a3c295 commit ecb30ae
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
13 changes: 13 additions & 0 deletions libcextract/PrettyPrint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,19 @@ SourceLocation PrettyPrint::Get_Expanded_Loc(Decl *decl)
}
}
}

/* In case this decl is a TypedefNameDecl, we also need to check for the
struct definition for extra attributes. See small/attr-10.c testscase
for an example where this happens. */
if (TypedefNameDecl *typedecl = dyn_cast<TypedefNameDecl>(decl)) {
if (TagDecl *tag = typedecl->getAnonDeclWithTypedefName()) {
SourceLocation tag_furthest = PrettyPrint::Get_Expanded_Loc(tag);
if (Is_Before(furthest, tag_furthest)) {
furthest = tag_furthest;
}
}
}

return furthest;
}

Expand Down
29 changes: 29 additions & 0 deletions testsuite/small/attr-10.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* { dg-options "-DCE_EXTRACT_FUNCTIONS=main -DCE_NO_EXTERNALIZATION" }*/

typedef unsigned short int sa_family_t;
typedef unsigned int __socklen_t;
typedef __socklen_t socklen_t;
typedef int ares_socket_t;
typedef socklen_t ares_socklen_t;

struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
};

typedef union {
struct sockaddr *__restrict __sockaddr__;
} __SOCKADDR_ARG __attribute__((__transparent_union__));

extern int getsockname(int __fd, __SOCKADDR_ARG __addr,
socklen_t *__restrict __len)
__attribute__((__nothrow__));

int main(void) {
struct sockaddr *src_addr;
ares_socket_t sock;
ares_socklen_t len;
getsockname(sock, src_addr, &len);
}

/* { dg-final { scan-tree-dump "__attribute__\(\(__transparent_union__\)\)" } } */

0 comments on commit ecb30ae

Please sign in to comment.