This is an archive of the discontinued LLVM Phabricator instance.

[clang][Sema] adds `[[clang::no_address]]` attribute
AbandonedPublic

Authored by cjdb on Apr 29 2021, 11:33 PM.

Details

Summary

[namespace.std]/p6 indicates that taking the address of standard
library is unspecified (possibly ill-formed). This commit adds an
opt-in mechanism for standard library functions to ensure that a
program can't take the address of said function.

Diff Detail

Event Timeline

cjdb created this revision.Apr 29 2021, 11:33 PM
cjdb requested review of this revision.Apr 29 2021, 11:33 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 29 2021, 11:33 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
zoecarver added inline comments.Apr 30 2021, 9:09 AM
clang/include/clang/Basic/AttrDocs.td
5972

Could you make this an error?

clang/lib/Sema/SemaOverload.cpp
12286

Nit: you can just assert(OverloadSet && "...").

However, it looks like from the implementation of GetOverloadSet this might very well be null. Asserts crash compilers. If you're very confident this isn't going to be null, leave the assert but change the dyn_casts in GetOverloadSet to casts. Otherwise, provide some way to bail here.

Quuxplusone added inline comments.
clang/test/SemaCXX/attr-no-address.cpp
47–48

FWIW, I don't think this diagnostic provides any benefit to the user-programmer; it merely inconveniences them.
But it does add a lot of burden on the libc++ developers, who must now remember to add a new clang-specific attribute on every function they write.
So for me this is all cost and no benefit.

Am I correct that this attribute doesn't interfere with the user-programmer's writing std::addressof(std::one_overload)?

cjdb abandoned this revision.Apr 30 2021, 9:36 AM

A different path forward was discussed with @ldionne and @zoecarver. Will experiment this other way.

Just for posterity, what we discussed is that since there is a list of addressable functions in the standard, we should explore adding a warning to Clang that fires whenever somebody takes the address of a function in namespace std, except if it's an addressable function. That list would either be maintained explicitly in Clang, or, preferably, we'd have an attribute that we can mark addressable functions with so that the compiler doesn't flag those specific functions.

I'm not sure whether that is actually a good approach, but I told @cjdb that from the library perspective, I was more comfortable with marking a few functions with that attribute than marking basically everything in the library with [[noaddress]].

Just for posterity, what we discussed is that since there is a list of addressable functions in the standard, we should explore adding a warning to Clang that fires whenever somebody takes the address of a function in namespace std, except if it's an addressable function. That list would either be maintained explicitly in Clang, or, preferably, we'd have an attribute that we can mark addressable functions with so that the compiler doesn't flag those specific functions.

I'm not sure whether that is actually a good approach, but I told @cjdb that from the library perspective, I was more comfortable with marking a few functions with that attribute than marking basically everything in the library with [[noaddress]].

Maybe opportunity to rework https://reviews.llvm.org/D58882 :)

Just for posterity, what we discussed is that since there is a list of addressable functions in the standard, we should explore adding a warning to Clang that fires whenever somebody takes the address of a function in namespace std, except if it's an addressable function. That list would either be maintained explicitly in Clang, or, preferably, we'd have an attribute that we can mark addressable functions with so that the compiler doesn't flag those specific functions.

Just in case this didn't come up in the discussion already: we can't rely on the standard library implementation having the "this function is addressable" attributes, because we support other standard libraries that won't have those attributes. I think a combination of an opt-in attribute on the std namespace plus an opt-out attribute on addressable functions would work, as would maintaining a list of addressable functions in Clang.