This is an archive of the discontinued LLVM Phabricator instance.

[Sema]Select correct lexical context during template instantiate
ClosedPublic

Authored by HerrCai0907 on Apr 22 2023, 10:42 PM.

Details

Summary

This patch wants to fix inline friend decl like

template <class F1> int foo(F1 X);
template <int A1> struct A {
  template <class F1> friend int foo(F1 X) { return A1; }
};

template struct A<1>;
int a = foo(1.0);

Diff Detail

Event Timeline

HerrCai0907 created this revision.Apr 22 2023, 10:42 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 22 2023, 10:42 PM
HerrCai0907 requested review of this revision.Apr 22 2023, 10:42 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 22 2023, 10:42 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

fix assert failed

clang/lib/Sema/SemaTemplateDeduction.cpp
3597 ↗(On Diff #516152)

I was originally REALLY suspicious about this function call here (and the setup with the out parameter/2nd variable here). but it seems that the 'true' argument (which, needs a /*ParamName */ comment) is specifically designed for this situation.

3598 ↗(On Diff #516152)

So in what case would the currently-instantiated definition NOT also be a friend? I would think this last condition should be able to be an assert instead.

3601 ↗(On Diff #516152)

I THINK this should just be:
Owner = FD->getLexicalDeclContext() here.

HerrCai0907 added inline comments.Apr 24 2023, 4:04 PM
clang/lib/Sema/SemaTemplateDeduction.cpp
3598 ↗(On Diff #516152)

Last condition cannot be an assert, define and declare in difference place is common case, what we need to identifier in here is inlined friend define.

3601 ↗(On Diff #516152)

The old Owner is FunctionTemplate->getLexicalDeclContext(). So I think we should use same level owner.

add comment and more test

erichkeane added inline comments.Apr 25 2023, 6:09 AM
clang/lib/Sema/SemaTemplateDeduction.cpp
3598 ↗(On Diff #516152)

Can you be more clear here? WHEN can a definition and declaration NOT have the same friend object kind? THAT is probably incorrect a bug.

3601 ↗(On Diff #516152)

Its not a question of "SameLevel", its that it was the accessible one based on what was around. IN this case, we have a 'better' alternative, which is the FunctionDecl.

HerrCai0907 added inline comments.Apr 25 2023, 2:18 PM
clang/lib/Sema/SemaTemplateDeduction.cpp
3598 ↗(On Diff #516152)

Sorry I cannot get the point.
Here I have 3 conditions:

  1. FD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None

FD(declaration) is not friend object.

  1. FD->isDefined(FDFriend, true)

get FDFriend(definition) from FD(declaration).

  1. FDFriend->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None)

FDFriend(definition) is friend object.

matching those 3 condition and then we can say FDFriend is a inline friend like

template <class F1> int foo(F1 X); // FD
template <int A1> struct A {
template <class F1> friend int foo(F1 X) { return A1; } // FDFriend
};

change LexicalDeclContext

erichkeane added inline comments.Apr 26 2023, 7:27 AM
clang/lib/Sema/SemaTemplateDeduction.cpp
3598 ↗(On Diff #516152)

Ok, my question is: WHEN is #3 "false" but #1 and #2 are "true"? It should not be possible for #1 to be "true" but #3 to be "false", as far as I know.

tahonermann added inline comments.
clang/lib/Sema/SemaTemplateDeduction.cpp
3598 ↗(On Diff #516152)

It looks like getFriendObjectKind() returns a declaration specific value such that, for the example given, it returns FOK_None for the first declaration and FOK_Declared for the friend definition. (I haven't tested that, but that is what my brief reading of the code suggests).

erichkeane accepted this revision.Apr 26 2023, 8:14 AM
erichkeane added inline comments.
clang/lib/Sema/SemaTemplateDeduction.cpp
3598 ↗(On Diff #516152)

Ah, right! thanks for that Tom! Yeah, its just that the 1st declaration is NOT a friend, I had these reversed in my head so was very confused. OK, thanks!

This revision is now accepted and ready to land.Apr 26 2023, 8:14 AM
This revision was landed with ongoing or failed builds.Apr 26 2023, 3:30 PM
This revision was automatically updated to reflect the committed changes.