Due to a recent (but retroactive) C++ rule change, only sufficiently
C-compatible classes are permitted to be given a typedef name for
linkage purposes. Add an enabled-by-default warning for these cases, and
rephrase our existing error for the case where we encounter the typedef
name for linkage after we've already computed and used a wrong linkage
in terms of the new rule.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
- Build Status
Buildable 45898 Build 48031: arc lint + arc unit
Event Timeline
Oh thank goodness, they finally fixed this.
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
4365 | Starting the quote here makes it look like it's describing the invalid-decl short-circuit just below. | |
4394 | This is essentially part of the next paragraph. I believe friend declarations also do not declare "members", under the same logic allowing static_assert. | |
4404 | Do lambdas in nested expressions really get added to the class's decls list? I wouldn't have expected that, but it definitely makes this check a lot easier. |
Updates based on review comments from @rjmccall.
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
4394 | I think you're right, but that's a defect in the wording -- a friend definition, at least, could use the class in a way that requires a linkage calculation, and the design intent as approved by the Evolution Working Group did not permit friend declarations. I'll take this back to the committee for some rewording, but I think it makes sense to proceed under the assumption that friends won't be allowed. In any case, I'm updating the diagnostic to treat friends as a special case, since they're not member declarations. | |
4404 | They end up in some enclosing DeclContext, which is either the class itself or something else that we also disallow. |
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
4394 | Could it? I think the same inability to write a self-reference that makes the C-like cases okay should also apply to friends. If you can write a self-reference in a friend declaration, you can write one in a template argument list in the type of a field declaration. Well, okay, I suppose a friend function *definition* might need to be forbidden. Anyway, I don't think it's actually a problem if the committee wants to outlaw friends here, just wondering at the effective rule they're aiming for in case we need to figure out how to apply it to extensions. | |
4404 | Yeah, obviously their DC should be the class, but I didn't think the decl-to-DC link always implied membership in the decls list. But hey, it seems to work in the case we care about. | |
4473–4477 | Might be good to tell future maintainers how to fix it: probably, by adding something to the forbidden list above. |
Ugh, you mentioned template argument lists and made me realize we can still reach problem cases that way. And with array bounds. :(
I've added back in a diagnostic for the case where we compute the linkage too early for a "C-like" struct. Hopefully people won't hit it too much.
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
4394 | Hm. Now you come to mention it, I think friends might actually be fine -- or at least no worse than non-static data members -- from a linkage perspective. The intended rule is described in P1766R1 section 2.3. If there are extensions that we permit in C structs, it would presumably be reasonable to permit them here too, but I would expect that C++-specific extensions should be disallowed here. |
Okay, if the basic idea is to avoid anything that would need the linkage to be computed, that seems like exactly the right goal.
I know one of the awful ways to get an early reference to the anonymous type is to define a typedef of like a pointer to it, then use that in a second declarator, then try to give it a typedef-for-linkage-purposes in yet another declarator. I don't know of any way to get an expression whose type involves the anonymous type without a non-static member function or initializer or something like that.
Starting the quote here makes it look like it's describing the invalid-decl short-circuit just below.