Skip to content

Commit

Permalink
Fixed #333: Check for valid SourceLocation of attributes.
Browse files Browse the repository at this point in the history
Functions like `operator new` and `operator delete` carry a hidden
attribute `__attribute__((visibility("default")))` which has no valid
`SourceLocation` as it is inherited from the STL. This patch adds code
to use only a valid `SourceLocation` to apply the offset to it to get
the replacement range of the `FunctionDecl`.
  • Loading branch information
andreasfertig committed Jul 26, 2020
1 parent 3d964b4 commit 2b9be10
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
10 changes: 8 additions & 2 deletions FunctionDeclHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,14 @@ void FunctionDeclHandler::run(const MatchFinder::MatchResult& result)

// Adjust the begin location, if this decl has an attribute
if(funcDecl->hasAttrs()) {
// the -3 are a guess that seems to work
funcRange.setBegin((*funcDecl->attr_begin())->getLocation().getLocWithOffset(-3));
// Find the first attribute with a valid source-location
for(const auto& attr : funcDecl->attrs()) {
if(const auto location = attr->getLocation(); location.isValid()) {
// the -3 are a guess that seems to work
funcRange.setBegin(location.getLocWithOffset(-3));
return funcRange;
}
}
}

return funcRange;
Expand Down
20 changes: 20 additions & 0 deletions tests/Issue333.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <cstdio>
#include <cstdlib>

// replacement of a minimal set of functions:
void* operator new(std::size_t sz) {
std::printf("global op new called, size = %zu\n",sz);
return std::malloc(sz);
}
void operator delete(void* ptr) noexcept
{
std::puts("global op delete called");
std::free(ptr);
}
int main() {
int* p1 = new int;
delete p1;

int* p2 = new int[10]; // guaranteed to call the replacement in C++11
delete[] p2;
}
24 changes: 24 additions & 0 deletions tests/Issue333.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <cstdio>
#include <cstdlib>

// replacement of a minimal set of functions:
__attribute__((visibility("default"))) void * operator new(std::size_t sz)
{
printf("global op new called, size = %zu\n", sz);
return malloc(sz);
}

__attribute__((visibility("default"))) void operator delete(void * ptr) noexcept
{
puts("global op delete called");
free(ptr);
}

int main()
{
int * p1 = new int;
delete p1;
int * p2 = new int[10];
delete[] p2;
}

0 comments on commit 2b9be10

Please sign in to comment.