@@ -2601,9 +2601,109 @@ auto Parser::parse_cpp_cast_expression(ExpressionAST*& yyast,
26012601
26022602 expect (TokenKind::T_RPAREN, ast->rparenLoc );
26032603
2604+ check_cpp_cast_expression (ast);
2605+
2606+ switch (unit->tokenKind (ast->castLoc )) {
2607+ case TokenKind::T_STATIC_CAST:
2608+ if (check_static_cast (ast)) break ;
2609+ if (config_.checkTypes ) {
2610+ parse_error (ast->firstSourceLocation (), " invalid static_cast" );
2611+ }
2612+ break ;
2613+
2614+ default :
2615+ break ;
2616+ } // switch
2617+
26042618 return true ;
26052619}
26062620
2621+ void Parser::check_cpp_cast_expression (CppCastExpressionAST* ast) {
2622+ if (!ast->typeId ) {
2623+ return ;
2624+ }
2625+
2626+ ast->type = ast->typeId ->type ;
2627+
2628+ if (auto refType = type_cast<LvalueReferenceType>(ast->type )) {
2629+ ast->type = refType->elementType ();
2630+ ast->valueCategory = ValueCategory::kLValue ;
2631+ return ;
2632+ }
2633+
2634+ if (auto rvalueRefType = type_cast<RvalueReferenceType>(ast->type )) {
2635+ ast->type = rvalueRefType->elementType ();
2636+
2637+ if (type_cast<FunctionType>(ast->type )) {
2638+ ast->valueCategory = ValueCategory::kLValue ;
2639+ } else {
2640+ ast->valueCategory = ValueCategory::kXValue ;
2641+ }
2642+ }
2643+ }
2644+
2645+ auto Parser::check_static_cast (CppCastExpressionAST* ast) -> bool {
2646+ if (!ast->typeId ) return false ;
2647+ auto targetType = ast->typeId ->type ;
2648+
2649+ if (control_->is_void (targetType)) return true ;
2650+
2651+ if (check_cast_to_derived (targetType, ast->expression )) return true ;
2652+
2653+ const auto cv1 = get_cv_qualifiers (ast->expression ->type );
2654+ const auto cv2 = get_cv_qualifiers (targetType);
2655+ if (!check_cv_qualifiers (cv2, cv1)) return false ;
2656+
2657+ if (implicit_conversion (ast->expression , ast->type )) return true ;
2658+
2659+ return false ;
2660+ };
2661+
2662+ auto Parser::check_cv_qualifiers (CvQualifiers target, CvQualifiers source) const
2663+ -> bool {
2664+ if (source == target) return true ;
2665+ if (source == CvQualifiers::kNone ) return true ;
2666+ if (target == CvQualifiers::kConstVolatile ) return true ;
2667+ return false ;
2668+ }
2669+
2670+ auto Parser::check_cast_to_derived (const Type* targetType,
2671+ ExpressionAST* expression) -> bool {
2672+ if (!is_lvalue (expression)) return false ;
2673+
2674+ auto sourceType = expression->type ;
2675+
2676+ CvQualifiers cv1 = CvQualifiers::kNone ;
2677+ if (auto qualType = type_cast<QualType>(sourceType)) {
2678+ cv1 = qualType->cvQualifiers ();
2679+ sourceType = qualType->elementType ();
2680+ }
2681+
2682+ auto targetRefType = type_cast<LvalueReferenceType>(targetType);
2683+ if (!targetRefType) return false ;
2684+
2685+ targetType = targetRefType->elementType ();
2686+
2687+ CvQualifiers cv2 = CvQualifiers::kNone ;
2688+ if (auto qualType = type_cast<QualType>(targetType)) {
2689+ cv2 = qualType->cvQualifiers ();
2690+ targetType = qualType->elementType ();
2691+ }
2692+
2693+ if (!check_cv_qualifiers (cv2, cv1)) return false ;
2694+
2695+ if (!control_->is_base_of (sourceType, targetType)) return false ;
2696+
2697+ return true ;
2698+ }
2699+
2700+ auto Parser::get_cv_qualifiers (const Type* type) const -> CvQualifiers {
2701+ if (auto qualType = type_cast<QualType>(type)) {
2702+ return qualType->cvQualifiers ();
2703+ }
2704+ return CvQualifiers::kNone ;
2705+ }
2706+
26072707auto Parser::parse_builtin_bit_cast_expression (ExpressionAST*& yyast,
26082708 const ExprContext& ctx) -> bool {
26092709 if (!lookat (TokenKind::T___BUILTIN_BIT_CAST)) return false ;
0 commit comments