[cfe-commits] r152621 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/CodeGenCXX/default-arguments.cpp test/SemaCXX/default1.cpp
James Molloy
james.molloy at arm.com
Tue Mar 13 01:55:35 PDT 2012
Author: jamesm
Date: Tue Mar 13 03:55:35 2012
New Revision: 152621
URL: http://llvm.org/viewvc/llvm-project?rev=152621&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CodeGenCXX/default-arguments.cpp
cfe/trunk/test/SemaCXX/default1.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=152621&r1=152620&r2=152621&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Mar 13 03:55:35 2012
@@ -1392,13 +1392,14 @@
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
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=152621&r1=152620&r2=152621&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Mar 13 03:55:35 2012
@@ -1720,7 +1720,7 @@
/// 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 @@
}
if (OldQTypeForComparison == NewQType)
- return MergeCompatibleFunctionDecls(New, Old);
+ return MergeCompatibleFunctionDecls(New, Old, S);
// Fall through for conflicting redeclarations and redefinitions.
}
@@ -1995,7 +1995,7 @@
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 @@
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 @@
/// 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 @@
Context);
if (getLangOpts().CPlusPlus)
- return MergeCXXFunctionDecl(New, Old);
+ return MergeCXXFunctionDecl(New, Old, S);
return false;
}
@@ -5698,7 +5699,7 @@
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;
}
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=152621&r1=152620&r2=152621&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Mar 13 03:55:35 2012
@@ -372,7 +372,8 @@
// 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 @@
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 @@
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 @@
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(),
Modified: cfe/trunk/test/CodeGenCXX/default-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/default-arguments.cpp?rev=152621&r1=152620&r2=152621&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/default-arguments.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/default-arguments.cpp Tue Mar 13 03:55:35 2012
@@ -63,3 +63,14 @@
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();
+}
Modified: cfe/trunk/test/SemaCXX/default1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/default1.cpp?rev=152621&r1=152620&r2=152621&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/default1.cpp (original)
+++ cfe/trunk/test/SemaCXX/default1.cpp Tue Mar 13 03:55:35 2012
@@ -32,3 +32,21 @@
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}}
+ }
+}
More information about the cfe-commits
mailing list