<div class="gmail_quote">On Thu, Sep 1, 2011 at 7:55 PM, Richard Trieu <span dir="ltr"><<a href="mailto:rtrieu@google.com">rtrieu@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
+/// \brief Diagnose bad pointer comparisons.<br>
+static void diagnoseDistinctPointerComparison(Sema &S, SourceLocation Loc,<br>
+                                              ExprResult &lex, ExprResult &rex,<br></blockquote><div><br></div><div>I would prefer 'LHS' and 'RHS' over 'lex' and 'rex'. The latter aren't very consistent with the style rules, and I find 'lex' particularly confusing in a compiler. =]</div>
<div><br></div><div>Also, "IsError" would be more conforming with the new style rules.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
+                                              bool isError) {<br>
+  S.Diag(Loc, isError ? diag::err_typecheck_comparison_of_distinct_pointers<br>
+                      : diag::ext_typecheck_comparison_of_distinct_pointers)<br>
+    << lex.get()->getType() << rex.get()->getType()<br>
+    << lex.get()->getSourceRange() << rex.get()->getSourceRange();<br>
+}<br>
+<br>
+/// \brief Returns false if the pointers are converted to a composite type,<br>
+/// true otherwise.<br>
+static bool convertPointersToCompositeType(Sema &S, SourceLocation Loc,<br>
+                                               ExprResult &lex,<br>
+                                               ExprResult &rex) {<br>
+  // C++ [expr.rel]p2:<br>
+  //   [...] Pointer conversions (4.10) and qualification<br>
+  //   conversions (4.4) are performed on pointer operands (or on<br>
+  //   a pointer operand and a null pointer constant) to bring<br>
+  //   them to their composite pointer type. [...]<br>
+  //<br>
+  // C++ [expr.eq]p1 uses the same notion for (in)equality<br>
+  // comparisons of pointers.<br>
+<br>
+  // C++ [expr.eq]p2:<br>
+  //   In addition, pointers to members can be compared, or a pointer to<br>
+  //   member and a null pointer constant. Pointer to member conversions<br>
+  //   (4.11) and qualification conversions (4.4) are performed to bring<br>
+  //   them to a common type. If one operand is a null pointer constant,<br>
+  //   the common type is the type of the other operand. Otherwise, the<br>
+  //   common type is a pointer to member type similar (4.4) to the type<br>
+  //   of one of the operands, with a cv-qualification signature (4.4)<br>
+  //   that is the union of the cv-qualification signatures of the operand<br>
+  //   types.<br>
+<br>
+  QualType lType = lex.get()->getType();<br>
+  QualType rType = rex.get()->getType();<br>
+  assert((lType->isPointerType() && rType->isPointerType()) ||<br>
+         (lType->isMemberPointerType() && rType->isMemberPointerType()));<br>
+<br>
+  bool NonStandardCompositeType = false;<br>
+  QualType T = S.FindCompositePointerType(Loc, lex, rex,<br>
+                           S.isSFINAEContext() ? 0 : &NonStandardCompositeType);<br>
+  if (T.isNull()) {<br>
+    diagnoseDistinctPointerComparison(S, Loc, lex, rex, /*isError*/true);<br>
+    return true;<br>
+  }<br>
+<br>
+  if (NonStandardCompositeType)<br>
+    S.Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard)<br>
+      << lType << rType << T << lex.get()->getSourceRange()<br>
+      << rex.get()->getSourceRange();<br>
+<br>
+  lex = S.ImpCastExprToType(lex.take(), T, CK_BitCast);<br>
+  rex = S.ImpCastExprToType(rex.take(), T, CK_BitCast);<br>
+  return false;<br>
+}<br>
+<br>
+static void diagnoseFunctionPointerToVoidComparison(Sema &S, SourceLocation Loc,<br>
+                                                    ExprResult &lex,<br>
+                                                    ExprResult &rex,<br>
+                                                    bool isError) {<br>
+  S.Diag(Loc,isError ? diag::err_typecheck_comparison_of_fptr_to_void<br>
+                     : diag::ext_typecheck_comparison_of_fptr_to_void)<br>
+    << lex.get()->getType() << rex.get()->getType()<br>
+    << lex.get()->getSourceRange() << rex.get()->getSourceRange();<br>
+}<br>
+<br>
 // C99 6.5.8, C++ [expr.rel]<br>
 QualType Sema::CheckCompareOperands(ExprResult &lex, ExprResult &rex,<br>
                                     SourceLocation Loc, unsigned OpaqueOpc,<br>
@@ -6348,12 +6416,8 @@<br>
         // conformance with the C++ standard.<br>
         if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())<br>
             && !LHSIsNull && !RHSIsNull) {<br>
-          Diag(Loc,<br>
-               isSFINAEContext()?<br>
-                   diag::err_typecheck_comparison_of_fptr_to_void<br>
-                 : diag::ext_typecheck_comparison_of_fptr_to_void)<br>
-            << lType << rType << lex.get()->getSourceRange()<br>
-            << rex.get()->getSourceRange();<br>
+          diagnoseFunctionPointerToVoidComparison(<br>
+              *this, Loc, lex, rex, /*isError*/ isSFINAEContext());<br>
<br>
           if (isSFINAEContext())<br>
             return QualType();<br>
@@ -6363,32 +6427,10 @@<br>
         }<br>
       }<br>
