From: Douglas Gregor Date: Wed, 5 Jan 2011 00:13:17 +0000 (+0000) Subject: Many of the built-in operator candidates introduced into overload X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2fdc5e8199e1e239620f2faae88997153703e16f;p=clang 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 --- 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); + } +}