Don't take the address of an xvalue when printing an expr result

Summary:
If we have an xvalue here, we will always hit the `err_typecheck_invalid_lvalue_addrof` error
in 'Sema::CheckAddressOfOperand' when trying to take the address of the result. This patch
uses the fallback code path where we store the result in a local variable instead when we hit
this case.

Fixes rdar://problem/40613277

Reviewers: jingham, vsk

Reviewed By: vsk

Subscribers: vsk, friss, lldb-commits

Differential Revision: https://reviews.llvm.org/D48303

llvm-svn: 336582
This commit is contained in:
Raphael Isemann 2018-07-09 18:57:11 +00:00
parent a62c9d62a3
commit b69854f01c
4 changed files with 56 additions and 3 deletions

View File

@ -0,0 +1,5 @@
LEVEL = ../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,37 @@
from __future__ import print_function
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class ExprXValuePrintingTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
self.main_source = "main.cpp"
self.main_source_spec = lldb.SBFileSpec(self.main_source)
def do_test(self, dictionary=None):
"""Printing an xvalue should work."""
self.build(dictionary=dictionary)
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
'// Break here', self.main_source_spec)
frame = thread.GetFrameAtIndex(0)
value = frame.EvaluateExpression("foo().data")
self.assertTrue(value.IsValid())
self.assertTrue(value.GetError().Success())
self.assertEqual(value.GetValueAsSigned(), 1234)
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
def test(self):
self.do_test()

View File

@ -0,0 +1,12 @@
struct Tmp
{
int data = 1234;
};
Tmp foo() { return Tmp(); }
int main(int argc, char const *argv[])
{
int something = foo().data;
return 0; // Break here
}

View File

@ -292,9 +292,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
//
// - During dematerialization, $0 is ignored.
bool is_lvalue = (last_expr->getValueKind() == VK_LValue ||
last_expr->getValueKind() == VK_XValue) &&
(last_expr->getObjectKind() == OK_Ordinary);
bool is_lvalue = last_expr->getValueKind() == VK_LValue &&
last_expr->getObjectKind() == OK_Ordinary;
QualType expr_qual_type = last_expr->getType();
const clang::Type *expr_type = expr_qual_type.getTypePtr();