aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-11-16 21:03:45 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-11-16 21:03:45 +0000
commita439e6f8f57eaeb0a02960d8f2d8ad124ba8b3d5 (patch)
treeda4ed25cf4e4feda79d34f5cd60be1c882f04c68
parent1468ac71124bc689d95e07a048505a21e8980269 (diff)
Repair broken FindCompositePointerType. Correct early termination condition. Get CVR qualifiers from canonical types. Traverse collected qualifiers in reverse order on rebuilding the pointer, so that we don't swap inner and outer qualifiers. That last one fixes PR5509.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88960 91177308-0d34-0410-b5e6-96231b3b80d8
-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;
+}