This is an archive of the discontinued LLVM Phabricator instance.

[Concepts] Correctly handle failure when checking concepts recursively
ClosedPublic

Authored by erichkeane on Oct 28 2022, 1:20 PM.

Details

Summary

Based on discussion on the core reflector, it was made clear that a
concept that depends on itself should be a hard error, not a constraint
failure. This patch implements a stack of constraint-checks-in-progress
to make sure we quit, rather than hitting stack-exhaustion.

Note that we DO need to be careful to make sure we still check
constraints properly that are caused by a previous constraint, but not
derived from (such as when a check causes us to check special member
function generation), so we cannot use the existing logic to see if this
is being instantiated.

This fixes https://github.com/llvm/llvm-project/issues/44304 and
https://github.com/llvm/llvm-project/issues/50891

Diff Detail

Event Timeline

erichkeane created this revision.Oct 28 2022, 1:20 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 28 2022, 1:20 PM
erichkeane requested review of this revision.Oct 28 2022, 1:20 PM
erichkeane retitled this revision from WIP Duplicate atomic constraints- to [Concepts] Correctly handle failure when checking concepts recursively.
erichkeane edited the summary of this revision. (Show Details)
erichkeane added reviewers: luken-google, usaxena95.
erichkeane removed a subscriber: usaxena95.

Add release notes.

Please feel free to review this!

erichkeane removed a subscriber: ychen.
erichkeane edited subscribers, added: Restricted Project, cfe-commits; removed: luken-google.Oct 31 2022, 11:37 AM

Add DELETE_ME so that the libcxx tests run. Due to the nature of this patch, it is possible that I will have missed a few cases where we should be 're-starting' the substitution stack checking.

Looks good to me!

aaron.ballman added reviewers: aaron.ballman, Restricted Project.Oct 31 2022, 12:18 PM

ACTUALLY add the libcxx testing, also rebase so hopefully it applies cleanly.

erichkeane updated this revision to Diff 472268.Nov 1 2022, 5:53 AM

fix clang format

aaron.ballman added inline comments.Nov 1 2022, 6:35 AM
clang/docs/ReleaseNotes.rst
272
clang/include/clang/Sema/Sema.h
7235
clang/lib/Sema/SemaConcept.cpp
150

Er, it'd be nice for this not to shadow the name of the class from Sema, that's pretty confusing.

276–278

What are the chances that this O(N^2) operation is going to come back to bite us in terms of compile time performance?

erichkeane marked 2 inline comments as done.Nov 1 2022, 6:52 AM
erichkeane added inline comments.
clang/lib/Sema/SemaConcept.cpp
150

What do you mean? What name does it shadow?

276–278

I'd hope not too much? This is just going through the whole list of template arguments on this expression, so I think that makes this O(M*N), where M and N are limited by the number of template arguments we allow.

erichkeane updated this revision to Diff 472286.Nov 1 2022, 6:55 AM

Fix issues aaron came up with.

aaron.ballman added inline comments.Nov 1 2022, 6:57 AM
clang/lib/Sema/SemaConcept.cpp
150

Sema.h:7239 (code you added in this patch).

276–278

Okay, I was mostly worried about STL headers where there may be a long list of template arguments and not a lot of recursion to worry about. We don't really memoize whether we've already determined a given constraint is not recursive so that we don't have to repeat this work over and over again, but if performance is a concern in practice, we could explore that as an option.

erichkeane marked 2 inline comments as done.Nov 1 2022, 7:36 AM
erichkeane added inline comments.
clang/lib/Sema/SemaConcept.cpp
150

Yikes! Thanks, good catch!

276–278

I'm somewhat worried there too, but I'd hope that an M*N < ~1000 would be a small impact. We actually DO memoize this, at least on a per instantiation basis, as we cache constraint evaluations.

erichkeane updated this revision to Diff 472298.Nov 1 2022, 7:37 AM
erichkeane marked an inline comment as done.

A quick 'quality of life' improvement, otherwise same as before. Should be ready for commit?

ychen added a comment.Nov 1 2022, 10:55 AM

Thanks for the patch. It looks good to me.

About

Note that we DO need to be careful to make sure we still check
constraints properly that are caused by a previous constraint, but not
derived from (such as when a check causes us to check special member
function generation), so we cannot use the existing logic to see if this
is being instantiated.

For the derived from case, I think we also end up getting the infinite recursion? Why do we disable the check for the derived from case?

Thanks for the patch. It looks good to me.

About

Note that we DO need to be careful to make sure we still check
constraints properly that are caused by a previous constraint, but not
derived from (such as when a check causes us to check special member
function generation), so we cannot use the existing logic to see if this
is being instantiated.

For the derived from case, I think we also end up getting the infinite recursion? Why do we disable the check for the derived from case?

Can you clarify what you mean? I'm not sure which test case you're speaking of.

ychen added a comment.Nov 1 2022, 11:32 AM

Thanks for the patch. It looks good to me.

About

Note that we DO need to be careful to make sure we still check
constraints properly that are caused by a previous constraint, but not
derived from (such as when a check causes us to check special member
function generation), so we cannot use the existing logic to see if this
is being instantiated.

For the derived from case, I think we also end up getting the infinite recursion? Why do we disable the check for the derived from case?

Can you clarify what you mean? I'm not sure which test case you're speaking of.

I was confused about the reason for resetting SatisfactionStack. Never mind :-). I think I understand it now.

ychen accepted this revision as: ychen.Nov 1 2022, 11:38 AM

LGTM

This revision is now accepted and ready to land.Nov 1 2022, 11:38 AM
This revision was landed with ongoing or failed builds.Nov 1 2022, 12:19 PM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptNov 1 2022, 12:19 PM
clang/lib/Sema/SemaOverload.cpp