aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaExprCXX.cpp26
-rw-r--r--test/SemaCXX/composite-pointer-type.cpp10
2 files changed, 24 insertions, 12 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index d0279538e3..bdd47cc2bb 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1884,8 +1884,6 @@ QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2) {
!T2->isPointerType() && !T2->isMemberPointerType())
return QualType();
- // FIXME: Do we need to work on the canonical types?
-
// C++0x 5.9p2
// Pointer conversions and qualification conversions are performed on
// pointer operands to bring them to their composite pointer type. If
@@ -1907,8 +1905,8 @@ QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2) {
}
// Now both have to be pointers or member pointers.
- if (!T1->isPointerType() && !T1->isMemberPointerType() &&
- !T2->isPointerType() && !T2->isMemberPointerType())
+ if ((!T1->isPointerType() && !T1->isMemberPointerType()) ||
+ (!T2->isPointerType() && !T2->isMemberPointerType()))
return QualType();
// Otherwise, of one of the operands has type "pointer to cv1 void," then
@@ -1922,9 +1920,13 @@ QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2) {
// conversions in both directions. If only one works, or if the two composite
// types are the same, we have succeeded.
// FIXME: extended qualifiers?
- llvm::SmallVector<unsigned, 4> QualifierUnion;
- llvm::SmallVector<std::pair<const Type *, const Type *>, 4> MemberOfClass;
- QualType Composite1 = T1, Composite2 = T2;
+ typedef llvm::SmallVector<unsigned, 4> QualifierVector;
+ QualifierVector QualifierUnion;
+ typedef llvm::SmallVector<std::pair<const Type *, const Type *>, 4>
+ ContainingClassVector;
+ ContainingClassVector MemberOfClass;
+ QualType Composite1 = Context.getCanonicalType(T1),
+ Composite2 = Context.getCanonicalType(T2);
do {
const PointerType *Ptr1, *Ptr2;
if ((Ptr1 = Composite1->getAs<PointerType>()) &&
@@ -1956,11 +1958,11 @@ QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2) {
} while (true);
// Rewrap the composites as pointers or member pointers with the union CVRs.
- llvm::SmallVector<std::pair<const Type *, const Type *>, 4>::iterator MOC
- = MemberOfClass.begin();
- for (llvm::SmallVector<unsigned, 4>::iterator
- I = QualifierUnion.begin(),
- E = QualifierUnion.end();
+ ContainingClassVector::reverse_iterator MOC
+ = MemberOfClass.rbegin();
+ for (QualifierVector::reverse_iterator
+ I = QualifierUnion.rbegin(),
+ E = QualifierUnion.rend();
I != E; (void)++I, ++MOC) {
Qualifiers Quals = Qualifiers::fromCVRMask(*I);
if (MOC->first && MOC->second) {
diff --git a/test/SemaCXX/composite-pointer-type.cpp b/test/SemaCXX/composite-pointer-type.cpp
index d8c864dd2a..1eec525f48 100644
--- a/test/SemaCXX/composite-pointer-type.cpp
+++ b/test/SemaCXX/composite-pointer-type.cpp
@@ -33,3 +33,13 @@ int ptrcmp1(void *a, int *b) {
int ptrcmp2(long *a, int *b) {
return a < b; // expected-error{{distinct}}
}
+
+// PR5509 - Multi-level pointers
+int f2() {
+ typedef int *IntPtr;
+ typedef IntPtr *IntPtrPtr;
+ typedef IntPtr const *IntPtrConstPtr;
+ IntPtrConstPtr i = 0;
+ IntPtrPtr j = 0;
+ return i != j;
+}