mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 23:49:22 +08:00
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.
llvm-svn: 152621
This commit is contained in:
@@ -1392,13 +1392,14 @@ public:
|
||||
bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New);
|
||||
void mergeDeclAttributes(Decl *New, Decl *Old, bool MergeDeprecation = true);
|
||||
void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls);
|
||||
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
|
||||
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
|
||||
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S);
|
||||
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
|
||||
Scope *S);
|
||||
void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old);
|
||||
void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
|
||||
void MergeVarDeclTypes(VarDecl *New, VarDecl *Old);
|
||||
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
|
||||
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
|
||||
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
|
||||
|
||||
// AssignmentAction - This is used by all the assignment diagnostic functions
|
||||
// to represent what is actually causing the operation
|
||||
|
||||
@@ -1720,7 +1720,7 @@ static bool canRedefineFunction(const FunctionDecl *FD,
|
||||
/// merged with.
|
||||
///
|
||||
/// Returns true if there was an error, false otherwise.
|
||||
bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
|
||||
bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) {
|
||||
// Verify the old decl was also a function.
|
||||
FunctionDecl *Old = 0;
|
||||
if (FunctionTemplateDecl *OldFunctionTemplate
|
||||
@@ -1950,7 +1950,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
|
||||
}
|
||||
|
||||
if (OldQTypeForComparison == NewQType)
|
||||
return MergeCompatibleFunctionDecls(New, Old);
|
||||
return MergeCompatibleFunctionDecls(New, Old, S);
|
||||
|
||||
// Fall through for conflicting redeclarations and redefinitions.
|
||||
}
|
||||
@@ -1995,7 +1995,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
|
||||
New->setParams(Params);
|
||||
}
|
||||
|
||||
return MergeCompatibleFunctionDecls(New, Old);
|
||||
return MergeCompatibleFunctionDecls(New, Old, S);
|
||||
}
|
||||
|
||||
// GNU C permits a K&R definition to follow a prototype declaration
|
||||
@@ -2056,7 +2056,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
|
||||
New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0],
|
||||
ArgTypes.size(),
|
||||
OldProto->getExtProtoInfo()));
|
||||
return MergeCompatibleFunctionDecls(New, Old);
|
||||
return MergeCompatibleFunctionDecls(New, Old, S);
|
||||
}
|
||||
|
||||
// Fall through to diagnose conflicting types.
|
||||
@@ -2097,7 +2097,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
|
||||
/// redeclaration of Old.
|
||||
///
|
||||
/// \returns false
|
||||
bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
|
||||
bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
|
||||
Scope *S) {
|
||||
// Merge the attributes
|
||||
mergeDeclAttributes(New, Old);
|
||||
|
||||
@@ -2118,7 +2119,7 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
|
||||
Context);
|
||||
|
||||
if (getLangOpts().CPlusPlus)
|
||||
return MergeCXXFunctionDecl(New, Old);
|
||||
return MergeCXXFunctionDecl(New, Old, S);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -5698,7 +5699,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
|
||||
if (Redeclaration) {
|
||||
// NewFD and OldDecl represent declarations that need to be
|
||||
// merged.
|
||||
if (MergeFunctionDecl(NewFD, OldDecl)) {
|
||||
if (MergeFunctionDecl(NewFD, OldDecl, S)) {
|
||||
NewFD->setInvalidDecl();
|
||||
return Redeclaration;
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -63,3 +63,14 @@ void f3() {
|
||||
B *bs = new B[2];
|
||||
delete bs;
|
||||
}
|
||||
|
||||
void f4() {
|
||||
void g4(int a, int b = 7);
|
||||
{
|
||||
void g4(int a, int b = 5);
|
||||
}
|
||||
void g4(int a = 5, int b);
|
||||
|
||||
// CHECK: call void @_Z2g4ii(i32 5, i32 7)
|
||||
g4();
|
||||
}
|
||||
|
||||
@@ -32,3 +32,21 @@ void k(Y y = 17); // expected-error{{no viable conversion}} \
|
||||
|
||||
void kk(Y = 17); // expected-error{{no viable conversion}} \
|
||||
// expected-note{{passing argument to parameter here}}
|
||||
|
||||
int l () {
|
||||
int m(int i, int j, int k = 3);
|
||||
if (1)
|
||||
{
|
||||
int m(int i, int j = 2, int k = 4);
|
||||
m(8);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i () {
|
||||
void j (int f = 4);
|
||||
{
|
||||
void j (int f); // expected-note{{'j' declared here}}
|
||||
j(); // expected-error{{too few arguments to function call, expected 1, have 0}}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user