]> granicus.if.org Git - clang/commitdiff
MSVC accepts that default parameters be redefined for member functions
authorFrancois Pichet <pichet2000@gmail.com>
Sun, 10 Apr 2011 03:03:52 +0000 (03:03 +0000)
committerFrancois Pichet <pichet2000@gmail.com>
Sun, 10 Apr 2011 03:03:52 +0000 (03:03 +0000)
of template class. The new value is ignored.

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129240 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/MicrosoftExtensions.cpp

index 92d5dd9e61fa7a887be0fba3df85be07a96f1d54..edcf4ef14fbd9c6c87dcc95332412611a4a38c4f 100644 (file)
@@ -1301,6 +1301,8 @@ def err_param_default_argument : Error<
   "C does not support default arguments">;
 def err_param_default_argument_redefinition : Error<
   "redefinition of default argument">;
+def war_param_default_argument_redefinition : ExtWarn<
+  "redefinition of default argument">;
 def err_param_default_argument_missing : Error<
   "missing default argument on parameter">;
 def err_param_default_argument_missing_name : Error<
index 6d50267289a29bed60ff57ee946f6f1f96d3124f..9dbca64639fe789ddc42dc8fc9bbde7032b97d5f 100644 (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
       // isn't worth the effort right now. This is the kind of test case that
       // 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);
       //   void g(int (*fp)(int) = f);
       //   void g(int (*fp)(int) = &f);
-      Diag(NewParam->getLocation(),
-           diag::err_param_default_argument_redefinition)
+      Diag(NewParam->getLocation(), DiagDefaultParamID)
         << NewParam->getDefaultArgRange();
       
       // 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)
         << OldParam->getDefaultArgRange();
-      Invalid = true;
     } else if (OldParam->hasDefaultArg()) {
       // Merge the old default argument into the new parameter.
       // It's important to use getInit() here;  getDefaultArg()
index 24c24aaf335dddcc9f0ca451a01adaeddd240c0f..2287d26fa8fa78da7790e2bd60a5b35588316858 100644 (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}}
+