This is an archive of the discontinued LLVM Phabricator instance.

[Sema] cast to CXXRecordDecl correctly when diag a default comparison method
ClosedPublic

Authored by HerrCai0907 on May 24 2023, 12:44 PM.

Details

Summary

Fixed: https://github.com/llvm/llvm-project/issues/62791
Fixed: https://github.com/llvm/llvm-project/issues/62102
in c++20, default comparison is supported. getLexicalDeclContext maybe cannot
get the CXXRecord if default comparison defined out of CXXRecord.
This patch want to get these information from the first function argument.

Diff Detail

Event Timeline

HerrCai0907 created this revision.May 24 2023, 12:44 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 24 2023, 12:44 PM
HerrCai0907 requested review of this revision.May 24 2023, 12:44 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 24 2023, 12:44 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
shafik added a reviewer: Restricted Project.May 24 2023, 12:49 PM
philnik retitled this revision from [Sema] cast to CXXRecoradDecl correctly when diag a default comparison method to [Sema] cast to CXXRecordDecl correctly when diag a default comparison method.May 24 2023, 12:51 PM
HerrCai0907 retitled this revision from [Sema] cast to CXXRecordDecl correctly when diag a default comparison method to [Sema] cast to CXXRecoradDecl correctly when diag a default comparison method.May 24 2023, 12:52 PM
HerrCai0907 retitled this revision from [Sema] cast to CXXRecoradDecl correctly when diag a default comparison method to [Sema] cast to CXXRecordDecl correctly when diag a default comparison method.May 24 2023, 12:53 PM

As Richard says, we should just be taking the first parameter type and using that instead (obviously de-qualified and removing reference if necessary).

clang/lib/Sema/SemaTemplateInstantiate.cpp
970

According to the comment on the related bug:

This code predates P2085R0, prior to which a comparison function could only be defaulted lexically within the class. Given that we can't use the lexically-enclosing class any more, we can instead look at the (first) parameter type to determine which class's comparison is being defaulted.
...
since the lexical context isn't the right thing for us to be looking at any more
...
HerrCai0907 edited the summary of this revision. (Show Details)May 24 2023, 1:00 PM
HerrCai0907 added a reviewer: hans.
HerrCai0907 added a comment.EditedMay 24 2023, 1:04 PM

As Richard says, we should just be taking the first parameter type and using that instead (obviously de-qualified and removing reference if necessary).

But we still can find the correct RecordDecl by redecls.

As Richard says, we should just be taking the first parameter type and using that instead (obviously de-qualified and removing reference if necessary).

But we still can find the correct RecordDecl by redecls.

That ends up being an absurdly larger amount of work, and in the case of a 'friend' declaration can result in the wrong answer, correct? Consider something like:

struct Foo;

struct Bar {
    friend bool operator==(const Foo&, const Foo&);
};

struct Foo {
    friend bool operator==(const Foo&, const Foo&);
};

bool operator==(const Foo&, const Foo&) = default;

or even:

struct Foo {
    bool operator==(const Foo&) const;
};

struct Bar {
    friend bool Foo::operator==(const Foo&) const;
};


bool operator==(Foo, Foo) = default;

In the 1st one, the lexical context could be 'Bar'. Searching 'redecls' will end up with the 'first one first', so at least the 2nd example isn't as problematic, but I'm sure someone more clever than I could come up with a case where that could be declared in a different order.

change solution

HerrCai0907 edited the summary of this revision. (Show Details)May 24 2023, 2:26 PM
erichkeane added inline comments.May 25 2023, 7:00 AM
clang/lib/Sema/SemaTemplateInstantiate.cpp
970

What is going on here? You already have the RecordType in the RecordType variable. You don't need to go to RecordDecl and back? You should just be able to put the RecordType variable directly.

getLocallyUnqualifiedSingleStepDesugaredType to find the whole record name

HerrCai0907 added inline comments.May 25 2023, 11:36 AM
clang/lib/Sema/SemaTemplateInstantiate.cpp
970

I am not very familiar with QualType's conversion. Do you think it is the correct path to remove all qualifier and get the full name for class?

erichkeane added inline comments.May 25 2023, 11:39 AM
clang/lib/Sema/SemaTemplateInstantiate.cpp
968

This doesn't seem right to me? I think you just want the unqualified, non-reference type here. I suspect you don't really want to do Desugaring at all, since then you lose the typedef information (so something like std::string will be confusing).

So I think you just want: .getNonReferenceType().getUnqualifiedType().

avoid desurger

remove not related change

erichkeane accepted this revision.May 25 2023, 12:39 PM

LGTM, thanks!

This revision is now accepted and ready to land.May 25 2023, 12:39 PM
This revision was landed with ongoing or failed builds.May 25 2023, 1:08 PM
This revision was automatically updated to reflect the committed changes.