From: Douglas Gregor Date: Fri, 21 May 2010 20:29:55 +0000 (+0000) Subject: Use CanQualType to enforce the use of a canonical type argument to X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e0d5fe2a417b84ac8b51927ebeb8f1c9ae492760;p=clang Use CanQualType to enforce the use of a canonical type argument to CXXBasePaths::isAmbiguous(), rather than just asserting that we have a canonical type. Fixes PR7176. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104374 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index edd633e8e1..5a84e404a1 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -196,7 +196,7 @@ public: /// \brief Determine whether the path from the most-derived type to the /// given base type is ambiguous (i.e., it refers to multiple subobjects of /// the same base type). - bool isAmbiguous(QualType BaseType); + bool isAmbiguous(CanQualType BaseType); /// \brief Whether we are finding multiple paths to detect ambiguities. bool isFindingAmbiguities() const { return FindAmbiguities; } diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp index a9f2230458..d616e42e00 100644 --- a/lib/AST/CXXInheritance.cpp +++ b/lib/AST/CXXInheritance.cpp @@ -49,9 +49,8 @@ CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() { /// ambiguous, i.e., there are two or more paths that refer to /// different base class subobjects of the same type. BaseType must be /// an unqualified, canonical class type. -bool CXXBasePaths::isAmbiguous(QualType BaseType) { - assert(BaseType.isCanonical() && "Base type must be the canonical type"); - assert(BaseType.hasQualifiers() == 0 && "Base type must be unqualified"); +bool CXXBasePaths::isAmbiguous(CanQualType BaseType) { + BaseType = BaseType.getUnqualifiedType(); std::pair& Subobjects = ClassSubobjects[BaseType]; return Subobjects.second + (Subobjects.first? 1 : 0) > 1; } diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index c8eae2fb0a..9b95552554 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -859,7 +859,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, } // B is a base of D. But is it an allowed base? If not, it's a hard error. - if (Paths.isAmbiguous(DestClass)) { + if (Paths.isAmbiguous(Self.Context.getCanonicalType(DestClass))) { Paths.clear(); Paths.setRecordingPaths(true); bool StillOkay = Self.IsDerivedFrom(SrcClass, DestClass, Paths); diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index 53e9385749..7d73fe4777 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -389,7 +389,7 @@ bool Sema::CheckExceptionSpecSubset( if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths)) continue; - if (Paths.isAmbiguous(CanonicalSuperT)) + if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT))) continue; // Do this check from a context without privileges. diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp index be25cbdb7e..9d5cd2fc92 100644 --- a/test/SemaCXX/member-pointer.cpp +++ b/test/SemaCXX/member-pointer.cpp @@ -157,3 +157,20 @@ namespace pr6783 { return object->*p2m; // expected-error {{left hand operand to ->*}} } } + +namespace PR7176 { + namespace base + { + struct Process + { }; + struct Continuous : Process + { + bool cond(); + }; + } + + typedef bool( base::Process::*Condition )(); + + void m() + { (void)(Condition) &base::Continuous::cond; } +}