This is an archive of the discontinued LLVM Phabricator instance.

[clang] fix concepts crash on substitution failure during normalization
ClosedPublic

Authored by mizvekov on Jul 27 2021, 12:27 PM.

Details

Summary

When substitution failed on the first constrained template argument (but
only the first), we would assert / crash. Checking for failure was only
being performed from the second constraint on.

This changes it so the checking is performed in that case,
and the code is also now simplified a little bit to hopefully
avoid this confusion.

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Diff Detail

Event Timeline

mizvekov created this revision.Jul 27 2021, 12:27 PM
mizvekov edited the summary of this revision. (Show Details)Jul 27 2021, 1:40 PM
mizvekov published this revision for review.Jul 27 2021, 1:51 PM
mizvekov added a reviewer: rsmith.
mizvekov added a subscriber: Quuxplusone.

This partially fixes https://bugs.llvm.org/show_bug.cgi?id=47174

It fixes the crash, but there is however a remaining issue, the bogus template lookup (no template named 'Y') diagnostic from @Quuxplusone's reduced test case is still there.

So far as I have seen though, it is only a diagnostic issue.
I can't find an alternate test case with valid code (non ambiguous overload resolution or otherwise) that triggers that kind of error.

Herald added a project: Restricted Project. · View Herald TranscriptJul 27 2021, 1:51 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
rsmith added inline comments.Jul 27 2021, 4:55 PM
clang/lib/Sema/SemaConcept.cpp
744

Might be useful to keep this assert; it will make it clearer to future readers that this function isn't intended to handle this case.

754

Doesn't this have a use-after-destruction bug? I'd expect emplace to first destroy its contained value and then construct a new one; in this case the second constructor argument looks like it'll be a reference to a destroyed object. I assume that's why the old code did the two-step construct and assign dance.

mizvekov added inline comments.Jul 27 2021, 5:26 PM
clang/lib/Sema/SemaConcept.cpp
744

Yeah you are right, the assert makes it obvious this is intended.

754

The constructor used here takes both constraints by value:

NormalizedConstraint(ASTContext &C, NormalizedConstraint LHS,
                     NormalizedConstraint RHS, CompoundConstraintKind Kind)
    : Constraint{CompoundConstraint{
          new (C) std::pair<NormalizedConstraint, NormalizedConstraint>{
              std::move(LHS), std::move(RHS)}, Kind}} { };
mizvekov added inline comments.Jul 27 2021, 5:28 PM
clang/lib/Sema/SemaConcept.cpp
754

But I will also check if emplace is doing the right thing here or not.

mizvekov updated this revision to Diff 362268.Jul 27 2021, 7:55 PM
  • Restore assert.
  • Fix incorrekt use of emplace.
mizvekov marked 2 inline comments as done.Jul 27 2021, 7:56 PM
rsmith accepted this revision.Jul 28 2021, 2:10 PM
This revision is now accepted and ready to land.Jul 28 2021, 2:10 PM