Skip to content

Commit 12adeb7

Browse files
committed
Compute types of c++ cast expressions
Signed-off-by: Roberto Raggi <[email protected]>
1 parent 08f19f7 commit 12adeb7

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

src/parser/cxx/parser.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,32 @@ auto Parser::parse_cpp_cast_expression(ExpressionAST*& yyast,
26012601

26022602
expect(TokenKind::T_RPAREN, ast->rparenLoc);
26032603

2604+
auto check_cpp_cast = [&] -> void {
2605+
if (!ast->typeId) {
2606+
return;
2607+
}
2608+
2609+
ast->type = ast->typeId->type;
2610+
2611+
if (auto refType = type_cast<LvalueReferenceType>(ast->type)) {
2612+
ast->type = refType->elementType();
2613+
ast->valueCategory = ValueCategory::kLValue;
2614+
return;
2615+
}
2616+
2617+
if (auto rvalueRefType = type_cast<RvalueReferenceType>(ast->type)) {
2618+
ast->type = rvalueRefType->elementType();
2619+
2620+
if (type_cast<FunctionType>(ast->type)) {
2621+
ast->valueCategory = ValueCategory::kLValue;
2622+
} else {
2623+
ast->valueCategory = ValueCategory::kXValue;
2624+
}
2625+
}
2626+
};
2627+
2628+
check_cpp_cast();
2629+
26042630
return true;
26052631
}
26062632

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %cxx -verify -fcheck %s
2+
3+
struct X {};
4+
5+
using F = int();
6+
7+
int f() { return 0; }
8+
9+
auto main() -> int {
10+
X x;
11+
12+
F&& rf = f;
13+
14+
// prvalue
15+
static_assert(__is_reference(decltype(static_cast<X>(x))) == false);
16+
17+
// lvalue if lvalue reference to object type
18+
static_assert(__is_lvalue_reference(decltype(static_cast<X&>(x))));
19+
20+
// rvalue if rvalue reference to object type
21+
static_assert(__is_rvalue_reference(decltype(static_cast<X&&>(x))));
22+
23+
// prvalue
24+
static_assert(__is_reference(decltype(static_cast<F*>(f))) == false);
25+
26+
// lvalue if lvalue reference to function type
27+
static_assert(__is_lvalue_reference(decltype(static_cast<F&>(f))));
28+
29+
// lvalue if rvalue reference to function type
30+
static_assert(__is_lvalue_reference(decltype(static_cast<F&&>(f))));
31+
}

0 commit comments

Comments
 (0)