This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] fix accessing GDM data from shared libraries
ClosedPublic

Authored by jranieri-grammatech on Oct 4 2018, 1:46 PM.

Details

Summary

The GDMIndex functions return a pointer that's used as a key for looking up data, but addresses of local statics defined in header files aren't the same across shared library boundaries and the result is that analyzer plugins can't access this data.

Diff Detail

Repository
rC Clang

Event Timeline

Hmmm, interesting. A checker doesn't usually need to access these specific static locals, at least not directly. These are usually accessed through functions in .cpp files that are supposed to be compiled with a pointer to the correct instance of the static local, and it doesn't seem to be necessary to expose them to plugins, simply because i don't immediately see why would a plugin want to use them. In this sense, i believe that the entire definition of these traits should be moved to .cpp files and be made private, accessed only via public methods of respective classes. But i guess it's more difficult and it's a separate chunk of work, so i totally approve this patch.

Also, i guess that's what they meant when they were saying that REGISTER_TRAIT_WITH_PROGRAMSTATE [and similar] macros shouldn't be used in headers (https://reviews.llvm.org/D51388?id=162968#inline-455495).

Did you use any sort of tool to find those? I.e., are there more such bugs, and can we prevent this from regressing and breaking your workflow later?

You didn't add reviewers. Does it mean that you are still planning to work on this patch further, or do you want this patch to be committed in its current shape? Static Analyzer patches are usually prefixed with [analyzer] (a few people auto-subscribe to those) and please feel free to add me and @george.karpenkov as reviewers, and the code owner is @dcoughlin.

In D52905#1257040, @NoQ wrote:

Hmmm, interesting. A checker doesn't usually need to access these specific static locals, at least not directly. These are usually accessed through functions in .cpp files that are supposed to be compiled with a pointer to the correct instance of the static local, and it doesn't seem to be necessary to expose them to plugins, simply because i don't immediately see why would a plugin want to use them. In this sense, i believe that the entire definition of these traits should be moved to .cpp files and be made private, accessed only via public methods of respective classes. But i guess it's more difficult and it's a separate chunk of work, so i totally approve this patch.

My current goal is to examine all of the information the analyzer has available at callsites and extract the portions that the project I'm working on might be interested in. I wouldn't disagree with your assessment in general, but it's definitely not something I have time allocated towards doing.

Also, i guess that's what they meant when they were saying that REGISTER_TRAIT_WITH_PROGRAMSTATE [and similar] macros shouldn't be used in headers (https://reviews.llvm.org/D51388?id=162968#inline-455495).

Yeah, I think so.

Did you use any sort of tool to find those? I.e., are there more such bugs, and can we prevent this from regressing and breaking your workflow later?

I wrote a very quick and dirty clang plugin that has this AST matcher:

returnStmt(hasReturnValue(ignoringImplicit(unaryOperator(
               hasOperatorName("&"),
               hasUnaryOperand(declRefExpr(
                   to(varDecl(isStaticLocal()))))))),
           isExpansionInFileMatching("/include/.*\\.h"))

where isStaticLocal is defined as:

AST_MATCHER(VarDecl, isStaticLocal) {
  return Node.isStaticLocal();
}

I've since adapted it to a clang-tidy checker under the llvm 'module', which I'll aim at getting approval to open source as well. Do you know if there's a way to run clang-tidy over all of clang+llvm automatically? My plugin approach had the advantage of just needing to fiddle with CMAKE_CXX_FLAGS to run against the whole codebase...

You didn't add reviewers. Does it mean that you are still planning to work on this patch further, or do you want this patch to be committed in its current shape? Static Analyzer patches are usually prefixed with [analyzer] (a few people auto-subscribe to those) and please feel free to add me and @george.karpenkov as reviewers, and the code owner is @dcoughlin.

This is just my inexperience with the Phabricator patch submission process showing through; I've traditionally emailed patches to the various -dev lists.

jranieri-grammatech retitled this revision from CSA: fix accessing GDM data from shared libraries to [analyzer] fix accessing GDM data from shared libraries.Oct 9 2018, 6:54 AM

Please reupload with full context (-U99999).

Added more context.

NoQ accepted this revision.Oct 9 2018, 12:12 PM

Cool, thanks! I'll commit.

This revision is now accepted and ready to land.Oct 9 2018, 12:12 PM
NoQ added a comment.Oct 9 2018, 12:13 PM

where isStaticLocal is defined as:

You can send this one as well if you like! It's weird that we don't already have it.

NoQ added a comment.Oct 9 2018, 12:15 PM
In D52905#1259249, @NoQ wrote:

where isStaticLocal is defined as:

You can send this one as well if you like! It's weird that we don't already have it.

Or actually maybe it can be implemented as allOf(hasStaticStorageDuration(), unless(hasGlobalStorage())).

there's a way to run clang-tidy over all of clang+llvm automatically

cmake should generate compile_commands.json by default, and then you could just point clang-tidy at that.

This revision was automatically updated to reflect the committed changes.