aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-05 00:13:17 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-05 00:13:17 +0000
commit2fdc5e8199e1e239620f2faae88997153703e16f (patch)
tree6f41335285ade341873ec5d707b4302db114dd82
parenta8311be2b85171e41cc82de12cdb43eaa026ce6e (diff)
Many of the built-in operator candidates introduced into overload
resolution require that the pointed-to type be an object type, but we weren't filtering out non-object types. Do so, fixing PR7851. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122853 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Type.h8
-rw-r--r--lib/Sema/SemaOverload.cpp17
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp4
-rw-r--r--test/SemaCXX/overloaded-builtin-operators.cpp17
4 files changed, 42 insertions, 4 deletions
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 208b23c726..887fc18441 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1079,6 +1079,14 @@ public:
bool isIncompleteOrObjectType() const {
return !isFunctionType();
}
+
+ /// \brief Determine whether this type is an object type.
+ bool isObjectType() const {
+ // C++ [basic.types]p8:
+ // An object type is a (possibly cv-qualified) type that is not a
+ // function type, not a reference type, and not a void type.
+ return !isReferenceType() && !isFunctionType() && !isVoidType();
+ }
/// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
bool isPODType() const;
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index a39f12603c..bed67c49cf 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -4821,7 +4821,7 @@ public:
PtrEnd = CandidateTypes[0].pointer_end();
Ptr != PtrEnd; ++Ptr) {
// Skip pointer types that aren't pointers to object types.
- if (!(*Ptr)->getPointeeType()->isIncompleteOrObjectType())
+ if (!(*Ptr)->getPointeeType()->isObjectType())
continue;
addPlusPlusMinusMinusStyleOverloads(*Ptr,
@@ -4847,6 +4847,9 @@ public:
Ptr != PtrEnd; ++Ptr) {
QualType ParamTy = *Ptr;
QualType PointeeTy = ParamTy->getPointeeType();
+ if (!PointeeTy->isObjectType() && !PointeeTy->isFunctionType())
+ continue;
+
S.AddBuiltinCandidate(S.Context.getLValueReferenceType(PointeeTy),
&ParamTy, Args, 1, CandidateSet);
}
@@ -5066,6 +5069,10 @@ public:
Ptr = CandidateTypes[Arg].pointer_begin(),
PtrEnd = CandidateTypes[Arg].pointer_end();
Ptr != PtrEnd; ++Ptr) {
+ QualType PointeeTy = (*Ptr)->getPointeeType();
+ if (!PointeeTy->isObjectType())
+ continue;
+
AsymetricParamTypes[Arg] = *Ptr;
if (Arg == 0 || Op == OO_Plus) {
// operator+(T*, ptrdiff_t) or operator-(T*, ptrdiff_t)
@@ -5251,6 +5258,8 @@ public:
// If this is operator=, keep track of the builtin candidates we added.
if (isEqualOp)
AddedTypes.insert(S.Context.getCanonicalType(*Ptr));
+ else if (!(*Ptr)->getPointeeType()->isObjectType())
+ continue;
// non-volatile version
QualType ParamTypes[2] = {
@@ -5443,6 +5452,9 @@ public:
Ptr != PtrEnd; ++Ptr) {
QualType ParamTypes[2] = { *Ptr, S.Context.getPointerDiffType() };
QualType PointeeType = (*Ptr)->getPointeeType();
+ if (!PointeeType->isObjectType())
+ continue;
+
QualType ResultTy = S.Context.getLValueReferenceType(PointeeType);
// T& operator[](T*, ptrdiff_t)
@@ -5455,6 +5467,9 @@ public:
Ptr != PtrEnd; ++Ptr) {
QualType ParamTypes[2] = { S.Context.getPointerDiffType(), *Ptr };
QualType PointeeType = (*Ptr)->getPointeeType();
+ if (!PointeeType->isObjectType())
+ continue;
+
QualType ResultTy = S.Context.getLValueReferenceType(PointeeType);
// T& operator[](ptrdiff_t, T*)
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index bad30b3265..18bfee301b 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -1515,10 +1515,8 @@ FinishTemplateArgumentDeduction(Sema &S,
= ClassTemplate->getTemplateParameters();
for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
TemplateArgument InstArg = ConvertedInstArgs.data()[I];
- Decl *Param = TemplateParams->getParam(I);
-
if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg)) {
- Info.Param = makeTemplateParameter(Param);
+ Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
Info.FirstArg = TemplateArgs[I];
Info.SecondArg = InstArg;
return Sema::TDK_NonDeducedMismatch;
diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp
index 382f5d973b..b3c08085a6 100644
--- a/test/SemaCXX/overloaded-builtin-operators.cpp
+++ b/test/SemaCXX/overloaded-builtin-operators.cpp
@@ -220,3 +220,20 @@ namespace PR8477 {
return foo[zero] == zero;
}
}
+
+namespace PR7851 {
+ struct X {
+ operator const void *() const;
+ operator void *();
+
+ operator const unsigned *() const;
+ operator unsigned *();
+ };
+
+ void f() {
+ X x;
+ x[0] = 1;
+ *x = 0;
+ (void)(x - x);
+ }
+}