Skip to content

Commit 755ba01

Browse files
committed
Compute the type of indirection operators
Signed-off-by: Roberto Raggi <[email protected]>
1 parent 4b4e6b4 commit 755ba01

File tree

4 files changed

+73
-9
lines changed

4 files changed

+73
-9
lines changed

src/parser/cxx/parser.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2919,6 +2919,21 @@ auto Parser::parse_unop_expression(ExpressionAST*& yyast,
29192919
ast->op = unit->tokenKind(opLoc);
29202920
ast->expression = expression;
29212921

2922+
switch (ast->op) {
2923+
case TokenKind::T_STAR: {
2924+
auto pointerType = type_cast<PointerType>(expression->type);
2925+
if (pointerType) {
2926+
ensure_prvalue(ast->expression);
2927+
ast->type = pointerType->elementType();
2928+
ast->valueCategory = ValueCategory::kLValue;
2929+
}
2930+
break;
2931+
}
2932+
2933+
default:
2934+
break;
2935+
} // switch
2936+
29222937
return true;
29232938
}
29242939

@@ -6365,6 +6380,23 @@ auto Parser::qualification_conversion(ExpressionAST*& expr,
63656380
return false;
63666381
}
63676382

6383+
void Parser::ensure_prvalue(ExpressionAST*& expr) {
6384+
if (lvalue_to_rvalue_conversion(expr)) {
6385+
expr->valueCategory = ValueCategory::kPrValue;
6386+
return;
6387+
}
6388+
6389+
if (array_to_pointer_conversion(expr)) {
6390+
expr->valueCategory = ValueCategory::kPrValue;
6391+
return;
6392+
}
6393+
6394+
if (function_to_pointer_conversion(expr)) {
6395+
expr->valueCategory = ValueCategory::kPrValue;
6396+
return;
6397+
}
6398+
}
6399+
63686400
auto Parser::implicit_conversion(ExpressionAST*& expr,
63696401
const Type* destinationType) -> bool {
63706402
if (!expr || !expr->type) return false;

src/parser/cxx/parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,8 @@ class Parser final {
858858
const Type* destinationType)
859859
-> bool;
860860

861+
void ensure_prvalue(ExpressionAST*& expr);
862+
861863
[[nodiscard]] auto implicit_conversion(ExpressionAST*& expr,
862864
const Type* destinationType) -> bool;
863865

tests/unit_tests/ast/asm_declaration_01.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,11 @@ end:;
106106
// CHECK-NEXT: constraint-literal: "+rm"
107107
// CHECK-NEXT: expression: unary-expression
108108
// CHECK-NEXT: op: *
109-
// CHECK-NEXT: expression: id-expression
110-
// CHECK-NEXT: unqualified-id: name-id
111-
// CHECK-NEXT: identifier: p
109+
// CHECK-NEXT: expression: implicit-cast-expression
110+
// CHECK-NEXT: cast-kind: lvalue-to-rvalue-conversion
111+
// CHECK-NEXT: expression: id-expression
112+
// CHECK-NEXT: unqualified-id: name-id
113+
// CHECK-NEXT: identifier: p
112114
// CHECK-NEXT: function-definition
113115
// CHECK-NEXT: decl-specifier-list
114116
// CHECK-NEXT: void-type-specifier

tests/unit_tests/sema/class_01.cc

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
// RUN: %cxx -verify -fcheck %s
22

33
struct X {
4-
void f() { static_assert(__is_same(decltype(this), X*)); }
4+
void f() {
5+
static_assert(__is_same(decltype(this), X*));
6+
static_assert(__is_same(decltype(*this), X&));
7+
}
58

6-
void f() const { static_assert(__is_same(decltype(this), const X*)); }
9+
void f() const {
10+
static_assert(__is_same(decltype(this), const X*));
11+
static_assert(__is_same(decltype(*this), const X&));
12+
}
713

8-
void f() volatile { static_assert(__is_same(decltype(this), volatile X*)); }
14+
void f() volatile {
15+
static_assert(__is_same(decltype(this), volatile X*));
16+
static_assert(__is_same(decltype(*this), volatile X&));
17+
}
918

1019
void f() const volatile {
1120
static_assert(__is_same(decltype(this), const volatile X*));
21+
static_assert(__is_same(decltype(*this), const volatile X&));
1222
}
1323

1424
void g();
@@ -17,12 +27,30 @@ struct X {
1727
void g() const volatile;
1828
};
1929

20-
void X::g() { static_assert(__is_same(decltype(this), X*)); }
30+
void X::g() {
31+
static_assert(__is_same(decltype(this), X*));
32+
static_assert(__is_same(decltype(*this), X&));
33+
34+
X* self = this;
35+
static_assert(__is_same(decltype(self), X*));
36+
static_assert(__is_same(decltype(*self), X&));
2137

22-
void X::g() const { static_assert(__is_same(decltype(this), const X*)); }
38+
X*& x = self;
39+
static_assert(__is_same(decltype(x), X*&));
40+
static_assert(__is_same(decltype(*x), X&));
41+
}
42+
43+
void X::g() const {
44+
static_assert(__is_same(decltype(this), const X*));
45+
static_assert(__is_same(decltype(*this), const X&));
46+
}
2347

24-
void X::g() volatile { static_assert(__is_same(decltype(this), volatile X*)); }
48+
void X::g() volatile {
49+
static_assert(__is_same(decltype(this), volatile X*));
50+
static_assert(__is_same(decltype(*this), volatile X&));
51+
}
2552

2653
void X::g() const volatile {
2754
static_assert(__is_same(decltype(this), const volatile X*));
55+
static_assert(__is_same(decltype(*this), const volatile X&));
2856
}

0 commit comments

Comments
 (0)