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 6d8c914..30ac618 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2008,7 +2008,8 @@
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 @@
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 @@
// 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 @@
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 d6fccff..9328326 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -348,6 +348,7 @@
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() {