diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-09-14 23:40:14 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-09-14 23:40:14 +0000 |
commit | f8aca8664512c80a018eb4a4a93c61ad6793abcd (patch) | |
tree | 6a1cf0964b6ba9e19f333abbcefb9655e51922ed | |
parent | 091cbbdcaa6f990c6ed7cc68b887b4767c0bbd85 (diff) |
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
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 32 | ||||
-rw-r--r-- | test/SemaCXX/type-traits.cpp | 1 |
2 files changed, 19 insertions, 14 deletions
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<CXXMethodDecl>(*Op); - if (Operator->isCopyAssignmentOperator()) { - FoundAssign = true; - const FunctionProtoType *CPT - = Operator->getType()->getAs<FunctionProtoType>(); - 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<CXXMethodDecl>(*Op); + if (Operator->isCopyAssignmentOperator()) { + FoundAssign = true; + const FunctionProtoType *CPT + = Operator->getType()->getAs<FunctionProtoType>(); + 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<RecordType>()) { CXXRecordDecl *RD = cast<CXXRecordDecl>(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() { |