aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2012-03-13 08:55:35 +0000
committerJames Molloy <james.molloy@arm.com>2012-03-13 08:55:35 +0000
commit9cda03ff7fc40b727d0cc44b1702dbae09d63f42 (patch)
treec6810bc9b1c12832eb2e96551581f15c0fb1274f /lib/Sema/SemaDeclCXX.cpp
parente37f484ab9a65ce4e5f90adcfa20add4215e0783 (diff)
Ensure that default arguments are handled correctly in sub scopes. For example:
void f () { int g (int a, int b=4); { int g(int a, int b=5); } } should compile. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152621 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index b6866d04e4..79a5d4c98c 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -372,7 +372,8 @@ void Sema::CheckExtraCXXDefaultArguments(Declarator &D) {
// function, once we already know that they have the same
// type. Subroutine of MergeFunctionDecl. Returns true if there was an
// error, false otherwise.
-bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
+bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old,
+ Scope *S) {
bool Invalid = false;
// C++ [dcl.fct.default]p4:
@@ -397,7 +398,16 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
ParmVarDecl *OldParam = Old->getParamDecl(p);
ParmVarDecl *NewParam = New->getParamDecl(p);
- if (OldParam->hasDefaultArg() && NewParam->hasDefaultArg()) {
+ bool OldParamHasDfl = OldParam->hasDefaultArg();
+ bool NewParamHasDfl = NewParam->hasDefaultArg();
+
+ NamedDecl *ND = Old;
+ if (S && !isDeclInScope(ND, New->getDeclContext(), S))
+ // Ignore default parameters of old decl if they are not in
+ // the same scope.
+ OldParamHasDfl = false;
+
+ if (OldParamHasDfl && NewParamHasDfl) {
unsigned DiagDefaultParamID =
diag::err_param_default_argument_redefinition;
@@ -443,7 +453,7 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
Diag(OldParam->getLocation(), diag::note_previous_definition)
<< OldParam->getDefaultArgRange();
- } else if (OldParam->hasDefaultArg()) {
+ } else if (OldParamHasDfl) {
// Merge the old default argument into the new parameter.
// It's important to use getInit() here; getDefaultArg()
// strips off any top-level ExprWithCleanups.
@@ -453,7 +463,7 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
OldParam->getUninstantiatedDefaultArg());
else
NewParam->setDefaultArg(OldParam->getInit());
- } else if (NewParam->hasDefaultArg()) {
+ } else if (NewParamHasDfl) {
if (New->getDescribedFunctionTemplate()) {
// Paragraph 4, quoted above, only applies to non-template functions.
Diag(NewParam->getLocation(),