This is an archive of the discontinued LLVM Phabricator instance.

[ASTImporter] Imported FunctionDecls inherit __attribute__((noreturn)) and analyzer_noreturn attrs from existing functions
Needs ReviewPublic

Authored by martong on Oct 8 2019, 4:31 AM.

Details

Summary

This way some CTU false positives are eliminated.

Event Timeline

martong created this revision.Oct 8 2019, 4:31 AM
Herald added a reviewer: shafik. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
shafik added inline comments.Oct 8 2019, 12:12 PM
clang/lib/AST/ASTImporter.cpp
7842

There are other attributes that apply to functions as well: nodiscard, maybe_unused and deprecated. Is there a reason not to support those as well?

Hello Balasz,
In my opinion, importing and setting the attributes should be handled by the stuff used in InitializeImportedDecl(). Can we extend it or reuse the code? It will allow us not to miss the required actions while importing a new function too.

Ouch! Sorry, Gabor -_\\

martong marked an inline comment as done.Oct 9 2019, 5:00 AM

Hello Balasz,
In my opinion, importing and setting the attributes should be handled by the stuff used in InitializeImportedDecl(). Can we extend it or reuse the code? It will allow us not to miss the required actions while importing a new function too.

I was thinking about that too, but it turned out to be a way more intrusive change.

We have to work with the most recent existing decl (PrevDecl) of the FunctionDecl whose attribute we currently import.
We can get the PrevDecl only with the help of the lookup. We can't get it from the ToD param of InitializeImportedDecl because by the time when we call InitializeImportedDecl the redecl chain is not connected. So, we should pass PrevDecl then into GetImportedOrCreateDecl. It would require to change all call expressions of GetImportedOrCreateDecl (58 occurences). Besides, we would use the PrevDecl only in case of inheritable attributes, only they require this special care. Note that there are a bunch of non-inheritable attributes which are already handled correctly in InitializeImportedDecl.

clang/lib/AST/ASTImporter.cpp
7842

Different attributes require different handling.

E.g. C++11 [[noreturn]] requires diagnostics if the first declaration of a function does not specify a the attribute, but a later does:

void f();
[[noreturn]] void f(); // ERROR

If a function is declared with [[noreturn]] in one translation unit, and the same function is declared without [[noreturn]] in another translation unit, the program is ill-formed; no diagnostic required.

But this is not true to the GNU attribute((noreturn)).

Also, there are non-inheritable attributes, in their case we do not have to copy anything from the existing most-recent-decl.

Thus, I think I am going to change the patch's name to indicate we deal only with __attribute__((noreturn)) and with analyzer_noreturn.

Hello Balasz,
In my opinion, importing and setting the attributes should be handled by the stuff used in InitializeImportedDecl(). Can we extend it or reuse the code? It will allow us not to miss the required actions while importing a new function too.

I was thinking about that too, but it turned out to be a way more intrusive change.

We have to work with the most recent existing decl (PrevDecl) of the FunctionDecl whose attribute we currently import.
We can get the PrevDecl only with the help of the lookup. We can't get it from the ToD param of InitializeImportedDecl because by the time when we call InitializeImportedDecl the redecl chain is not connected. So, we should pass PrevDecl then into GetImportedOrCreateDecl. It would require to change all call expressions of GetImportedOrCreateDecl (58 occurences). Besides, we would use the PrevDecl only in case of inheritable attributes, only they require this special care. Note that there are a bunch of non-inheritable attributes which are already handled correctly in InitializeImportedDecl.

Actually, giving it some more thought, I realized it would make sense to pass the PrevDecl into GetImportedOrCreateDecl because that way we could connect the redecl chain right after the new node is created, and before importing any other node. That could facilitate structural eq check in the import of subsequent dependent nodes (see https://github.com/Ericsson/clang/issues/506).
Anyway, this change would be quite a big change compared to the original small patch we have here.

martong retitled this revision from [ASTImporter] Imported FunctionDecls inherit attributes from existing functions to [ASTImporter] Imported FunctionDecls inherit __attribute__((noreturn)) and analyzer_noreturn attrs from existing functions.Oct 9 2019, 5:15 AM