<br>
-      // C++ [expr.rel]p2:<br>
-      //   [...] Pointer conversions (4.10) and qualification<br>
-      //   conversions (4.4) are performed on pointer operands (or on<br>
-      //   a pointer operand and a null pointer constant) to bring<br>
-      //   them to their composite pointer type. [...]<br>
-      //<br>
-      // C++ [expr.eq]p1 uses the same notion for (in)equality<br>
-      // comparisons of pointers.<br>
-      bool NonStandardCompositeType = false;<br>
-      QualType T = FindCompositePointerType(Loc, lex, rex,<br>
-                              isSFINAEContext()? 0 : &NonStandardCompositeType);<br>
-      if (T.isNull()) {<br>
-        Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)<br>
-          << lType << rType << lex.get()->getSourceRange()<br>
-          << rex.get()->getSourceRange();<br>
+      if (convertPointersToCompositeType(*this, Loc, lex, rex))<br>
         return QualType();<br>
-      } else if (NonStandardCompositeType) {<br>
-        Diag(Loc,<br>
-             diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard)<br>
-          << lType << rType << T<br>
-          << lex.get()->getSourceRange() << rex.get()->getSourceRange();<br>
-      }<br>
-<br>
-      lex = ImpCastExprToType(lex.take(), T, CK_BitCast);<br>
-      rex = ImpCastExprToType(rex.take(), T, CK_BitCast);<br>
-      return ResultTy;<br>
+      else<br>
+        return ResultTy;<br>
     }<br>
     // C99 6.5.9p2 and C99 6.5.8p2<br>
     if (Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),<br>
@@ -6403,16 +6445,12 @@<br>
                (LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {<br>
       // Valid unless comparison between non-null pointer and function pointer<br>
       if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())<br>
-          && !LHSIsNull && !RHSIsNull) {<br>
-        Diag(Loc, diag::ext_typecheck_comparison_of_fptr_to_void)<br>
-          << lType << rType << lex.get()->getSourceRange()<br>
-          << rex.get()->getSourceRange();<br>
-      }<br>
+          && !LHSIsNull && !RHSIsNull)<br>
+        diagnoseFunctionPointerToVoidComparison(*this, Loc, lex, rex,<br>
+                                                /*isError*/false);<br>
     } else {<br>
       // Invalid<br>
-      Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)<br>
-        << lType << rType << lex.get()->getSourceRange()<br>
-        << rex.get()->getSourceRange();<br>
+      diagnoseDistinctPointerComparison(*this, Loc, lex, rex, /*isError*/false);<br>
     }<br>
     if (LCanPointeeTy != RCanPointeeTy) {<br>
       if (LHSIsNull && !RHSIsNull)<br>
@@ -6454,34 +6492,10 @@<br>
     // Comparison of member pointers.<br>
     if (!isRelational &&<br>
         lType->isMemberPointerType() && rType->isMemberPointerType()) {<br>
-      // C++ [expr.eq]p2:<br>
-      //   In addition, pointers to members can be compared, or a pointer to<br>
-      //   member and a null pointer constant. Pointer to member conversions<br>
-      //   (4.11) and qualification conversions (4.4) are performed to bring<br>
-      //   them to a common type. If one operand is a null pointer constant,<br>
-      //   the common type is the type of the other operand. Otherwise, the<br>
-      //   common type is a pointer to member type similar (4.4) to the type<br>
-      //   of one of the operands, with a cv-qualification signature (4.4)<br>
-      //   that is the union of the cv-qualification signatures of the operand<br>
-      //   types.<br>
-      bool NonStandardCompositeType = false;<br>
-      QualType T = FindCompositePointerType(Loc, lex, rex,<br>
-                              isSFINAEContext()? 0 : &NonStandardCompositeType);<br>
-      if (T.isNull()) {<br>
-        Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)<br>
-          << lType << rType << lex.get()->getSourceRange()<br>
-          << rex.get()->getSourceRange();<br>
+      if (convertPointersToCompositeType(*this, Loc, lex, rex))<br>
         return QualType();<br>
-      } else if (NonStandardCompositeType) {<br>
-        Diag(Loc,<br>
-             diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard)<br>
-          << lType << rType << T<br>
-          << lex.get()->getSourceRange() << rex.get()->getSourceRange();<br>
-      }<br>
-<br>
-      lex = ImpCastExprToType(lex.take(), T, CK_BitCast);<br>
-      rex = ImpCastExprToType(rex.take(), T, CK_BitCast);<br>
-      return ResultTy;<br>
+      else<br>
+        return ResultTy;<br>
     }<br>
<br>
     // Handle scoped enumeration types specifically, since they don't promote<br>
@@ -6537,9 +6551,8 @@<br>
<br>
       if (!LPtrToVoid && !RPtrToVoid &&<br>
           !Context.typesAreCompatible(lType, rType)) {<br>
-        Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)<br>
-          << lType << rType << lex.get()->getSourceRange()<br>
-          << rex.get()->getSourceRange();<br>
+        diagnoseDistinctPointerComparison(*this, Loc, lex, rex,<br>
+                                          /*isError*/false);<br>
       }<br>
       if (LHSIsNull && !RHSIsNull)<br>
         lex = ImpCastExprToType(lex.take(), rType, CK_BitCast);<br>
@@ -6549,9 +6562,8 @@<br>
     }<br>
     if (lType->isObjCObjectPointerType() && rType->isObjCObjectPointerType()) {<br>
       if (!Context.areComparableObjCPointerTypes(lType, rType))<br>
-        Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)<br>
-          << lType << rType << lex.get()->getSourceRange()<br>
-          << rex.get()->getSourceRange();<br>
+        diagnoseDistinctPointerComparison(*this, Loc, lex, rex,<br>
+                                          /*isError*/false);<br>
       if (LHSIsNull && !RHSIsNull)<br>
         lex = ImpCastExprToType(lex.take(), rType, CK_BitCast);<br>
       else<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>