@@ -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