Skip to content

Commit 2f73083

Browse files
committed
Improve checking for subtraction operator
1 parent 611d33d commit 2f73083

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

src/parser/cxx/type_checker.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,8 +1624,6 @@ auto TypeChecker::Visitor::usual_arithmetic_conversion(ExpressionAST*& expr,
16241624
(void)lvalue_to_rvalue_conversion(other);
16251625
adjust_cv(other);
16261626

1627-
if (control()->is_same(expr->type, other->type)) return expr->type;
1628-
16291627
ExpressionAST* savedExpr = expr;
16301628
ExpressionAST* savedOther = other;
16311629

@@ -1991,8 +1989,15 @@ void TypeChecker::Visitor::check_subtraction(BinaryExpressionAST* ast) {
19911989
}
19921990

19931991
if (control()->is_pointer(ast->rightExpression->type)) {
1994-
if (control()->is_same(ast->leftExpression->type,
1995-
ast->rightExpression->type)) {
1992+
auto leftElementType =
1993+
control()->get_element_type(ast->leftExpression->type);
1994+
(void)strip_cv(leftElementType);
1995+
1996+
auto rightElementType =
1997+
control()->get_element_type(ast->rightExpression->type);
1998+
(void)strip_cv(rightElementType);
1999+
2000+
if (control()->is_same(leftElementType, rightElementType)) {
19962001
ast->type = control()->getLongIntType(); // TODO: ptrdiff_t
19972002
} else {
19982003
error(ast->opLoc,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %cxx -verify -fcheck %s
2+
3+
auto main() -> int {
4+
char* p;
5+
const char* cp;
6+
void* vp;
7+
int i = 0;
8+
short s = 0;
9+
10+
static_assert(__is_same(int, decltype('a' - '0')));
11+
static_assert(__is_same(int, decltype('a' - 0)));
12+
static_assert(__is_same(int, decltype('a' - s)));
13+
static_assert(__is_same(long, decltype('a' - 1l)));
14+
static_assert(__is_same(unsigned, decltype('a' - 1u)));
15+
16+
static_assert(__is_same(decltype(p), decltype(p - 0)));
17+
static_assert(__is_same(decltype(p), decltype(p - i)));
18+
19+
static_assert(__is_same(long, decltype(p - p)));
20+
static_assert(__is_same(long, decltype(p - cp)));
21+
22+
// clang-format off
23+
24+
// expected-error@1 {{'char*' and 'void*' are not pointers to compatible types}}
25+
p - vp;
26+
27+
// expected-error@1 {{invalid operands to binary expression 'int' and 'char*'}}
28+
0 - p;
29+
30+
// clang-format on
31+
32+
return 0;
33+
}

0 commit comments

Comments
 (0)