r279486 - Fix regression introduced by r279164: only pass definitions as the PatternDef

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 23 12:50:05 PDT 2016


Thanks. Fixed and reapplied as r279557.

On Mon, Aug 22, 2016 at 7:08 PM, Chandler Carruth <chandlerc at gmail.com>
wrote:

> Reverted this per Richard's request in r279500.
>
>
> On Mon, Aug 22, 2016 at 3:33 PM Richard Smith via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> Author: rsmith
>> Date: Mon Aug 22 17:25:03 2016
>> New Revision: 279486
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=279486&view=rev
>> Log:
>> Fix regression introduced by r279164: only pass definitions as the
>> PatternDef
>> to DiagnoseUninstantiableTemplate, teach hasVisibleDefinition to
>> correctly
>> determine whether a function definition is visible, and mark both the
>> function
>> and the template as visible when merging function template definitions to
>> provide hasVisibleDefinition with the relevant information.
>>
>> The change to always pass the right declaration as the PatternDef to
>> DiagnoseUninstantiableTemplate also caused those checks to happen before
>> other
>> diagnostics in InstantiateFunctionDefinition, giving worse diagnostics
>> for the
>> same situations, so I sunk the relevant diagnostics into
>> DiagnoseUninstantiableTemplate. Those parts of this patch are based on
>> changes
>> in reviews.llvm.org/D23492 by Vassil Vassilev.
>>
>> Modified:
>>     cfe/trunk/lib/Sema/SemaDecl.cpp
>>     cfe/trunk/lib/Sema/SemaTemplate.cpp
>>     cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
>>     cfe/trunk/lib/Sema/SemaType.cpp
>>     cfe/trunk/test/Modules/Inputs/merge-template-pattern-visibility/a.h
>>     cfe/trunk/test/Modules/Inputs/merge-template-pattern-visibility/b.h
>>     cfe/trunk/test/Modules/merge-template-pattern-visibility.cpp
>>
>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>> SemaDecl.cpp?rev=279486&r1=279485&r2=279486&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Aug 22 17:25:03 2016
>> @@ -11274,9 +11274,8 @@ Sema::CheckForFunctionRedefinition(Funct
>>      SkipBody->ShouldSkip = true;
>>      if (auto *TD = Definition->getDescribedFunctionTemplate())
>>        makeMergedDefinitionVisible(TD, FD->getLocation());
>> -    else
>> -      makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition),
>> -                                  FD->getLocation());
>> +    makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition),
>> +                                FD->getLocation());
>>      return;
>>    }
>>
>>
>> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>> SemaTemplate.cpp?rev=279486&r1=279485&r2=279486&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Aug 22 17:25:03 2016
>> @@ -487,8 +487,6 @@ bool Sema::DiagnoseUninstantiableTemplat
>>    QualType InstantiationTy;
>>    if (TagDecl *TD = dyn_cast<TagDecl>(Instantiation))
>>      InstantiationTy = Context.getTypeDeclType(TD);
>> -  else
>> -    InstantiationTy = cast<FunctionDecl>(Instantiation)->getType();
>>    if (!Complain || (PatternDef && PatternDef->isInvalidDecl())) {
>>      // Say nothing
>>    } else if (PatternDef) {
>> @@ -500,15 +498,30 @@ bool Sema::DiagnoseUninstantiableTemplat
>>      // we're lexically inside it.
>>      Instantiation->setInvalidDecl();
>>    } else if (InstantiatedFromMember) {
>> -    Diag(PointOfInstantiation,
>> -         diag::err_implicit_instantiate_member_undefined)
>> -      << InstantiationTy;
>> -    Diag(Pattern->getLocation(), diag::note_member_declared_at);
>> +    if (isa<FunctionDecl>(Instantiation)) {
>> +      Diag(PointOfInstantiation,
>> +           diag::err_explicit_instantiation_undefined_member)
>> +        << 1 << Instantiation->getDeclName() <<
>> Instantiation->getDeclContext();
>> +    } else {
>> +      Diag(PointOfInstantiation,
>> +           diag::err_implicit_instantiate_member_undefined)
>> +        << InstantiationTy;
>> +    }
>> +    Diag(Pattern->getLocation(), isa<FunctionDecl>(Instantiation)
>> +                                     ? diag::note_explicit_
>> instantiation_here
>> +                                     : diag::note_member_declared_at);
>>    } else {
>> -    Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
>> -      << (TSK != TSK_ImplicitInstantiation)
>> -      << InstantiationTy;
>> -    Diag(Pattern->getLocation(), diag::note_template_decl_here);
>> +    if (isa<FunctionDecl>(Instantiation))
>> +      Diag(PointOfInstantiation,
>> +           diag::err_explicit_instantiation_undefined_func_template)
>> +        << Pattern;
>> +    else
>> +      Diag(PointOfInstantiation, diag::err_template_
>> instantiate_undefined)
>> +        << (TSK != TSK_ImplicitInstantiation)
>> +        << InstantiationTy;
>> +    Diag(Pattern->getLocation(), isa<FunctionDecl>(Instantiation)
>> +                                     ? diag::note_explicit_
>> instantiation_here
>> +                                     : diag::note_template_decl_here);
>>    }
>>
>>    // In general, Instantiation isn't marked invalid to get more than one
>>
>> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>> SemaTemplateInstantiateDecl.cpp?rev=279486&r1=279485&r2=279486&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Aug 22
>> 17:25:03 2016
>> @@ -3554,23 +3554,38 @@ void Sema::InstantiateFunctionDefinition
>>    const FunctionDecl *PatternDecl = Function->
>> getTemplateInstantiationPattern();
>>    assert(PatternDecl && "instantiating a non-template");
>>
>> -  Stmt *Pattern = PatternDecl->getBody(PatternDecl);
>> -  assert(PatternDecl && "template definition is not a template");
>> -  if (!Pattern) {
>> -    // Try to find a defaulted definition
>> -    PatternDecl->isDefined(PatternDecl);
>> -  }
>> -  assert(PatternDecl && "template definition is not a template");
>> +  const FunctionDecl *PatternDef = PatternDecl->getDefinition();
>> +  Stmt *Pattern = PatternDef->getBody(PatternDef);
>> +  if (PatternDef)
>> +    PatternDecl = PatternDef;
>>
>>    // FIXME: We need to track the instantiation stack in order to know
>> which
>>    // definitions should be visible within this instantiation.
>>    if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function,
>>                                  Function->getInstantiatedFromMemberFunct
>> ion(),
>> -                                     PatternDecl, PatternDecl, TSK,
>> -                                     /*Complain*/DefinitionRequired))
>> -     return;
>> -
>> +                                     PatternDecl, PatternDef, TSK,
>> +                                     /*Complain*/DefinitionRequired)) {
>> +    if (DefinitionRequired)
>> +      Function->setInvalidDecl();
>> +    else if (TSK == TSK_ExplicitInstantiationDefinition) {
>> +      // Try again at the end of the translation unit (at which point a
>> +      // definition will be required).
>> +      assert(!Recursive);
>> +      PendingInstantiations.push_back(
>> +        std::make_pair(Function, PointOfInstantiation));
>> +    } else if (TSK == TSK_ImplicitInstantiation) {
>> +      if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
>> +        Diag(PointOfInstantiation, diag::warn_func_template_missing)
>> +          << Function;
>> +        Diag(PatternDecl->getLocation(), diag::note_forward_template_
>> decl);
>> +        if (getLangOpts().CPlusPlus11)
>> +          Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
>> +            << Function;
>> +      }
>> +    }
>>
>> +    return;
>> +  }
>>
>>    // Postpone late parsed template instantiations.
>>    if (PatternDecl->isLateTemplateParsed() &&
>> @@ -3604,40 +3619,9 @@ void Sema::InstantiateFunctionDefinition
>>      Pattern = PatternDecl->getBody(PatternDecl);
>>    }
>>
>> -  // FIXME: Check if we could sink these diagnostics in
>> -  // DiagnoseUninstantiableTemplate.
>> -  if (!Pattern && !PatternDecl->isDefaulted()) {
>> -    if (DefinitionRequired) {
>> -      if (Function->getPrimaryTemplate())
>> -        Diag(PointOfInstantiation,
>> -             diag::err_explicit_instantiation_undefined_func_template)
>> -          << Function->getPrimaryTemplate();
>> -      else
>> -        Diag(PointOfInstantiation,
>> -             diag::err_explicit_instantiation_undefined_member)
>> -          << 1 << Function->getDeclName() << Function->getDeclContext();
>> -
>> -      if (PatternDecl)
>> -        Diag(PatternDecl->getLocation(),
>> -             diag::note_explicit_instantiation_here);
>> -      Function->setInvalidDecl();
>> -    } else if (TSK == TSK_ExplicitInstantiationDefinition) {
>> -      assert(!Recursive);
>> -      PendingInstantiations.push_back(
>> -        std::make_pair(Function, PointOfInstantiation));
>> -    } else if (TSK == TSK_ImplicitInstantiation) {
>> -      if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
>> -        Diag(PointOfInstantiation, diag::warn_func_template_missing)
>> -          << Function;
>> -        Diag(PatternDecl->getLocation(), diag::note_forward_template_
>> decl);
>> -        if (getLangOpts().CPlusPlus11)
>> -          Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
>> -            << Function;
>> -      }
>> -    }
>> -
>> -    return;
>> -  }
>> +  // Note, we should never try to instantiate a deleted function
>> template.
>> +  assert((Pattern || PatternDecl->isDefaulted()) &&
>> +         "unexpected kind of function template definition");
>>
>>    // C++1y [temp.explicit]p10:
>>    //   Except for inline functions, declarations with types deduced from
>> their
>>
>> Modified: cfe/trunk/lib/Sema/SemaType.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
>> SemaType.cpp?rev=279486&r1=279485&r2=279486&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Aug 22 17:25:03 2016
>> @@ -6890,6 +6890,10 @@ bool Sema::hasVisibleDefinition(NamedDec
>>        return false;
>>      }
>>      D = ED->getDefinition();
>> +  } else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
>> +    if (auto *Pattern = FD->getTemplateInstantiationPattern())
>> +      FD = Pattern;
>> +    D = FD->getDefinition();
>>    }
>>    assert(D && "missing definition for pattern of instantiated
>> definition");
>>
>> @@ -6897,7 +6901,7 @@ bool Sema::hasVisibleDefinition(NamedDec
>>    if (isVisible(D))
>>      return true;
>>
>> -  // The external source may have additional definitions of this type
>> that are
>> +  // The external source may have additional definitions of this entity
>> that are
>>    // visible, so complete the redeclaration chain now and ask again.
>>    if (auto *Source = Context.getExternalSource()) {
>>      Source->CompleteRedeclChain(D);
>>
>> Modified: cfe/trunk/test/Modules/Inputs/merge-template-pattern-
>> visibility/a.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
>> Modules/Inputs/merge-template-pattern-visibility/a.h?rev=
>> 279486&r1=279485&r2=279486&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/test/Modules/Inputs/merge-template-pattern-visibility/a.h
>> (original)
>> +++ cfe/trunk/test/Modules/Inputs/merge-template-pattern-visibility/a.h
>> Mon Aug 22 17:25:03 2016
>> @@ -3,3 +3,4 @@ template<typename T> struct B;
>>
>>  template<typename, typename> struct A {};
>>  template<typename T> struct B : A<T> {};
>> +template<typename T> inline auto C(T) {}
>>
>> Modified: cfe/trunk/test/Modules/Inputs/merge-template-pattern-
>> visibility/b.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
>> Modules/Inputs/merge-template-pattern-visibility/b.h?rev=
>> 279486&r1=279485&r2=279486&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/test/Modules/Inputs/merge-template-pattern-visibility/b.h
>> (original)
>> +++ cfe/trunk/test/Modules/Inputs/merge-template-pattern-visibility/b.h
>> Mon Aug 22 17:25:03 2016
>> @@ -3,7 +3,9 @@ template<typename T> struct B;
>>
>>  template<typename, typename> struct A {};
>>  template<typename T> struct B : A<T> {};
>> +template<typename T> inline auto C(T) {}
>>
>>  inline void f() {
>>    B<int> bi;
>> +  C(0);
>>  }
>>
>> Modified: cfe/trunk/test/Modules/merge-template-pattern-visibility.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
>> Modules/merge-template-pattern-visibility.cpp?rev=
>> 279486&r1=279485&r2=279486&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/test/Modules/merge-template-pattern-visibility.cpp
>> (original)
>> +++ cfe/trunk/test/Modules/merge-template-pattern-visibility.cpp Mon Aug
>> 22 17:25:03 2016
>> @@ -1,4 +1,4 @@
>>  // RUN: rm -rf %t
>> -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t
>> -fno-modules-error-recovery \
>> +// RUN: %clang_cc1 -fmodules -fno-modules-error-recovery -std=c++14 \
>>  // RUN:            -fmodule-name=X -emit-module %S/Inputs/merge-template-
>> pattern-visibility/module.modulemap -x c++ \
>> -// RUN:            -fmodules-local-submodule-visibility
>> +// RUN:            -fmodules-local-submodule-visibility -o %t/X.pcm
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160823/730704b6/attachment-0001.html>


More information about the cfe-commits mailing list