Skip to content

Commit b9efc8a

Browse files
committed
Compute types of increment expressions
Signed-off-by: Roberto Raggi <[email protected]>
1 parent 1e0ea2e commit b9efc8a

File tree

2 files changed

+97
-20
lines changed

2 files changed

+97
-20
lines changed

src/parser/cxx/parser.cc

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2902,26 +2902,16 @@ auto Parser::parse_expression_list(List<ExpressionAST*>*& yyast,
29022902

29032903
auto Parser::parse_unary_expression(ExpressionAST*& yyast,
29042904
const ExprContext& ctx) -> bool {
2905-
if (parse_unop_expression(yyast, ctx))
2906-
return true;
2907-
else if (parse_complex_expression(yyast, ctx))
2908-
return true;
2909-
else if (parse_await_expression(yyast, ctx))
2910-
return true;
2911-
else if (parse_sizeof_expression(yyast, ctx))
2912-
return true;
2913-
else if (parse_alignof_expression(yyast, ctx))
2914-
return true;
2915-
else if (parse_noexcept_expression(yyast, ctx))
2916-
return true;
2917-
else if (parse_new_expression(yyast, ctx))
2918-
return true;
2919-
else if (parse_delete_expression(yyast, ctx))
2920-
return true;
2921-
else if (parse_reflect_expression(yyast, ctx))
2922-
return true;
2923-
else
2924-
return parse_postfix_expression(yyast, ctx);
2905+
if (parse_unop_expression(yyast, ctx)) return true;
2906+
if (parse_complex_expression(yyast, ctx)) return true;
2907+
if (parse_await_expression(yyast, ctx)) return true;
2908+
if (parse_sizeof_expression(yyast, ctx)) return true;
2909+
if (parse_alignof_expression(yyast, ctx)) return true;
2910+
if (parse_noexcept_expression(yyast, ctx)) return true;
2911+
if (parse_new_expression(yyast, ctx)) return true;
2912+
if (parse_delete_expression(yyast, ctx)) return true;
2913+
if (parse_reflect_expression(yyast, ctx)) return true;
2914+
return parse_postfix_expression(yyast, ctx);
29252915
}
29262916

29272917
auto Parser::parse_unop_expression(ExpressionAST*& yyast,
@@ -3052,6 +3042,52 @@ auto Parser::parse_unop_expression(ExpressionAST*& yyast,
30523042
break;
30533043
}
30543044

3045+
case TokenKind::T_PLUS_PLUS: {
3046+
if (!is_glvalue(ast->expression)) {
3047+
break;
3048+
}
3049+
3050+
auto ty = ast->expression->type;
3051+
3052+
if (control_->is_arithmetic(ty) && !control_->is_const(ty)) {
3053+
ast->type = ty;
3054+
ast->valueCategory = ValueCategory::kLValue;
3055+
break;
3056+
}
3057+
3058+
if (auto ptrTy = type_cast<PointerType>(ty)) {
3059+
if (ptrTy && !control_->is_void(ptrTy->elementType())) {
3060+
ast->type = ptrTy;
3061+
ast->valueCategory = ValueCategory::kLValue;
3062+
}
3063+
}
3064+
3065+
break;
3066+
}
3067+
3068+
case TokenKind::T_MINUS_MINUS: {
3069+
if (!is_glvalue(ast->expression)) {
3070+
break;
3071+
}
3072+
3073+
auto ty = ast->expression->type;
3074+
3075+
if (control_->is_arithmetic(ty) && !control_->is_const(ty)) {
3076+
ast->type = ty;
3077+
ast->valueCategory = ValueCategory::kLValue;
3078+
break;
3079+
}
3080+
3081+
if (auto ptrTy = type_cast<PointerType>(ty)) {
3082+
if (ptrTy && !control_->is_void(ptrTy->elementType())) {
3083+
ast->type = ptrTy;
3084+
ast->valueCategory = ValueCategory::kLValue;
3085+
}
3086+
}
3087+
3088+
break;
3089+
}
3090+
30553091
default:
30563092
break;
30573093
} // switch

tests/unit_tests/sema/incr_01.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %cxx -verify -fcheck %s
2+
3+
auto main() -> int {
4+
char c{};
5+
static_assert(__is_same(decltype(++c), char&));
6+
static_assert(__is_same(decltype(--c), char&));
7+
static_assert(__is_lvalue_reference(decltype(++c)));
8+
static_assert(__is_lvalue_reference(decltype(--c)));
9+
10+
int x{};
11+
static_assert(__is_same(decltype(++x), int&));
12+
static_assert(__is_same(decltype(--x), int&));
13+
static_assert(__is_lvalue_reference(decltype(++x)));
14+
static_assert(__is_lvalue_reference(decltype(--x)));
15+
16+
float f{};
17+
static_assert(__is_same(decltype(++f), float&));
18+
static_assert(__is_same(decltype(--f), float&));
19+
static_assert(__is_lvalue_reference(decltype(++f)));
20+
static_assert(__is_lvalue_reference(decltype(--f)));
21+
22+
double d{};
23+
static_assert(__is_same(decltype(++d), double&));
24+
static_assert(__is_same(decltype(--d), double&));
25+
static_assert(__is_lvalue_reference(decltype(++d)));
26+
static_assert(__is_lvalue_reference(decltype(--d)));
27+
28+
char* p{};
29+
static_assert(__is_same(decltype(++p), char*&));
30+
static_assert(__is_same(decltype(--p), char*&));
31+
static_assert(__is_lvalue_reference(decltype(++p)));
32+
static_assert(__is_lvalue_reference(decltype(--p)));
33+
34+
char*& pr = p;
35+
static_assert(__is_same(decltype(++pr), char*&));
36+
static_assert(__is_same(decltype(--pr), char*&));
37+
static_assert(__is_lvalue_reference(decltype(++pr)));
38+
static_assert(__is_lvalue_reference(decltype(--pr)));
39+
40+
return 0;
41+
}

0 commit comments

Comments
 (0)