Fix destructor and assignment operator lookup in the has_nothrow traits.

llvm-svn: 113897
This commit is contained in:
Sebastian Redl 2010-09-14 23:40:14 +00:00
parent f5e56de080
commit 058fc820d7
2 changed files with 19 additions and 14 deletions

View File

@ -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));

View File

@ -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() {