This is an archive of the discontinued LLVM Phabricator instance.

[Error] Fix template deduction in createFileError
ClosedPublic

Authored by aganea on Aug 30 2018, 8:06 AM.

Details

Summary

This properly fixes the build break here.

/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/include/llvm/Support/Error.h:1219:11: error: default arguments cannot be added to a function template that has already been declared
        * = nullptr) {
          ^ ~~~~~~~
/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/include/llvm/Support/Error.h:1175:16: note: previous template declaration is here
  friend Error createFileError(
               ^
1 error generated.

As an example, I've included a compile-time error in ErrorTest.cpp (which I would not commit), although I don't know how I should test this properly?

On a broader view, do you think shielding createFileError() against such usage is useful? It is a corner case, and it is already covered at runtime.

Diff Detail

Event Timeline

aganea created this revision.Aug 30 2018, 8:06 AM
aganea added inline comments.Aug 30 2018, 8:10 AM
unittests/Support/ErrorTest.cpp
877

This is only provided as an example, not to be commited.

MSVC 2017 15.8 fails with:

1>f:\svn\llvm\unittests\support\errortest.cpp(877): error C2672: 'createFileError': no matching overloaded function found
1>f:\svn\llvm\unittests\support\errortest.cpp(877): error C2783: 'llvm::Error llvm::createFileError(std::string,Err)': could not deduce template argument for '<unnamed-symbol>'
1>f:\svn\llvm\include\llvm\support\error.h(1175): note: see declaration of 'llvm::createFileError'

Clang (aug. snapshot) fails with:

1>F:\svn\llvm\unittests\Support\ErrorTest.cpp(877): error : no matching function for call to 'createFileError'
1>F:\svn\llvm\include\llvm/Support/Error.h(1211):  note: candidate template ignored: requirement '!std::is_base_of<ErrorSuccess, ErrorSuccess>::value' was not satisfied [with Err = llvm::ErrorSuccess]
aganea added a comment.Sep 6 2018, 4:57 PM

Ping. Please let me know if there’re any comments on this. I just wanted to make sure I’m not overdesigning. TIA!

zturner added inline comments.Sep 6 2018, 5:06 PM
include/llvm/Support/Error.h
1208–1211

What if you just write:

Error createFileError(std::string F, ErrorSuccess) = delete;

Does that also solve the problem?

ilya-biryukov accepted this revision.Sep 7 2018, 3:30 AM

LGTM from my side, SFINAE check looks correct.
Not familiar with the code, though, so we should probably wait for an approval from @zturner too.

include/llvm/Support/Error.h
1208–1211

I think this won't work if we want it to work for descendants of ErorrSucces. The reason is that the template would still be preferred for the derived classes, e.g.

class MyErrorSuccess : public ErrorSuccess {
  ///... 
};

void test() {
  createFile("foo", MyErrorSuccess()); // <-- chooses a template, not `=delete`d function.
}

The reason is that the non-template overload needs a derived-to-base conversion for the second arg, so it's considered "worse" than the template one for the purpose of the overloading.

Haven't checked with the compiler, though.

This revision is now accepted and ready to land.Sep 7 2018, 3:30 AM
aganea added inline comments.Sep 7 2018, 6:16 AM
include/llvm/Support/Error.h
1208–1211

If using the = delete suggestion, createFileError("file.bin", ErrorSuccess()) fails with:

1>F:\svn\llvm\unittests\Support\ErrorTest.cpp(878): error : call to deleted function 'createFileError'
1>F:\svn\llvm\include\llvm/Support/Error.h(1217):  note: candidate function has been explicitly deleted
1>F:\svn\llvm\include\llvm/Support/Error.h(1213):  note: candidate function [with Err = llvm::ErrorSuccess]

However, createFileError("file.bin", MyErrorSuccess()) is fine.

The constructor to Expected has the same issue. It would fail with ErrorSuccess, but not with MyErrorSuccess.

We could make ErrorSucess final? Is it really desirable to have several ways of succeeding?

ilya-biryukov added inline comments.Sep 7 2018, 6:32 AM
include/llvm/Support/Error.h
1208–1211

Making ErrorSuccess sounds reasonable.
The sfinae trick also checks the deduced type is a subtype of Error, do we want to get rid of this check too? (Would fail in the template body instead, I assume)

ilya-biryukov added inline comments.Sep 7 2018, 6:52 AM
include/llvm/Support/Error.h
1208–1211

Correction: making ErrorSuccess final ...

aganea updated this revision to Diff 164412.Sep 7 2018, 6:55 AM
aganea added a reviewer: lhames.

Updated diff. I made ErrorSuccess a final class. That makes things simpler and solves the issue for Expected as well.

Please let me know if that sounds better.

zturner added a subscriber: aganea.Sep 7 2018, 7:07 AM

That works, I agree it doesn’t make sense to have descendants of
ErrorSuccess.

Lgtm

This revision was automatically updated to reflect the committed changes.