]> granicus.if.org Git - clang/commitdiff
Many of the built-in operator candidates introduced into overload
authorDouglas Gregor <dgregor@apple.com>
Wed, 5 Jan 2011 00:13:17 +0000 (00:13 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 5 Jan 2011 00:13:17 +0000 (00:13 +0000)
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

include/clang/AST/Type.h
lib/Sema/SemaOverload.cpp
lib/Sema/SemaTemplateDeduction.cpp
test/SemaCXX/overloaded-builtin-operators.cpp

index 208b23c7268aa293965ba7adfc7b113c03a6fbe4..887fc184412a60e27fceb204cec560b77ed41b68 100644 (file)
@@ -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;
index a39f12603ce23effc99bc7694a9430147a92f92d..bed67c49cf55a45e2a61a8178c3c32fc0b6f47b9 100644 (file)
@@ -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*)
index bad30b3265d4e82606de34887a5004231e183c07..18bfee301ba23186aa4d93964d11429ccaf099e8 100644 (file)
@@ -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;
index 382f5d973baf0cee68c021b02cd04e03e0b9b7f2..b3c08085a695fbb9833fe85df01a84af72b4b229 100644 (file)
@@ -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);
+  }
+}