diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2012-12-09 17:45:41 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2012-12-09 17:45:41 +0000 |
commit | fff3248e69c478cfb4d1a1ffdefb808d5885535b (patch) | |
tree | 4d0810b453c6b57e7b4bedb1c70c0aab7c35a12b /lib/Sema/SemaDeclCXX.cpp | |
parent | baab683a5a95fff67439dd069e004487a2c1bc8c (diff) |
Virtual method overrides can no longer have mismatched calling conventions. This fixes PR14339.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169705 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 6f1b489a2d..2fae8c9f91 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -26,6 +26,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeOrdering.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/CXXFieldCollector.h" #include "clang/Sema/DeclSpec.h" @@ -10950,6 +10951,40 @@ void Sema::DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock) { } } +bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
+ const CXXMethodDecl *Old) { + const FunctionType *NewFT = New->getType()->getAs<FunctionType>(); + const FunctionType *OldFT = Old->getType()->getAs<FunctionType>(); + + CallingConv NewCC = NewFT->getCallConv(), OldCC = OldFT->getCallConv(); + + // If the calling conventions match, everything is fine + if (NewCC == OldCC) + return false; + + // If either of the calling conventions are set to "default", we need to pick + // something more sensible based on the target. This supports code where the + // one method explicitly sets thiscall, and another has no explicit calling + // convention. + CallingConv Default = + Context.getTargetInfo().getDefaultCallingConv(TargetInfo::CCMT_Member); + if (NewCC == CC_Default) + NewCC = Default; + if (OldCC == CC_Default) + OldCC = Default; + + // If the calling conventions still don't match, then report the error + if (NewCC != OldCC) { + Diag(New->getLocation(),
+ diag::err_conflicting_overriding_cc_attributes)
+ << New->getDeclName() << New->getType() << Old->getType();
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ return true;
+ } + + return false; +} + bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New, const CXXMethodDecl *Old) { QualType NewTy = New->getType()->getAs<FunctionType>()->getResultType(); |