[cfe-commits] r138994 - /cfe/trunk/lib/Sema/SemaExpr.cpp
Richard Trieu
rtrieu at google.com
Thu Sep 1 19:55:45 PDT 2011
Author: rtrieu
Date: Thu Sep 1 21:55:45 2011
New Revision: 138994
URL: http://llvm.org/viewvc/llvm-project?rev=138994&view=rev
Log:
Reduce code duplication for pointer comparisons in CheckCompareOperands().
Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=138994&r1=138993&r2=138994&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Sep 1 21:55:45 2011
@@ -6167,6 +6167,74 @@
return false;
}
+/// \brief Diagnose bad pointer comparisons.
+static void diagnoseDistinctPointerComparison(Sema &S, SourceLocation Loc,
+ ExprResult &lex, ExprResult &rex,
+ bool isError) {
+ S.Diag(Loc, isError ? diag::err_typecheck_comparison_of_distinct_pointers
+ : diag::ext_typecheck_comparison_of_distinct_pointers)
+ << lex.get()->getType() << rex.get()->getType()
+ << lex.get()->getSourceRange() << rex.get()->getSourceRange();
+}
+
+/// \brief Returns false if the pointers are converted to a composite type,
+/// true otherwise.
+static bool convertPointersToCompositeType(Sema &S, SourceLocation Loc,
+ ExprResult &lex,
+ ExprResult &rex) {
+ // C++ [expr.rel]p2:
+ // [...] Pointer conversions (4.10) and qualification
+ // conversions (4.4) are performed on pointer operands (or on
+ // a pointer operand and a null pointer constant) to bring
+ // them to their composite pointer type. [...]
+ //
+ // C++ [expr.eq]p1 uses the same notion for (in)equality
+ // comparisons of pointers.
+
+ // C++ [expr.eq]p2:
+ // In addition, pointers to members can be compared, or a pointer to
+ // member and a null pointer constant. Pointer to member conversions
+ // (4.11) and qualification conversions (4.4) are performed to bring
+ // them to a common type. If one operand is a null pointer constant,
+ // the common type is the type of the other operand. Otherwise, the
+ // common type is a pointer to member type similar (4.4) to the type
+ // of one of the operands, with a cv-qualification signature (4.4)
+ // that is the union of the cv-qualification signatures of the operand
+ // types.
+
+ QualType lType = lex.get()->getType();
+ QualType rType = rex.get()->getType();
+ assert((lType->isPointerType() && rType->isPointerType()) ||
+ (lType->isMemberPointerType() && rType->isMemberPointerType()));
+
+ bool NonStandardCompositeType = false;
+ QualType T = S.FindCompositePointerType(Loc, lex, rex,
+ S.isSFINAEContext() ? 0 : &NonStandardCompositeType);
+ if (T.isNull()) {
+ diagnoseDistinctPointerComparison(S, Loc, lex, rex, /*isError*/true);
+ return true;
+ }
+
+ if (NonStandardCompositeType)
+ S.Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard)
+ << lType << rType << T << lex.get()->getSourceRange()
+ << rex.get()->getSourceRange();
+
+ lex = S.ImpCastExprToType(lex.take(), T, CK_BitCast);
+ rex = S.ImpCastExprToType(rex.take(), T, CK_BitCast);
+ return false;
+}
+
+static void diagnoseFunctionPointerToVoidComparison(Sema &S, SourceLocation Loc,
+ ExprResult &lex,
+ ExprResult &rex,
+ bool isError) {
+ S.Diag(Loc,isError ? diag::err_typecheck_comparison_of_fptr_to_void
+ : diag::ext_typecheck_comparison_of_fptr_to_void)
+ << lex.get()->getType() << rex.get()->getType()
+ << lex.get()->getSourceRange() << rex.get()->getSourceRange();
+}
+
// C99 6.5.8, C++ [expr.rel]
QualType Sema::CheckCompareOperands(ExprResult &lex, ExprResult &rex,
SourceLocation Loc, unsigned OpaqueOpc,
@@ -6348,12 +6416,8 @@
// conformance with the C++ standard.
if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
&& !LHSIsNull && !RHSIsNull) {
- Diag(Loc,
- isSFINAEContext()?
- diag::err_typecheck_comparison_of_fptr_to_void
- : diag::ext_typecheck_comparison_of_fptr_to_void)
- << lType << rType << lex.get()->getSourceRange()
- << rex.get()->getSourceRange();
+ diagnoseFunctionPointerToVoidComparison(
+ *this, Loc, lex, rex, /*isError*/ isSFINAEContext());
if (isSFINAEContext())
return QualType();
@@ -6363,32 +6427,10 @@
}
}
- // C++ [expr.rel]p2:
- // [...] Pointer conversions (4.10) and qualification
- // conversions (4.4) are performed on pointer operands (or on
- // a pointer operand and a null pointer constant) to bring
- // them to their composite pointer type. [...]
- //
- // C++ [expr.eq]p1 uses the same notion for (in)equality
- // comparisons of pointers.
- bool NonStandardCompositeType = false;
- QualType T = FindCompositePointerType(Loc, lex, rex,
- isSFINAEContext()? 0 : &NonStandardCompositeType);
- if (T.isNull()) {
- Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)
- << lType << rType << lex.get()->getSourceRange()
- << rex.get()->getSourceRange();
+ if (convertPointersToCompositeType(*this, Loc, lex, rex))
return QualType();
- } else if (NonStandardCompositeType) {
- Diag(Loc,
- diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard)
- << lType << rType << T
- << lex.get()->getSourceRange() << rex.get()->getSourceRange();
- }
-
- lex = ImpCastExprToType(lex.take(), T, CK_BitCast);
- rex = ImpCastExprToType(rex.take(), T, CK_BitCast);
- return ResultTy;
+ else
+ return ResultTy;
}
// C99 6.5.9p2 and C99 6.5.8p2
if (Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
@@ -6403,16 +6445,12 @@
(LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {
// Valid unless comparison between non-null pointer and function pointer
if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
- && !LHSIsNull && !RHSIsNull) {
- Diag(Loc, diag::ext_typecheck_comparison_of_fptr_to_void)
- << lType << rType << lex.get()->getSourceRange()
- << rex.get()->getSourceRange();
- }
+ && !LHSIsNull && !RHSIsNull)
+ diagnoseFunctionPointerToVoidComparison(*this, Loc, lex, rex,
+ /*isError*/false);
} else {
// Invalid
- Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
- << lType << rType << lex.get()->getSourceRange()
- << rex.get()->getSourceRange();
+ diagnoseDistinctPointerComparison(*this, Loc, lex, rex, /*isError*/false);
}
if (LCanPointeeTy != RCanPointeeTy) {
if (LHSIsNull && !RHSIsNull)
@@ -6454,34 +6492,10 @@
// Comparison of member pointers.
if (!isRelational &&
lType->isMemberPointerType() && rType->isMemberPointerType()) {
- // C++ [expr.eq]p2:
- // In addition, pointers to members can be compared, or a pointer to
- // member and a null pointer constant. Pointer to member conversions
- // (4.11) and qualification conversions (4.4) are performed to bring
- // them to a common type. If one operand is a null pointer constant,
- // the common type is the type of the other operand. Otherwise, the
- // common type is a pointer to member type similar (4.4) to the type
- // of one of the operands, with a cv-qualification signature (4.4)
- // that is the union of the cv-qualification signatures of the operand
- // types.
- bool NonStandardCompositeType = false;
- QualType T = FindCompositePointerType(Loc, lex, rex,
- isSFINAEContext()? 0 : &NonStandardCompositeType);
- if (T.isNull()) {
- Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)
- << lType << rType << lex.get()->getSourceRange()
- << rex.get()->getSourceRange();
+ if (convertPointersToCompositeType(*this, Loc, lex, rex))
return QualType();
- } else if (NonStandardCompositeType) {
- Diag(Loc,
- diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard)
- << lType << rType << T
- << lex.get()->getSourceRange() << rex.get()->getSourceRange();
- }
-
- lex = ImpCastExprToType(lex.take(), T, CK_BitCast);
- rex = ImpCastExprToType(rex.take(), T, CK_BitCast);
- return ResultTy;
+ else
+ return ResultTy;
}
// Handle scoped enumeration types specifically, since they don't promote
@@ -6537,9 +6551,8 @@
if (!LPtrToVoid && !RPtrToVoid &&
!Context.typesAreCompatible(lType, rType)) {
- Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
- << lType << rType << lex.get()->getSourceRange()
- << rex.get()->getSourceRange();
+ diagnoseDistinctPointerComparison(*this, Loc, lex, rex,
+ /*isError*/false);
}
if (LHSIsNull && !RHSIsNull)
lex = ImpCastExprToType(lex.take(), rType, CK_BitCast);
@@ -6549,9 +6562,8 @@
}
if (lType->isObjCObjectPointerType() && rType->isObjCObjectPointerType()) {
if (!Context.areComparableObjCPointerTypes(lType, rType))
- Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
- << lType << rType << lex.get()->getSourceRange()
- << rex.get()->getSourceRange();
+ diagnoseDistinctPointerComparison(*this, Loc, lex, rex,
+ /*isError*/false);
if (LHSIsNull && !RHSIsNull)
lex = ImpCastExprToType(lex.take(), rType, CK_BitCast);
else
More information about the cfe-commits
mailing list