Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #1: Back port Trompeloeil to C++11. #67

Merged
merged 51 commits into from
Dec 2, 2017

Conversation

AndrewPaxie
Copy link
Collaborator

Back ported Trompeloeil to C++11.  Changes by file and directory:
* `.travis.yml`
  * Added job for `g++-4.8` C++11 mode.
  * Accepted 4 errors in `check_errors.sh` when in C++11 mode.
* `CMakeLists.txt`
  * Allowed C++ dialect to be specified on command line using
    `CXX_STANDARD="11"` for C++11, default C++14.
  * Fixed Catch at version 1.11.0, given 2.0.1 triggers a defect
    in `g++` when compiling `libc++`.
  * Refined which sanitizers can be used based on given compiler
    and compiler version.
* `README.md`
  * Updated supported compiler list.
  * Added link to `docs/Backward.md`.
  * Added link to `docs/PlatformAndLibraries.md`.
* `include/trompeloeil.hpp`
  * Significantly reworked to accommodate the C++11 API and
    support compilation in a C++11 dialect.
* `check_errors.sh`
  * Require `CXXFLAGS` with either `-std=c++11` or `-std=c++14`.
* `docs/FAQ.md`
  * Updated supported compilers list.
  * Updated answer regarding C++11 support.
* `docs/`
  * New: "Backward compatibility with earlier versions of C++".
  * New: "Platform and library support for Trompeloeil".
* `compilation_errors/`
  * Support for C++11 expectation syntax in test cases.
* `test/`
  * Split `compiling_tests.cpp` into separately compilable files,
    for Catch main, C++11 test cases and C++14 test cases.

First round review.

rollbear and others added 30 commits September 4, 2017 14:22
Avoid static destruction fiasco for recursive_mutex
Fix issue 55: restore warnings for Clang builds
Removed TROMPELOEIL_DEBUG_RE_FAILURE after confirming regex_check fixed.
Reorganized environment for g++-4.8 to see if it's recognized.
Fix bug in `struct throw_handler_t` found by g++-7 AddressSanitizer.
- Require standard C++ mode without extensions.
- g++-7: disabled sanitize-address-use-after-scope ASan check.
- clang++4.0: enabled sanitize-address-use-after-scope ASan check.
- Added -j 4 to make command line.
@coveralls
Copy link

coveralls commented Nov 15, 2017

Coverage Status

Coverage decreased (-4.1%) to 95.0% when pulling 5138911 on AndrewPaxie:c++11 into f78af43 on rollbear:develop.

@AndrewPaxie
Copy link
Collaborator Author

I have made some changes to improve Coveralls integration:

  • v34 of kcov selected so it can compile on Artful Aardvark (glibc 2.26 no longer defines SIGUNUSED).
  • Tried changing the include pattern to include/trompeloeil.hpp but this might not be the right place to define this for Coveralls integration. I am exploring coveralls.io UI to see what reporting facilities there are. Perhaps this broke when trompeloeil.hpp moved to directory include?

The drop in coverage in g++-4.8 -std=c++11 is due to the way I disabled the regex test failures, among other tests that fail e.g. neg_matcher failures. I have another approach that I would like to try that conditionally uses regex matching; if the test suite is not enabled for regexes then it will fall back to a less precise string comparison method.

Thus there will be further updates as the review progresses.

@rollbear
Copy link
Owner

Apologies my lack of attention, but my ISP (bless their infinite incompetence) has left me without internet connection for a week now, and my fallback over the phone is running thin. I'll get back to you, but I hope you can live with my apparent absense for the moment.

@AndrewPaxie
Copy link
Collaborator Author

All is good. Plenty of work to get through on the current feedback.

@coveralls
Copy link

coveralls commented Nov 16, 2017

Coverage Status

Coverage decreased (-0.3%) to 98.843% when pulling 8000792 on AndrewPaxie:c++11 into f78af43 on rollbear:develop.

