From d85cef5a54074a5f647f45c2218675f7774a909d Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 17 Sep 2009 19:51:30 +0000 Subject: [PATCH] Merge uninstantiated default arguments more carefully, and try not to 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 | 4 +++- lib/Sema/SemaDeclCXX.cpp | 8 ++++++-- test/SemaTemplate/default-expr-arguments.cpp | 6 ++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9f86f1233f..f5a3dc4252 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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(); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 6135368039..75718ddec9 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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. diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp index 74d87e9db9..575283ed8b 100644 --- a/test/SemaTemplate/default-expr-arguments.cpp +++ b/test/SemaTemplate/default-expr-arguments.cpp @@ -1,5 +1,11 @@ // RUN: clang-cc -fsyntax-only -verify %s +template +class C { C(int a0 = 0); }; + +template<> +C::C(int a0); + struct S { }; template void f1(T a, T b = 10) { } // expected-error{{cannot initialize 'b' with an rvalue of type 'int'}}