@@ -384,7 +384,43 @@ void TypeChecker::Visitor::operator()(MemberExpressionAST* ast) {
384384 if (check_member_access (ast)) return ;
385385}
386386
387- void TypeChecker::Visitor::operator ()(PostIncrExpressionAST* ast) {}
387+ void TypeChecker::Visitor::operator ()(PostIncrExpressionAST* ast) {
388+ if (control ()->is_class (ast->baseExpression ->type )) return ;
389+
390+ const std::string_view op =
391+ ast->op == TokenKind::T_PLUS_PLUS ? " increment" : " decrement" ;
392+
393+ // builtin postfix increment operator
394+ if (!is_glvalue (ast->baseExpression )) {
395+ error (ast->opLoc , std::format (" cannot {} an rvalue of type '{}'" , op,
396+ to_string (ast->baseExpression ->type )));
397+ return ;
398+ }
399+
400+ auto incr_arithmetic = [&]() {
401+ if (!control ()->is_arithmetic (ast->baseExpression ->type )) return false ;
402+ auto ty = control ()->remove_cv (ast->baseExpression ->type );
403+ if (type_cast<BoolType>(ty)) return false ;
404+
405+ ast->type = ty;
406+ ast->valueCategory = ValueCategory::kPrValue ;
407+ return true ;
408+ };
409+
410+ auto incr_pointer = [&]() {
411+ if (!control ()->is_pointer (ast->baseExpression ->type )) return false ;
412+ auto ty = control ()->remove_cv (ast->baseExpression ->type );
413+ ast->type = ty;
414+ ast->valueCategory = ValueCategory::kPrValue ;
415+ return true ;
416+ };
417+
418+ if (incr_arithmetic ()) return ;
419+ if (incr_pointer ()) return ;
420+
421+ error (ast->opLoc , std::format (" cannot {} a value of type '{}'" , op,
422+ to_string (ast->baseExpression ->type )));
423+ }
388424
389425void TypeChecker::Visitor::operator ()(CppCastExpressionAST* ast) {
390426 check_cpp_cast_expression (ast);
0 commit comments