@coveralls
Copy link

coveralls commented Nov 16, 2017

Coverage Status

Coverage decreased (-0.08%) to 99.034% when pulling 1d4fa3c on AndrewPaxie:c++11 into f78af43 on rollbear:develop.

@coveralls
Copy link

coveralls commented Nov 18, 2017

Coverage Status

Coverage decreased (-0.08%) to 99.034% when pulling 6044957 on AndrewPaxie:c++11 into f78af43 on rollbear:develop.

@AndrewPaxie
Copy link
Collaborator Author

I have had a look at the history of Coveralls builds to find where browsing to the source of trompeloeil.hpp stopped working. History:

Working in build #328, branch develop, 5 July 2017.

Working in build #330, branch master, 11 July 2017.
https://coveralls.io/builds/12348365/source?filename=trompeloeil.hpp

Commit e57910f @rollbear rollbear committed on Jul 18
"Host self test programs in cmake" is when trompeloeil.hpp moved to include/.

Broken in build #349, branch cmake, 20 July 2017.
https://coveralls.io/builds/12473361/source?filename=trompeloeil.hpp

Broken in build #354, branch develop, 20 July 2017.

Seems there is some update needed to .travis.yml or the Coveralls service configuration, not sure which.

@AndrewPaxie
Copy link
Collaborator Author

I raised issue Make Catch_global_namespace_dummy a complete type in the Catch2 project summarizing the failure to compile Trompeloeil with libc++ and suggesting a fix.

@rollbear
Copy link
Owner

That issue with coveralls not showing the source is so weird. I'm certain it worked after that trompeloeil.hpp move into directory include.

@rollbear
Copy link
Owner

There was an input field on the coveralls.io site, where I could enter a subdirectory to look for the file in. That worked out fine.

@@ -529,10 +849,23 @@ namespace trompeloeil
class duck_typed_matcher : public matcher
{
public:
#if TROMPELOEIL_GCC && TROMPELOEIL_GCC_VERSION < 40900
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused by the operator std::string&&() const added here. The comment implies that this is just to make the self test compile, but does this mean that duck typed matchers do not work with g++-4.8? If so, I wonder if it wouldn't be better to exclude those tests when building with g++-4.8.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a long story to be told with whisky and tears in equal parts. The code here is the product of many other failed experiments. I am investigating the consequences of removing support for these g++-4.8-specific user-defined conversions in duck_typed_matcher and wildcard on my production code base and will have a better idea of the direction to take in the next day or so.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We live about as far apart as we can on this planet, but should we meet, I'll bring the whisky and you can cry your eyes out ;-)
No worries.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disabled the non-template user-defined conversions in wildcard and
duck_typed_matcher after finding

  • No production code was affected by not having support for implicit
    conversions from wildcard or duck_typed_matcher to rvalue references.
  • Only five test cases failed without these user-defined conversions.
    These are now guarded with TROMPELOEIL_TEST_RVALUE_REFERENCE_FAILURES.
    Interestingly only wildcard test cases failed: I could not find a test
    case failure with duck_typed_matcher.

Documentation in Backward.md has been updated to explain the shortcomings
of g++-4.8 should someone stumble upon this issue.

It also appears that the impact on coverage as reported by Coveralls has
been minimal.

@@ -1279,14 +1615,30 @@ namespace trompeloeil
noexcept
{}

#if TROMPELOEIL_GCC && TROMPELOEIL_GCC_VERSION < 40900
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same confusion here.

typename Sig,
typename H,
typename R = decltype(::trompeloeil::default_return<return_of_t<Sig>>())>
struct throw_handler_t
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for this to be a template? The template types are already known in the surrounding type and should be accessible.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out that Sig can be dropped as a template parameter, using signature instead.
R can be made a type alias inside the struct.
But H remains as a template parameter of throw_handler_t as it comes from the
template parameter H of handle_throw.

