forked from OSchip/llvm-project
Turns out that Sebastian already implemented the logic to compute the
composite pointer type, and his is better! Updated relational- and equality-operator checking accordingly. llvm-svn: 70963
This commit is contained in:
parent
dae1abc7ac
commit
b8420464c6
|
@ -2420,8 +2420,6 @@ public:
|
||||||
QualType rhsType);
|
QualType rhsType);
|
||||||
|
|
||||||
bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
|
bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
|
||||||
QualType CompositePointerType(Expr *LHS, Expr *RHS,
|
|
||||||
bool LHSIsNull, bool RHSIsNull);
|
|
||||||
|
|
||||||
bool PerformImplicitConversion(Expr *&From, QualType ToType,
|
bool PerformImplicitConversion(Expr *&From, QualType ToType,
|
||||||
const char *Flavor,
|
const char *Flavor,
|
||||||
|
|
|
@ -3771,7 +3771,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
||||||
//
|
//
|
||||||
// C++ [expr.eq]p2 uses the same notion for (in)equality
|
// C++ [expr.eq]p2 uses the same notion for (in)equality
|
||||||
// comparisons of pointers.
|
// comparisons of pointers.
|
||||||
QualType T = CompositePointerType(lex, rex, LHSIsNull, RHSIsNull);
|
QualType T = FindCompositePointerType(lex, rex);
|
||||||
if (T.isNull()) {
|
if (T.isNull()) {
|
||||||
Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)
|
Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)
|
||||||
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
|
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
|
||||||
|
|
|
@ -768,77 +768,6 @@ Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Determine the composite pointer type (C++ [expr.rel]p2)
|
|
||||||
/// given the left- and right-hand expressions in a relational
|
|
||||||
/// operation.
|
|
||||||
///
|
|
||||||
/// While the notion of a composite pointer type is only described for
|
|
||||||
/// relational operators (<, >, <=, >=), the same computation is used
|
|
||||||
/// to determine the "common type" used for the equality operators
|
|
||||||
/// (==, !=) when comparing pointers.
|
|
||||||
///
|
|
||||||
/// \param LHS the left-hand operand.
|
|
||||||
/// \param RHS the right-hand operand.
|
|
||||||
/// \param LHSIsNull whether \p LHS is the NULL pointer constant
|
|
||||||
/// \param RHSIsNull whether \p RHS is the NULL pointer constant
|
|
||||||
///
|
|
||||||
/// \returns the composite pointer type, if any, or the null type if
|
|
||||||
/// no such type exists. It is the caller's responsibility to emit
|
|
||||||
/// diagnostic.
|
|
||||||
QualType Sema::CompositePointerType(Expr *LHS, Expr *RHS,
|
|
||||||
bool LHSIsNull, bool RHSIsNull) {
|
|
||||||
// First, determine whether LHS and RHS have pointer types, and what
|
|
||||||
// types they point to.
|
|
||||||
QualType LHSPointee;
|
|
||||||
QualType RHSPointee;
|
|
||||||
if (const PointerType *LHSPtr = LHS->getType()->getAsPointerType())
|
|
||||||
LHSPointee = LHSPtr->getPointeeType();
|
|
||||||
if (const PointerType *RHSPtr = RHS->getType()->getAsPointerType())
|
|
||||||
RHSPointee = RHSPtr->getPointeeType();
|
|
||||||
|
|
||||||
// C++ [expr.rel]p2:
|
|
||||||
// [...] If one operand is a null pointer constant, the composite
|
|
||||||
// pointer type is the type of the other operand.
|
|
||||||
if (LHSIsNull && !RHSPointee.isNull())
|
|
||||||
return RHS->getType();
|
|
||||||
if (RHSIsNull && !LHSPointee.isNull())
|
|
||||||
return LHS->getType();
|
|
||||||
|
|
||||||
// If neither LHS nor RHS has pointer type, we're done.
|
|
||||||
if (LHSPointee.isNull() && RHSPointee.isNull())
|
|
||||||
return QualType();
|
|
||||||
|
|
||||||
// [...] Otherwise, if one of the operands has type "pointer to cv1
|
|
||||||
// void", then the other has type "pointer to cv2 T" and the
|
|
||||||
// composite pointer type is "pointer to cv12 void", where cv12 is
|
|
||||||
// the union of cv1 and cv2.
|
|
||||||
QualType LHSPointeeCanon = Context.getCanonicalType(LHSPointee);
|
|
||||||
QualType RHSPointeeCanon = Context.getCanonicalType(RHSPointee);
|
|
||||||
unsigned CVQuals =
|
|
||||||
(LHSPointeeCanon.getCVRQualifiers() | RHSPointeeCanon.getCVRQualifiers());
|
|
||||||
if (LHSPointeeCanon->isVoidType() || RHSPointeeCanon->isVoidType())
|
|
||||||
return Context.getPointerType(Context.VoidTy.getQualifiedType(CVQuals));
|
|
||||||
|
|
||||||
// [...] Otherwise, the composite pointer type is a pointer 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 FullyQualifiedLHSType
|
|
||||||
= Context.getPointerType(LHSPointee.getQualifiedType(CVQuals));
|
|
||||||
QualType CompositePointerType;
|
|
||||||
bool IncompatibleObjC = false;
|
|
||||||
if (IsPointerConversion(RHS, RHS->getType(), FullyQualifiedLHSType,
|
|
||||||
CompositePointerType, IncompatibleObjC))
|
|
||||||
return CompositePointerType;
|
|
||||||
QualType FullyQualifiedRHSType
|
|
||||||
= Context.getPointerType(RHSPointee.getQualifiedType(CVQuals));
|
|
||||||
if (IsPointerConversion(LHS, LHS->getType(), FullyQualifiedRHSType,
|
|
||||||
CompositePointerType, IncompatibleObjC))
|
|
||||||
return CompositePointerType;
|
|
||||||
|
|
||||||
return QualType();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// PerformImplicitConversion - Perform an implicit conversion of the
|
/// PerformImplicitConversion - Perform an implicit conversion of the
|
||||||
/// expression From to the type ToType. Returns true if there was an
|
/// expression From to the type ToType. Returns true if there was an
|
||||||
/// error, false otherwise. The expression From is replaced with the
|
/// error, false otherwise. The expression From is replaced with the
|
||||||
|
|
Loading…
Reference in New Issue