Adding a checker to find a function given its name and add a given visibility attribute if none is present (i.e. __attribute__((visibility("hidden"))).
Details
Diff Detail
Event Timeline
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
33 | Would it make more sense to store a list of names and then find all of them at once, rather than a single name at a time? | |
35 | It'd be nice to pick a slightly better string literal to use. | |
41 | This diagnostic doesn't really tell the user what's wrong with their code. | |
test/clang-tidy/fuchsia-add-visibility.cpp | ||
11 | I'd also like to see tests where the attribute is already present on the definition (to ensure it doesn't get added), or is already present on the declaration and is inherited on the definition. What should happen with code like this: __attribute__((visibility("internal"))) void f(); void f() { } Will this check attempt to add __attribute__((visibility("hidden"))) to the definition? |
I'd like a test for #pragma GCC visibility push(hidden) which should cause each symbol to be treated as though it were explicitly hidden.
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
33 | +1 on this we generally want to make this change to many different functions at the same time. |
I'd like a test for #pragma GCC visibility push(hidden) which should cause each symbol to be treated as though it were explicitly hidden.
To clarify, this check should still give a warning if the specified variable doesn't actually have that in source code. e.g. simply because "#pragma GCC visibility push(hidden)" was at the top dosn't mean these functions should get a pass.
- Added visibility parameter
- Updated Name parameter to be a list of names, as opposed to a single name
- Fixed comments and documentation
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
37–40 | Rather than do this, you should use parseStringList() from OptionsUtils.h. This will also ensure you don't use the wrong separator (we use semi-colons for this, not commas). | |
49 | You should use serializeStringList() for this. See InefficientVectorOperationCheck for an example of parsing and serializing the string lists. | |
57 | Rather than a for loop, you can pass the list to hasAnyName(). | |
64 | Once you drop the for loop, you can pick a single name to bind to -- the check() function will be called once for each match anyway, so you don't need an explicit loop checking all of the name. | |
66–67 | You should use a Twine to construct this in place. | |
69 | How about: "function expected to be annotated with '%0' visibility" I'm mostly worried about the case where the function has a visibility attribute, but it has the *wrong* visibility specified. The current wording would be confusing in that circumstance. Or is that not a scenario you care about, just that *any* visibility is specified on the function? | |
clang-tidy/fuchsia/AddVisibilityCheck.h | ||
22 | The backtick is in the wrong place. |
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
69 | The use case for this check is forcing code bases to carefully control what symbols are exported rather than just exporting everything. So if someone took the time to explicitly set the visibility of one of these symbols we care about then we should assume they knew what they were doing. The specific use case I care about for this check is using -fvisibility=hidden and then checking to make sure a certain curated list of symbols has explicit default visibility. |
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
69 | Ah, so a mismatch is unimportant, that's good to know. How about: "function expected to be annotated with the 'visibility' attribute"? |
Updating check to allow for #pragma and command line visibility specs, and updating tests
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
69 | So in implementing a way to handle #pragma and command line directives, it became clear that the more comprehensive check (that replaces existing attrs) was a trivial implementation on top of that, so I put it in. If we just want to ignore those cases, I can take out the conditional path. |
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
24–26 | Can remove these comments. | |
53–54 | Can you use makeArrayRef() rather than using a SmallVector that allocates? | |
63 | const auto * | |
67 | Why are you passing D as well? | |
73 | Why are you passing in both VisAttr and D? | |
test/clang-tidy/fuchsia-add-visibility.cpp | ||
26 | Should this test case diagnose, assuming foo is in the list of functions to check? __attribute__((visibility("default"))) void foo(int); void foo(double); // Diagnose? How about this case? template <typename Ty> __attribute__((visibility("default"))) void foo(Ty); template <> void foo<int>(int); // Diagnose? |
After discussion, the goal of this checker slightly changed to target definitions in header files, rather than declarations. As a result, the check now adds the attribute to any definition (declaration or not) that appears in a header file.
Also updating tests.
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
53–54 | Type-wise it gets funky -- makeArrayRef() creates an ArrayRef<std::string>, and the matcher wants a container of StringRefs. Is there a good way to do that without allocating? |
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
26 | What are these comments doing here? | |
49 | What about internal? | |
64 | Something in the list that simply has explicit visibility should pass I think. For instance saying you have a blacklist of symbols instead of a whitelist. Sometimes internal or hidden might be used but we might want to add "hidden" by default. So "Vis" might be DefaultVisibility but we don't want to raise an error/change something labeled with internal visibility to hidden. |
Can you add a test for when #pragma GCC visibility push(hidden) is used and the visibility attribute is hidden?
clang-tidy/fuchsia/AddVisibilityCheck.cpp | ||
---|---|---|
40 | This works for now, but it would be nice to expose "driver diagnostics" for sanity checking clang-tidy configuration options. These diagnostics would not be required to pass in a source location, merely the diagnostic text. We already support thing kind of things for driver-generated diagnostics, but it's not exposed to clang-tidy yet. | |
49 | Might be a good use of StringSwitch. | |
53–54 | I think there is, but it is orthogonal to your patch to make that many changes, so you can ignore my suggestion. I didn't see the type shenanigans there. | |
75 | Capitalization |
The backtick is in the wrong place.