@@ -109,6 +109,14 @@ struct TypeChecker::Visitor {
109109 ExpressionAST*& other)
110110 -> const Type*;
111111
112+ [[nodiscard]] auto get_qualification_combined_type (const Type* left,
113+ const Type* right)
114+ -> const Type*;
115+
116+ [[nodiscard]] auto get_qualification_combined_type (
117+ const Type* left, const Type* right, bool & didChangeTypeOrQualifiers)
118+ -> const Type*;
119+
112120 [[nodiscard]] auto composite_pointer_type (ExpressionAST*& expr,
113121 ExpressionAST*& other)
114122 -> const Type*;
@@ -1736,6 +1744,98 @@ auto TypeChecker::Visitor::usual_arithmetic_conversion(ExpressionAST*& expr,
17361744 return control ()->getIntType ();
17371745}
17381746
1747+ auto TypeChecker::Visitor::get_qualification_combined_type (const Type* left,
1748+ const Type* right)
1749+ -> const Type* {
1750+ bool didChangeTypeOrQualifiers = false ;
1751+
1752+ auto type =
1753+ get_qualification_combined_type (left, right, didChangeTypeOrQualifiers);
1754+
1755+ return type;
1756+ }
1757+
1758+ auto TypeChecker::Visitor::get_qualification_combined_type (
1759+ const Type* left, const Type* right, bool & didChangeTypeOrQualifiers)
1760+ -> const Type* {
1761+ auto check_inputs = [&] {
1762+ if (control ()->is_pointer (left) && control ()->is_pointer (right)) {
1763+ return true ;
1764+ }
1765+
1766+ if (control ()->is_array (left) && control ()->is_array (right)) {
1767+ return true ;
1768+ }
1769+
1770+ return false ;
1771+ };
1772+
1773+ auto cv1 = strip_cv (left);
1774+ auto cv2 = strip_cv (right);
1775+
1776+ if (!check_inputs ()) {
1777+ const auto cv3 = merge_cv (cv1, cv2);
1778+
1779+ if (control ()->is_same (left, right)) {
1780+ return control ()->add_cv (left, cv3);
1781+ }
1782+
1783+ if (control ()->is_base_of (left, right)) {
1784+ return control ()->add_cv (left, cv1);
1785+ }
1786+
1787+ if (control ()->is_base_of (right, left)) {
1788+ return control ()->add_cv (right, cv2);
1789+ }
1790+
1791+ return nullptr ;
1792+ }
1793+
1794+ auto leftElementType = control ()->get_element_type (left);
1795+ if (control ()->is_array (leftElementType)) {
1796+ cv1 = merge_cv (cv1, control ()->get_cv_qualifiers (leftElementType));
1797+ }
1798+
1799+ auto rightElementType = control ()->get_element_type (right);
1800+ if (control ()->is_array (rightElementType)) {
1801+ cv2 = merge_cv (cv2, control ()->get_cv_qualifiers (rightElementType));
1802+ }
1803+
1804+ auto elementType = get_qualification_combined_type (
1805+ leftElementType, rightElementType, didChangeTypeOrQualifiers);
1806+
1807+ if (!elementType) {
1808+ return nullptr ;
1809+ }
1810+
1811+ auto cv3 = merge_cv (cv1, cv2);
1812+
1813+ if (didChangeTypeOrQualifiers) cv3 = cv3 | CvQualifiers::kConst ;
1814+
1815+ if (cv1 != cv3 || cv2 != cv3) didChangeTypeOrQualifiers = true ;
1816+
1817+ elementType = control ()->add_cv (elementType, cv3);
1818+
1819+ if (control ()->is_array (left) && control ()->is_array (right)) {
1820+ auto leftArrayType = type_cast<BoundedArrayType>(left);
1821+ auto rightArrayType = type_cast<BoundedArrayType>(right);
1822+
1823+ if (leftArrayType && rightArrayType) {
1824+ if (leftArrayType->size () != rightArrayType->size ()) return nullptr ;
1825+ return control ()->getBoundedArrayType (elementType, leftArrayType->size ());
1826+ }
1827+
1828+ if (leftArrayType || rightArrayType) {
1829+ // one of arrays is unbounded
1830+ didChangeTypeOrQualifiers = true ;
1831+ }
1832+
1833+ return control ()->getUnboundedArrayType (elementType);
1834+ }
1835+
1836+ return control ()->getPointerType (elementType);
1837+ }
1838+
17391839auto TypeChecker::Visitor::composite_pointer_type (ExpressionAST*& expr,
17401840 ExpressionAST*& other)
17411841 -> const Type* {
@@ -1767,9 +1867,11 @@ auto TypeChecker::Visitor::composite_pointer_type(ExpressionAST*& expr,
17671867 return control ()->getPointerType (control ()->add_cv (t2, cv1));
17681868 }
17691869
1770- // TODO: check for noexcept function pointers
1870+ if (auto type = get_qualification_combined_type (expr->type , other->type )) {
1871+ return type;
1872+ }
17711873
1772- // TODO: check for reference related
1874+ // TODO: check for noexcept function pointers
17731875 }
17741876
17751877 return nullptr ;
0 commit comments