This is an archive of the discontinued LLVM Phabricator instance.

SemaOverload: Complete candidates before emitting the error, to ensure diagnostics emitted (or suppressed) during completion don't interfere with the overload notes
ClosedPublic

Authored by dblaikie on Apr 30 2019, 5:45 PM.

Details

Summary

Because diagnostics and their notes are not connected at the API level,
if the error message for an overload is emitted, then the overload
candidates are completed - if a diagnostic is emitted during that work,
the notes related to overload candidates would be attached to the latter
diagnostic, not the original error. Sort of worse, if the latter
diagnostic was disabled, the notes are disabled.

Diff Detail

Repository
rC Clang

Event Timeline

dblaikie created this revision.Apr 30 2019, 5:45 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 30 2019, 5:45 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Oh, @rsmith - if there's any better/different testing (if you can figure out how to reduce the test case down further, now that we know the cause - or if you'd like testing for other codepaths I've touched in this patch) I'm all ears. (also naming/API wrangling - my changes were just the minimal sort of "this works" based on what we discussed, but totally happy to do more involved/different things if there's such to be done)

rsmith accepted this revision.May 2 2019, 4:27 PM

LGTM, thanks!

lib/Sema/SemaOverload.cpp
3522–3523

Can we avoid calling CompleteCandidates on this path?

This revision is now accepted and ready to land.May 2 2019, 4:27 PM
rsmith added a comment.May 2 2019, 4:31 PM

Oh, @rsmith - if there's any better/different testing (if you can figure out how to reduce the test case down further, now that we know the cause - or if you'd like testing for other codepaths I've touched in this patch) I'm all ears. (also naming/API wrangling - my changes were just the minimal sort of "this works" based on what we discussed, but totally happy to do more involved/different things if there's such to be done)

Perhaps we could add a diagnostic scope object of some kind, which would assert (or reorder the diagnostics?) if a diagnostic is produced while producing notes for a different diagnostic. That might help for new code and for places where we're aware -- or suspect -- there is a problem, but we don't know where the existing bugs are and that doesn't help us find them. :(

This revision was automatically updated to reflect the committed changes.
dblaikie marked an inline comment as done.May 2 2019, 5:45 PM

Oh, @rsmith - if there's any better/different testing (if you can figure out how to reduce the test case down further, now that we know the cause - or if you'd like testing for other codepaths I've touched in this patch) I'm all ears. (also naming/API wrangling - my changes were just the minimal sort of "this works" based on what we discussed, but totally happy to do more involved/different things if there's such to be done)

Perhaps we could add a diagnostic scope object of some kind, which would assert (or reorder the diagnostics?) if a diagnostic is produced while producing notes for a different diagnostic. That might help for new code and for places where we're aware -- or suspect -- there is a problem, but we don't know where the existing bugs are and that doesn't help us find them. :(

Yeah, I was thinking about something like that. Yeah, doesn't seem any reason we couldn't retrofit something on top of the diagnostics infratsructure - or a utility in it that connects notes to their diagnostic & either asserts, or delays emission, etc.

I was thinking about that in the context of cleaning up /everything/ to use that, but yeah - we could do it as an incremental migration/as needed sort of thing.

lib/Sema/SemaOverload.cpp
3522–3523

Yeah, I raised up the two if conditions to a pre-check:

if (!(OvResult == OR_Ambiguous ||
      (OvResult == OR_No_Viable_Function && !CandidateSet.empty())))
  return false;

auto Cands = ...
if (...Ambiguous)
  ...
else { // No_Viable_Function && !empty()
  ...
NoteCandidates

(open to other ideas, couldn't quite think of anything that didn't involve some duplication - either duplicating the conditions or the CompleteCandidates call, etc)