erichkeane updated this revision to Diff 279609. erichkeane added a comment.
Revert change to cxx_dr_status and update the test to have the right tag. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D84048/new/ https://reviews.llvm.org/D84048 Files: clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/CXX/drs/dr23xx.cpp Index: clang/test/CXX/drs/dr23xx.cpp =================================================================== --- clang/test/CXX/drs/dr23xx.cpp +++ clang/test/CXX/drs/dr23xx.cpp @@ -113,3 +113,26 @@ extern template const int d<const int>; #endif } + +#if __cplusplus >= 201103L +namespace dr2303 { // dr2303: 12 +template <typename... T> +struct A; +template <> +struct A<> {}; +template <typename T, typename... Ts> +struct A<T, Ts...> : A<Ts...> {}; +struct B : A<int> {}; + +template <typename... T> +void f(const A<T...> &); +template <typename... T> +void f2(const A<T...> *); + +void g() { + f(B{}); // This is no longer ambiguous. + B b; + f2(&b); +} +} //namespace dr2303 +#endif Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1792,7 +1792,10 @@ // transformed A can be a derived class of the deduced A. Likewise if // P is a pointer to a class of the form simple-template-id, the // transformed A can be a pointer to a derived class pointed to by the - // deduced A. + // deduced A. However, if there is a class C that is a (direct or + // indirect) base class of D and derived (directly or indirectly) from a + // class B and that would be a valid deduced A, the deduced A cannot be + // B or pointer to B, respectively. // // These alternatives are considered only if type deduction would // otherwise fail. If they yield more than one possible deduced A, the @@ -1812,6 +1815,7 @@ while (!ToVisit.empty()) { // Retrieve the next class in the inheritance hierarchy. const RecordType *NextT = ToVisit.pop_back_val(); + bool SkipBases = false; // If we have already seen this type, skip it. if (!Visited.insert(NextT).second) @@ -1840,17 +1844,28 @@ Info.Param = BaseInfo.Param; Info.FirstArg = BaseInfo.FirstArg; Info.SecondArg = BaseInfo.SecondArg; + + // In order to implement CWG2303 (added the following to p4b3): + // However, if there is a class C that is a (direct or indirect) + // base class of D and derived (directly or indirectly) from a + // class B and that would be a valid deduced A, the deduced A + // cannot be B or pointer to B, respectively. + // We shouldn't visit the bases of a successful match ('C'), as they + // could only be 'B' here. + SkipBases = true; } Deduced = DeducedOrig; } // Visit base classes - CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl()); - for (const auto &Base : Next->bases()) { - assert(Base.getType()->isRecordType() && - "Base class that isn't a record?"); - ToVisit.push_back(Base.getType()->getAs<RecordType>()); + if (!SkipBases) { + CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl()); + for (const auto &Base : Next->bases()) { + assert(Base.getType()->isRecordType() && + "Base class that isn't a record?"); + ToVisit.push_back(Base.getType()->getAs<RecordType>()); + } } }
Index: clang/test/CXX/drs/dr23xx.cpp =================================================================== --- clang/test/CXX/drs/dr23xx.cpp +++ clang/test/CXX/drs/dr23xx.cpp @@ -113,3 +113,26 @@ extern template const int d<const int>; #endif } + +#if __cplusplus >= 201103L +namespace dr2303 { // dr2303: 12 +template <typename... T> +struct A; +template <> +struct A<> {}; +template <typename T, typename... Ts> +struct A<T, Ts...> : A<Ts...> {}; +struct B : A<int> {}; + +template <typename... T> +void f(const A<T...> &); +template <typename... T> +void f2(const A<T...> *); + +void g() { + f(B{}); // This is no longer ambiguous. + B b; + f2(&b); +} +} //namespace dr2303 +#endif Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1792,7 +1792,10 @@ // transformed A can be a derived class of the deduced A. Likewise if // P is a pointer to a class of the form simple-template-id, the // transformed A can be a pointer to a derived class pointed to by the - // deduced A. + // deduced A. However, if there is a class C that is a (direct or + // indirect) base class of D and derived (directly or indirectly) from a + // class B and that would be a valid deduced A, the deduced A cannot be + // B or pointer to B, respectively. // // These alternatives are considered only if type deduction would // otherwise fail. If they yield more than one possible deduced A, the @@ -1812,6 +1815,7 @@ while (!ToVisit.empty()) { // Retrieve the next class in the inheritance hierarchy. const RecordType *NextT = ToVisit.pop_back_val(); + bool SkipBases = false; // If we have already seen this type, skip it. if (!Visited.insert(NextT).second) @@ -1840,17 +1844,28 @@ Info.Param = BaseInfo.Param; Info.FirstArg = BaseInfo.FirstArg; Info.SecondArg = BaseInfo.SecondArg; + + // In order to implement CWG2303 (added the following to p4b3): + // However, if there is a class C that is a (direct or indirect) + // base class of D and derived (directly or indirectly) from a + // class B and that would be a valid deduced A, the deduced A + // cannot be B or pointer to B, respectively. + // We shouldn't visit the bases of a successful match ('C'), as they + // could only be 'B' here. + SkipBases = true; } Deduced = DeducedOrig; } // Visit base classes - CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl()); - for (const auto &Base : Next->bases()) { - assert(Base.getType()->isRecordType() && - "Base class that isn't a record?"); - ToVisit.push_back(Base.getType()->getAs<RecordType>()); + if (!SkipBases) { + CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl()); + for (const auto &Base : Next->bases()) { + assert(Base.getType()->isRecordType() && + "Base class that isn't a record?"); + ToVisit.push_back(Base.getType()->getAs<RecordType>()); + } } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits