MSVC accepts that default parameters be redefined for member functions

of template class. The new value is ignored.

This fixes 1 error when parsing MSVC 2010 header files with clang.

llvm-svn: 129240
This commit is contained in:
Francois Pichet 2011-04-10 03:03:52 +00:00
parent 87eb515aba
commit 53fe2bb29e
3 changed files with 25 additions and 3 deletions

View File

@ -1301,6 +1301,8 @@ def err_param_default_argument : Error<
"C does not support default arguments">; "C does not support default arguments">;
def err_param_default_argument_redefinition : Error< def err_param_default_argument_redefinition : Error<
"redefinition of default argument">; "redefinition of default argument">;
def war_param_default_argument_redefinition : ExtWarn<
"redefinition of default argument">;
def err_param_default_argument_missing : Error< def err_param_default_argument_missing : Error<
"missing default argument on parameter">; "missing default argument on parameter">;
def err_param_default_argument_missing_name : Error< def err_param_default_argument_missing_name : Error<

View File

@ -293,12 +293,24 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
// for NewParam to find the last source location in the type... but it // for NewParam to find the last source location in the type... but it
// isn't worth the effort right now. This is the kind of test case that // isn't worth the effort right now. This is the kind of test case that
// is hard to get right: // is hard to get right:
unsigned DiagDefaultParamID =
diag::err_param_default_argument_redefinition;
// MSVC accepts that default parameters be redefined for member functions
// of template class. The new default parameter's value is ignored.
Invalid = true;
if (getLangOptions().Microsoft) {
CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(New);
if (MD && MD->getParent()->getDescribedClassTemplate()) {
DiagDefaultParamID = diag::war_param_default_argument_redefinition;
Invalid = false;
}
}
// int f(int); // int f(int);
// void g(int (*fp)(int) = f); // void g(int (*fp)(int) = f);
// void g(int (*fp)(int) = &f); // void g(int (*fp)(int) = &f);
Diag(NewParam->getLocation(), Diag(NewParam->getLocation(), DiagDefaultParamID)
diag::err_param_default_argument_redefinition)
<< NewParam->getDefaultArgRange(); << NewParam->getDefaultArgRange();
// Look for the function declaration where the default argument was // Look for the function declaration where the default argument was
@ -313,7 +325,6 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
Diag(OldParam->getLocation(), diag::note_previous_definition) Diag(OldParam->getLocation(), diag::note_previous_definition)
<< OldParam->getDefaultArgRange(); << OldParam->getDefaultArgRange();
Invalid = true;
} else if (OldParam->hasDefaultArg()) { } else if (OldParam->hasDefaultArg()) {
// Merge the old default argument into the new parameter. // Merge the old default argument into the new parameter.
// It's important to use getInit() here; getDefaultArg() // It's important to use getInit() here; getDefaultArg()

View File

@ -127,3 +127,12 @@ __declspec(dllimport) void AAA::f2(void) { // expected-error {{dllimport attribu
template <class T>
class BB {
public:
void f(int g = 10 ); // expected-note {{previous definition is here}}
};
template <class T>
void BB<T>::f(int g = 0) { } // expected-warning {{redefinition of default argument}}