aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-01-14 05:37:29 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-01-14 05:37:29 +0000
commit21c8fa87a3517d835072193a59a955ec7f6bf408 (patch)
tree1bd5c804197cdc7053895c89feb7b27aa4b1f320 /lib/Sema/SemaOverload.cpp
parent7b19cb116d0909de72dc8242b0a4e6c5ed39d421 (diff)
PR12008: defer adding the implicit 'const' to a constexpr member function until
we know whether it is static. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172376 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp47
1 files changed, 28 insertions, 19 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index cfabccf5fe..cc9f4df447 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1012,28 +1012,37 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
// 13.1p2). While not part of the definition of the signature,
// this check is important to determine whether these functions
// can be overloaded.
- CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
- CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
+ CXXMethodDecl *OldMethod = dyn_cast<CXXMethodDecl>(Old);
+ CXXMethodDecl *NewMethod = dyn_cast<CXXMethodDecl>(New);
if (OldMethod && NewMethod &&
- !OldMethod->isStatic() && !NewMethod->isStatic() &&
- (OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers() ||
- OldMethod->getRefQualifier() != NewMethod->getRefQualifier())) {
- if (!UseUsingDeclRules &&
- OldMethod->getRefQualifier() != NewMethod->getRefQualifier() &&
- (OldMethod->getRefQualifier() == RQ_None ||
- NewMethod->getRefQualifier() == RQ_None)) {
- // C++0x [over.load]p2:
- // - Member function declarations with the same name and the same
- // parameter-type-list as well as member function template
- // declarations with the same name, the same parameter-type-list, and
- // the same template parameter lists cannot be overloaded if any of
- // them, but not all, have a ref-qualifier (8.3.5).
- Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload)
- << NewMethod->getRefQualifier() << OldMethod->getRefQualifier();
- Diag(OldMethod->getLocation(), diag::note_previous_declaration);
+ !OldMethod->isStatic() && !NewMethod->isStatic()) {
+ if (OldMethod->getRefQualifier() != NewMethod->getRefQualifier()) {
+ if (!UseUsingDeclRules &&
+ (OldMethod->getRefQualifier() == RQ_None ||
+ NewMethod->getRefQualifier() == RQ_None)) {
+ // C++0x [over.load]p2:
+ // - Member function declarations with the same name and the same
+ // parameter-type-list as well as member function template
+ // declarations with the same name, the same parameter-type-list, and
+ // the same template parameter lists cannot be overloaded if any of
+ // them, but not all, have a ref-qualifier (8.3.5).
+ Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload)
+ << NewMethod->getRefQualifier() << OldMethod->getRefQualifier();
+ Diag(OldMethod->getLocation(), diag::note_previous_declaration);
+ }
+ return true;
}
- return true;
+ // We may not have applied the implicit const for a constexpr member
+ // function yet (because we haven't yet resolved whether this is a static
+ // or non-static member function). Add it now, on the assumption that this
+ // is a redeclaration of OldMethod.
+ unsigned NewQuals = NewMethod->getTypeQualifiers();
+ if ((OldMethod->isConstexpr() || NewMethod->isConstexpr()) &&
+ !isa<CXXConstructorDecl>(NewMethod))
+ NewQuals |= Qualifiers::Const;
+ if (OldMethod->getTypeQualifiers() != NewQuals)
+ return true;
}
// The signatures match; this is not an overload.