Skip to content

Commit

Permalink
Fix Late Externalization when variable is declared as macro expansion
Browse files Browse the repository at this point in the history
In the case where a variable is declared as a consequence of a macro
expansion, as an example:
```
 #include "lateext-7.h"
 DEFINE_STATIC_KEY_FALSE(aaa);
```
What happens is that when trying to get the FileID of `aaa` it returns
the FileID for the include file rather than the main file.  Hence make
sure it gets the expansion location rather than the spelling location.

Signed-off-by: Giuliano Belinassi <[email protected]>
  • Loading branch information
giulianobelinassi committed Aug 21, 2024
1 parent 733a1a2 commit c69e9ff
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 2 deletions.
19 changes: 19 additions & 0 deletions libcextract/LLVMMisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,25 @@ Decl *Get_Bodyless_Or_Itself(Decl *decl)
return bodyless ? bodyless : decl;
}

DeclaratorDecl *Get_With_Body(DeclaratorDecl *decl)
{
if (FunctionDecl *fdecl = dyn_cast<FunctionDecl>(decl)) {
return fdecl->getDefinition();
}

if (VarDecl *vdecl = dyn_cast<VarDecl>(decl)) {
return vdecl->getDefinition();
}

return nullptr;
}

DeclaratorDecl *Get_With_Body_Or_Itself(DeclaratorDecl *decl)
{
DeclaratorDecl *with_body = Get_With_Body(decl);
return with_body ? with_body : decl;
}

/* Get the TopLevel Decl that contains the location loc. */
Decl *Get_Toplevel_Decl_At_Location(ASTUnit *ast, const SourceLocation &loc)
{
Expand Down
6 changes: 6 additions & 0 deletions libcextract/LLVMMisc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ FunctionDecl *Get_Bodyless_Or_Itself(FunctionDecl *decl);
TagDecl *Get_Bodyless_Or_Itself(TagDecl *decl);
Decl *Get_Bodyless_Or_Itself(Decl *decl);

/** Get version of declarator with body. */
DeclaratorDecl *Get_With_Body(DeclaratorDecl *decl);

/** Get version of declarator with body or itself. */
DeclaratorDecl *Get_With_Body_Or_Itself(DeclaratorDecl *decl);

/* Get the TopLevel Decl that contains the location loc. */
Decl *Get_Toplevel_Decl_At_Location(ASTUnit *ast, const SourceLocation &loc);

Expand Down
6 changes: 4 additions & 2 deletions libcextract/SymbolExternalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -977,9 +977,11 @@ void SymbolExternalizer::Late_Externalize(void)
SE.Insert_Text(sym->LateInsertLocation, outstr.str());

/* In case the symbol is in the main file already, we must delete it. */
SourceLocation loc = sm.getExpansionLoc(sym->OldDecl->getBeginLoc());
DeclaratorDecl *old_decl = Get_With_Body_Or_Itself(sym->OldDecl);

SourceLocation loc = sm.getExpansionLoc(old_decl->getBeginLoc());
if (sm.getFileID(loc) == sm.getMainFileID()) {
SE.Remove_Text(sym->OldDecl->getSourceRange(), 1000);
SE.Remove_Text(old_decl->getSourceRange(), 1000);
}
} else {
/* Fallback to the old method of rewriting the declaration. */
Expand Down
13 changes: 13 additions & 0 deletions testsuite/lateext/lateext-7.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_LATE_EXTERNALIZE -DCE_EXPORT_SYMBOLS=aaa -DCE_KEEP_INCLUDES" }*/

#include "lateext-7.h"

DEFINE_STATIC_KEY_FALSE(aaa);

int f(void)
{
return aaa.key;
}

/* { dg-final { scan-tree-dump-not "DEFINE_STATIC_KEY_FALSE\(\*klpe_aaa\)" } } */
/* { dg-final { scan-tree-dump "static struct AA \*klpe_aaa;" } } */
13 changes: 13 additions & 0 deletions testsuite/lateext/lateext-7.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
struct AA {
int key;
};

int g(void);

extern struct AA aaa;

#define STATIC_KEY_FALSE_INIT (struct AA){ .key = 0, }

#define DEFINE_STATIC_KEY_FALSE(name) \
struct AA name = STATIC_KEY_FALSE_INIT

0 comments on commit c69e9ff

Please sign in to comment.