]> granicus.if.org Git - clang/commitdiff
Merge uninstantiated default arguments more carefully, and try not to
authorDouglas Gregor <dgregor@apple.com>
Thu, 17 Sep 2009 19:51:30 +0000 (19:51 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 17 Sep 2009 19:51:30 +0000 (19:51 +0000)
complain about specializations of member functions that are not
definitions. Fixes PR4995.

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

lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
test/SemaTemplate/default-expr-arguments.cpp

index 9f86f1233f5dd12efe818568042c1312cd09e84e..f5a3dc42525f681504f8e14338d57cef076de463 100644 (file)
@@ -2684,7 +2684,9 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   if (D.getCXXScopeSpec().isSet() && !NewFD->isInvalidDecl()) {
     // An out-of-line member function declaration must also be a
     // definition (C++ [dcl.meaning]p1).
-    if (!IsFunctionDefinition && !isFriend) {
+    // FIXME: Find a better way to recognize out-of-line specializations!
+    if (!IsFunctionDefinition && !isFriend &&
+        !(TemplateParamLists.size() && !FunctionTemplate)) {
       Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
         << D.getCXXScopeSpec().getRange();
       NewFD->setInvalidDecl();
index 6135368039949f4ee9033e9a76fb66303cb40f5d..75718ddec9e78dd64cd76aa8829e3843c7c31b80 100644 (file)
@@ -280,9 +280,13 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
       Diag(OldParam->getLocation(), diag::note_previous_definition)
         << OldParam->getDefaultArgRange();
       Invalid = true;
-    } else if (OldParam->getDefaultArg()) {
+    } else if (OldParam->hasDefaultArg()) {
       // Merge the old default argument into the new parameter
-      NewParam->setDefaultArg(OldParam->getDefaultArg());
+      if (OldParam->hasUninstantiatedDefaultArg())
+        NewParam->setUninstantiatedDefaultArg(
+                                      OldParam->getUninstantiatedDefaultArg());
+      else
+        NewParam->setDefaultArg(OldParam->getDefaultArg());
     } else if (NewParam->hasDefaultArg()) {
       if (New->getDescribedFunctionTemplate()) {
         // Paragraph 4, quoted above, only applies to non-template functions.
index 74d87e9db905e1222c4ff513f98e77545d3aab43..575283ed8b513b9fcaf384b4ed238ae0617ce33c 100644 (file)
@@ -1,5 +1,11 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
+template<typename T>
+class C { C(int a0 = 0); };
+
+template<>
+C<char>::C(int a0);
+
 struct S { };
 
 template<typename T> void f1(T a, T b = 10) { } // expected-error{{cannot initialize 'b' with an rvalue of type 'int'}}