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

gtest: Do not reference temporaries past the expression that created them #4540

Merged
merged 1 commit into from
Nov 28, 2019

Conversation

rwy7
Copy link
Contributor

@rwy7 rwy7 commented Nov 5, 2019

This is an error in gtest, not in OMR.

This same error is repeated in a few places, causing different types of
bad behaviour on AIX, including breaking almost all logging and option
processing.

Rather than bind a const mytype& to a temporary result, copy the result
into a local, which ensures it is safe to access the value later in the
program.

When a reference is bound to a temporary value, that reference is
invalid when the value dies, at the end of the "full expression" that
created it. Using this reference to a temporary in a later expression
results in a kind of "use after destruction" error.

Fixes: #4537
Signed-off-by: Robert Young rwy0717@gmail.com

This is an error in gtest, not in OMR.

This same error is repeated in a few places, causing different types of
bad behaviour on AIX, including breaking almost all logging and option
processing.

Rather than bind a const mytype& to a temporary result, copy the result
into a local, which ensures it is safe to access the value later in the
program.

When a reference is bound to a temporary value, that reference is
invalid when the value dies, at the end of the "full expression" that
created it. Using this reference to a temporary in a later expression
results in a kind of "use after destruction" error.

Fixes: eclipse-omr#4537
Signed-off-by: Robert Young <rwy0717@gmail.com>
@smlambert
Copy link
Contributor

Is this a change that can or should be contributed back to gtest directly?

@rwy7
Copy link
Contributor Author

rwy7 commented Nov 5, 2019

It should be, I'm in the middle of going through the google CLA right now. I figure it will be at least a few days, though

EDIT: Nevermind, already done 💃 !

@rwy7 rwy7 changed the title gtest: Do not reference temporaries past their lifetimes gtest: Do not reference temporaries past the expression that createdt them Nov 6, 2019
@rwy7 rwy7 changed the title gtest: Do not reference temporaries past the expression that createdt them gtest: Do not reference temporaries past the expression that created them Nov 6, 2019
@mgaudet
Copy link

mgaudet commented Nov 6, 2019

Side note: I think this is actually an AIX compiler bug. My understanding is that this pattern should be fine due to lifetime extension

All temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created, and if multiple temporary objects were created, they are destroyed in the order opposite to the order of creation. This is true even if that evaluation ends in throwing an exception.

There are two exceptions from that:

  • The lifetime of a temporary object may be extended by binding to a const lvalue reference or to an rvalue reference (since C++11), see reference initialization for details.

(emphasis mine)

That fact that it -only- blows up on AIX is another argument in favour of that.

@rwy7
Copy link
Contributor Author

rwy7 commented Nov 6, 2019

Yes, I actually I meant to update this issue, I am beginning to suspect compiler bug as well. When I first started looking at this bug, I wasn't aware of the lifetime extension rule :). However, I have checked, and the rule is correctly applied by AIX in simple cases. I need to spend more time looking at the crash. As you said, the pattern of code should be valid.

@rwy7
Copy link
Contributor Author

rwy7 commented Nov 11, 2019

@genie-omr build aix

1 similar comment
@rwy7
Copy link
Contributor Author

rwy7 commented Nov 11, 2019

@genie-omr build aix

@rwy7
Copy link
Contributor Author

rwy7 commented Nov 21, 2019

This is a compiler bug in XLC 12.1, possibly older versions as well. The problem is not present in XLC 13.1, which we are using in OMR CI. The problematic code was introduced with gtest 1.8 all the way back in 2017.

The two problem lines were:

I've tried to update every line that binds a reference to a temporary, just just to make sure there are no problems we don't know about yet. In this case, I'm willing to make a code change because it is such a minor patch, in tests only, for a toolchain we officially support. Since this is a bug in XLC, I'm not going to be contributing these changes upstream to gtest. Before we upgrade gtest again, we should look at finally dropping support for XLC 12.1.

Without this patch, the gtest output looks like this:

./omrthreadtest
[==========] Running  tests from  test cases.
[==========]  tests from  test cases ran. ( ms total)
[  PASSED  ]  tests.
[  ALL TESTS PASSED  ] 
./omrthreadtest --gtest_also_run_disabled_tests --gtest_filter=ThreadCreateTest.DISABLED_SetAttrThreadWeight
[==========] Running  tests from  test cases.
[==========]  tests from  test cases ran. ( ms total)
[  PASSED  ]  tests.
[  ALL TESTS PASSED  ] 
ALL omr_threadtest PASSED
DONE

Since this PR is just hacking around a toolchain bug, I can understand why someone wouldn't want this contributed, so if anyone opposes this PR, please comment or just thumbs down the issue.

@youngar
Copy link
Contributor

youngar commented Nov 27, 2019

@genie-omr build all

@youngar
Copy link
Contributor

youngar commented Nov 28, 2019

Travis testing has passed, although github's UI is not reflecting this (for me). Merging!

@youngar youngar merged commit 2f4870b into eclipse-omr:master Nov 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tests do no work on AIX 6.1
5 participants