From: Sebastian Redl Date: Tue, 14 Sep 2010 23:40:14 +0000 (+0000) Subject: Fix destructor and assignment operator lookup in the has_nothrow traits. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f8aca8664512c80a018eb4a4a93c61ad6793abcd;p=clang Fix destructor and assignment operator lookup in the has_nothrow traits. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113897 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 6d8c914654..30ac6189f7 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2008,7 +2008,8 @@ ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait UTT, return BuildUnaryTypeTrait(UTT, KWLoc, TSInfo, RParen); } -static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T) { +static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T, + SourceLocation KeyLoc) { assert(!T->isDependentType() && "Cannot evaluate traits for dependent types."); ASTContext &C = Self.Context; @@ -2118,17 +2119,20 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T) { bool FoundAssign = false; bool AllNoThrow = true; DeclarationName Name = C.DeclarationNames.getCXXOperatorName(OO_Equal); - DeclContext::lookup_const_iterator Op, OpEnd; - for (llvm::tie(Op, OpEnd) = RD->lookup(Name); - Op != OpEnd; ++Op) { - CXXMethodDecl *Operator = cast(*Op); - if (Operator->isCopyAssignmentOperator()) { - FoundAssign = true; - const FunctionProtoType *CPT - = Operator->getType()->getAs(); - if (!CPT->hasEmptyExceptionSpec()) { - AllNoThrow = false; - break; + LookupResult Res(Self, DeclarationNameInfo(Name, KeyLoc), + Sema::LookupOrdinaryName); + if (Self.LookupQualifiedName(Res, RD)) { + for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end(); + Op != OpEnd; ++Op) { + CXXMethodDecl *Operator = cast(*Op); + if (Operator->isCopyAssignmentOperator()) { + FoundAssign = true; + const FunctionProtoType *CPT + = Operator->getType()->getAs(); + if (!CPT->hasEmptyExceptionSpec()) { + AllNoThrow = false; + break; + } } } } @@ -2213,7 +2217,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T) { // then the trait is true, else it is false. if (const RecordType *Record = T->getAs()) { CXXRecordDecl *RD = cast(Record->getDecl()); - if (CXXDestructorDecl *Destructor = RD->getDestructor()) + if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD)) return Destructor->isVirtual(); } return false; @@ -2241,7 +2245,7 @@ ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT, bool Value = false; if (!T->isDependentType()) - Value = EvaluateUnaryTypeTrait(*this, UTT, T); + Value = EvaluateUnaryTypeTrait(*this, UTT, T, KWLoc); return Owned(new (Context) UnaryTypeTraitExpr(KWLoc, UTT, TSInfo, Value, RParen, Context.BoolTy)); diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index d6fccffaac..9328326b1a 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -348,6 +348,7 @@ void has_nothrow_assign() { int t21[T(__has_nothrow_assign(HasMultipleNoThrowCopyAssign))]; int t22[F(__has_nothrow_assign(void))]; int t23[F(__has_nothrow_assign(cvoid))]; + int t24[T(__has_nothrow_assign(HasVirtDest))]; } void has_nothrow_copy() {