summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-10-21 22:01:30 +0000
committerDouglas Gregor <dgregor@apple.com>2009-10-21 22:01:30 +0000
commitb8440a76c48ceb9ccc00c8b1f4f09ae213d77e22 (patch)
tree7e1173dc13d6e52185632df2ee2528eb440c1238
parent066b61668455c8e3558b2667d4cee4eb3dd17219 (diff)
downloadbcm5719-llvm-b8440a76c48ceb9ccc00c8b1f4f09ae213d77e22.tar.gz
bcm5719-llvm-b8440a76c48ceb9ccc00c8b1f4f09ae213d77e22.zip
Don't generate pointer types for void or base classes when finding
conversion types for builtin overloaded operator candidates; I misread this section in the standard the first time around. llvm-svn: 84788
-rw-r--r--clang/lib/Sema/SemaOverload.cpp38
-rw-r--r--clang/test/SemaCXX/overloaded-builtin-operators.cpp25
2 files changed, 36 insertions, 27 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f5a7d18980c..9611bb20b93 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -3053,32 +3053,6 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
// of types.
if (!AddPointerWithMoreQualifiedTypeVariants(Ty, VisibleQuals))
return;
-
- // Add 'cv void*' to our set of types.
- if (!Ty->isVoidType()) {
- QualType QualVoid
- = Context.getCVRQualifiedType(Context.VoidTy,
- PointeeTy.getCVRQualifiers());
- AddPointerWithMoreQualifiedTypeVariants(Context.getPointerType(QualVoid),
- VisibleQuals);
- }
-
- // If this is a pointer to a class type, add pointers to its bases
- // (with the same level of cv-qualification as the original
- // derived class, of course).
- if (const RecordType *PointeeRec = PointeeTy->getAs<RecordType>()) {
- CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(PointeeRec->getDecl());
- for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
- Base != ClassDecl->bases_end(); ++Base) {
- QualType BaseTy = Context.getCanonicalType(Base->getType());
- BaseTy = Context.getCVRQualifiedType(BaseTy.getUnqualifiedType(),
- PointeeTy.getCVRQualifiers());
- // Add the pointer type, recursively, so that we get all of
- // the indirect base classes, too.
- AddTypesConvertedFrom(Context.getPointerType(BaseTy), false, false,
- VisibleQuals);
- }
- }
} else if (Ty->isMemberPointerType()) {
// Member pointers are far easier, since the pointee can't be converted.
if (!AddMemberPointerWithMoreQualifiedTypeVariants(Ty))
@@ -3224,7 +3198,17 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
Context.UnsignedIntTy, Context.UnsignedLongTy, Context.UnsignedLongLongTy,
Context.FloatTy, Context.DoubleTy, Context.LongDoubleTy
};
-
+ assert(ArithmeticTypes[FirstPromotedIntegralType] == Context.IntTy &&
+ "Invalid first promoted integral type");
+ assert(ArithmeticTypes[LastPromotedIntegralType - 1]
+ == Context.UnsignedLongLongTy &&
+ "Invalid last promoted integral type");
+ assert(ArithmeticTypes[FirstPromotedArithmeticType] == Context.IntTy &&
+ "Invalid first promoted arithmetic type");
+ assert(ArithmeticTypes[LastPromotedArithmeticType - 1]
+ == Context.LongDoubleTy &&
+ "Invalid last promoted arithmetic type");
+
// Find all of the types that the arguments can convert to, but only
// if the operator we're looking at has built-in operator candidates
// that make use of these types.
diff --git a/clang/test/SemaCXX/overloaded-builtin-operators.cpp b/clang/test/SemaCXX/overloaded-builtin-operators.cpp
index 0284b2929b3..13777daf2d2 100644
--- a/clang/test/SemaCXX/overloaded-builtin-operators.cpp
+++ b/clang/test/SemaCXX/overloaded-builtin-operators.cpp
@@ -150,3 +150,28 @@ void test_with_ptrs(VolatileIntPtr vip, ConstIntPtr cip, ShortRef sr,
void test_assign_restrictions(ShortRef& sr) {
sr = (short)0; // expected-error{{no viable overloaded '='}}
}
+
+struct Base { };
+struct Derived1 : Base { };
+struct Derived2 : Base { };
+
+template<typename T>
+struct ConvertibleToPtrOf {
+ operator T*();
+};
+
+bool test_with_base_ptrs(ConvertibleToPtrOf<Derived1> d1,
+ ConvertibleToPtrOf<Derived2> d2) {
+ return d1 == d2; // expected-error{{invalid operands}}
+}
+
+// DR425
+struct A {
+ template< typename T > operator T() const;
+};
+
+void test_dr425(A a) {
+ // FIXME: lots of candidates here!
+ (void)(1.0f * a); // expected-error{{ambiguous}} \
+ // expected-note 81{{candidate}}
+}
OpenPOWER on IntegriCloud