This is an archive of the discontinued LLVM Phabricator instance.

Fix assertion when generating diagnostic for inline namespaces
ClosedPublic

Authored by aaron.ballman on Aug 19 2021, 12:44 PM.

Details

Summary

When calculating the name to display for inline namespaces, we have custom logic to try to hide redundant inline namespaces from the diagnostic. Calculating these redundancies requires performing a lookup in the parent declaration context, but that lookup should not try to look through transparent declaration contexts, like linkage specifications. Instead, loop up the declaration context chain until we find a non-transparent context and use that instead.

This fixes PR49954.

Diff Detail

Event Timeline

aaron.ballman requested review of this revision.Aug 19 2021, 12:44 PM
aaron.ballman created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptAug 19 2021, 12:44 PM

This whole function seems a little suspect, but I don't have a good example of a place it would break. Is there no cases where a lookup could result in the same COUNT but different declaration set? I guess it is more the question of whether a transparent context can 'lose' a name lookup (perhaps a case of conflicting names?), then have it added by the local namespace.

clang/include/clang/AST/Decl.h
620

This loop seems useful enough to be its own function in DeclContext? I think I remember seeing us do this for a different patch, right?

This whole function seems a little suspect, but I don't have a good example of a place it would break. Is there no cases where a lookup could result in the same COUNT but different declaration set? I guess it is more the question of whether a transparent context can 'lose' a name lookup (perhaps a case of conflicting names?), then have it added by the local namespace.

I don't believe transparent contexts can lose a name lookup -- they're transparent, so the declarations aren't owned by that context, they're owned by the first non-transparent context they run into (as I understand it, anyway). However, the important bit on this patch is: lookup() asserts that you're not trying to call it on a transparent context, so that tells me that we should walk until we find a non-transparent context rather than the current approach of assuming the parent is not transparent.

clang/include/clang/AST/Decl.h
620

This pattern does appear in the code base a few places; I could add a new helper method.

Updating based on review comments.

erichkeane accepted this revision.Aug 20 2021, 6:23 AM

This whole function seems a little suspect, but I don't have a good example of a place it would break. Is there no cases where a lookup could result in the same COUNT but different declaration set? I guess it is more the question of whether a transparent context can 'lose' a name lookup (perhaps a case of conflicting names?), then have it added by the local namespace.

I don't believe transparent contexts can lose a name lookup -- they're transparent, so the declarations aren't owned by that context, they're owned by the first non-transparent context they run into (as I understand it, anyway). However, the important bit on this patch is: lookup() asserts that you're not trying to call it on a transparent context, so that tells me that we should walk until we find a non-transparent context rather than the current approach of assuming the parent is not transparent.

Right... you're probably right here, the mechanism with 'lookup' just feels 1/2 too clever. Anyway, I think I believe that is a battle for another day. See the clang-format warning above, otherwise LGTM.

This revision is now accepted and ready to land.Aug 20 2021, 6:23 AM
aaron.ballman closed this revision.Aug 20 2021, 6:57 AM
aaron.ballman marked an inline comment as done.

Thanks for the reviews! I've committed (with the formatting fix) in 48f73ee666a264d23716ff6bb671cad836b65ccf.

cor3ntin added inline comments.
clang/lib/AST/DeclBase.cpp
1222 ↗(On Diff #367765)

Can getParent() be null? If it cam, then this function can return null which you don't check when you call that function. Or it can't and your test is not doing anything.

erichkeane added inline comments.Aug 20 2021, 8:51 AM
clang/lib/AST/DeclBase.cpp
1222 ↗(On Diff #367765)

I don't think it can ever be null, a DC of transparent-context type is always going to have at least a TranslationUnit as a parent.

I might think an assertion here to replace the DC && part might be worth it.

aaron.ballman added inline comments.Aug 20 2021, 9:05 AM
clang/lib/AST/DeclBase.cpp
1222 ↗(On Diff #367765)

Thanks for the suggestions! I switched to an assert in 65bcdeaa15b729dae40190c6a990cd67c12e9f10.