@@ -3498,6 +3991,9 @@ namespace trompeloeil
unsigned long trompeloeil_expectation_line; \
const char *trompeloeil_expectation_string; \
\
using call_params_type_t = ::trompeloeil::call_params_type_t<sig>; \
using return_of_t = ::trompeloeil::return_of_t<sig>; \
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These types really should have a trompeloeil_ prefix to their names. It's not unimaginable that anyone may want to mock a function named return_of_t, or call_params_type_t.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@rollbear
Copy link
Owner

Added some comments/questions to ´trompeloeil.hpp`. I'll dive into the macros at the end of the file later.

…n step.

Actioned review comments:
- Simplified class template throw_handler_t.
- Renamed internal types in mock function implementation to avoid name clashes.
@coveralls
Copy link

coveralls commented Nov 20, 2017

Coverage Status

Coverage decreased (-0.08%) to 99.034% when pulling 096ff87 on AndrewPaxie:c++11 into f78af43 on rollbear:develop.

@coveralls
Copy link

coveralls commented Nov 22, 2017

Coverage Status

Coverage decreased (-0.08%) to 99.034% when pulling a2e0af6 on AndrewPaxie:c++11 into f78af43 on rollbear:develop.

@rollbear
Copy link
Owner

OK. I'm falling behind again, since my ISP finally "fixed" the problems (and I now have no internet connection at all instead of just a bad one.) I'll get back to you when things are working to at least some degree.

@coveralls
Copy link

coveralls commented Nov 25, 2017

Coverage Status

Coverage decreased (-0.08%) to 99.034% when pulling e3694e3 on AndrewPaxie:c++11 into f78af43 on rollbear:develop.

@rollbear
Copy link
Owner

Internet connection restored. I'll get back to you. There's just a bit of a backlog to wade through...

@rollbear rollbear merged commit 6bcb8c3 into rollbear:develop Dec 2, 2017
@rollbear
Copy link
Owner

rollbear commented Dec 2, 2017

Phiew. It took some time to read through. I'll let it simmer in the develop branch a while before tagging the big official C++11 compatible release.

One question, though. The _AS_STRING macros. Is there any particular reason why there are two different implementations? The C++11 version surely works just as well in C++14? Unless you tell me not to, I'll merge them. Then there's the problem with the short form name, of course. A macro named AS_STRING only is almost guaranteed to collide with other macros in user code.

@AndrewPaxie
Copy link
Collaborator Author

Thanks for the review and merge! I was just drafting this response
but will proceed with pull requests against develop.

Yes it is a good idea to let the code "rest" for a while in develop.
I am still actively seeking a means to improve the TROMPELOEIL_RETURN_ macro
so the -> e_t::trompeloeil_return_of_t trailing return type may be dropped.
Of course, the delay is because I never really understood the differences
between template type deduction, auto type deduction, and decltype type
deduction (and still don't).

I am going to revert the _AS_STRING macros in the next 18 hours.
Please do not merge them. Their importance is low and the possibility
of name-clash and of irritating our users is high. I will move the C++11
version to compiling_tests_11.cpp, where it is needed, and drop the
second C++14 version (never used).

As to their necessity and difference, the C++11 expectation macros expand
macros given in the func (and other) arguments before any stringizing
is performed. For C++11, ANY(int) is stringized as
::trompeloeil::any_matcher<int>("int")
whereas for C++14 it is stringized as ANY(int).

This lead to all kinds of failures in the test cases in
compiling_tests_11.cpp.

These utility macros were supposed to hide the actual stringized contents
of macro. So

  • C++11: macro expand then stringize.
  • C++14: stringize without macro expansion.

This was another case of seeking but not finding a point-for-point C++11
version of the expectation macros when compared to the C++14 implementation.

I explained this difference in
Macro expansion of ANY matcher before stringizing
I will update this documentation to reflect our moving the responsibility
to providing a workaround to those users who are actually affected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants