@@ -50,6 +50,14 @@ struct TypeChecker::Visitor {
5050 return check.unit_ ->control ();
5151 }
5252
53+ [[nodiscard]] auto is_parsing_c () const {
54+ return check.unit_ ->language () == LanguageKind::kC ;
55+ }
56+
57+ [[nodiscard]] auto is_parsing_cxx () const {
58+ return check.unit_ ->language () == LanguageKind::kCXX ;
59+ }
60+
5361 void error (SourceLocation loc, std::string message) {
5462 if (!check.reportErrors_ ) return ;
5563 check.unit_ ->error (loc, std::move (message));
@@ -498,7 +506,16 @@ void TypeChecker::Visitor::operator()(PostIncrExpressionAST* ast) {
498506 }
499507
500508 auto incr_arithmetic = [&]() {
501- if (!control ()->is_arithmetic (ast->baseExpression ->type )) return false ;
509+ if (control ()->is_const (ast->baseExpression ->type )) return false ;
510+
511+ if (is_parsing_cxx () &&
512+ !control ()->is_arithmetic (ast->baseExpression ->type ))
513+ return false ;
514+
515+ if (is_parsing_c () &&
516+ !control ()->is_arithmetic_or_unscoped_enum (ast->baseExpression ->type ))
517+ return false ;
518+
502519 auto ty = control ()->remove_cv (ast->baseExpression ->type );
503520 if (type_cast<BoolType>(ty)) return false ;
504521
@@ -798,20 +815,23 @@ void TypeChecker::Visitor::operator()(UnaryExpressionAST* ast) {
798815 break ;
799816 }
800817
801- auto ty = ast->expression ->type ;
818+ if (!control ()->is_const (ast->expression ->type )) {
819+ const auto ty = ast->expression ->type ;
802820
803- if (control ()->is_arithmetic (ty) && !control ()->is_const (ty)) {
804- ast->type = ty;
805- ast->valueCategory = ValueCategory::kLValue ;
806- break ;
807- }
808-
809- if (auto ptrTy = type_cast<PointerType>(ty)) {
810- if (!control ()->is_void (ptrTy->elementType ())) {
811- ast->type = ptrTy;
821+ if (is_parsing_cxx () ? control ()->is_arithmetic (ty)
822+ : control ()->is_arithmetic_or_unscoped_enum (ty)) {
823+ ast->type = ty;
812824 ast->valueCategory = ValueCategory::kLValue ;
813825 break ;
814826 }
827+
828+ if (auto ptrTy = type_cast<PointerType>(ty)) {
829+ if (!control ()->is_void (ptrTy->elementType ())) {
830+ ast->type = ptrTy;
831+ ast->valueCategory = ValueCategory::kLValue ;
832+ break ;
833+ }
834+ }
815835 }
816836
817837 error (ast->opLoc , std::format (" cannot increment a value of type '{}'" ,
@@ -826,20 +846,23 @@ void TypeChecker::Visitor::operator()(UnaryExpressionAST* ast) {
826846 break ;
827847 }
828848
829- auto ty = ast->expression ->type ;
830-
831- if (control ()->is_arithmetic (ty) && !control ()->is_const (ty)) {
832- ast->type = ty;
833- ast->valueCategory = ValueCategory::kLValue ;
834- break ;
835- }
849+ if (!control ()->is_const (ast->expression ->type )) {
850+ auto ty = ast->expression ->type ;
836851
837- if (auto ptrTy = type_cast<PointerType> (ty)) {
838- if (ptrTy && ! control ()->is_void (ptrTy-> elementType () )) {
839- ast->type = ptrTy ;
852+ if (is_parsing_cxx () ? control ()-> is_arithmetic (ty)
853+ : control ()->is_arithmetic_or_unscoped_enum (ty )) {
854+ ast->type = ty ;
840855 ast->valueCategory = ValueCategory::kLValue ;
841856 break ;
842857 }
858+
859+ if (auto ptrTy = type_cast<PointerType>(ty)) {
860+ if (ptrTy && !control ()->is_void (ptrTy->elementType ())) {
861+ ast->type = ptrTy;
862+ ast->valueCategory = ValueCategory::kLValue ;
863+ break ;
864+ }
865+ }
843866 }
844867
845868 error (ast->opLoc , std::format (" cannot decrement a value of type '{}'" ,
0 commit comments