r338165 - [Sema] Use a TreeTransform to extract deduction guide parameter types
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 27 14:23:48 PDT 2018
Author: epilk
Date: Fri Jul 27 14:23:48 2018
New Revision: 338165
URL: http://llvm.org/viewvc/llvm-project?rev=338165&view=rev
Log:
[Sema] Use a TreeTransform to extract deduction guide parameter types
Previously, we just canonicalized the type, but this lead to crashes with
parameter types that referred to ParmVarDecls of the constructor. There may be
more cases that this TreeTransform needs to handle though, such as a constructor
parameter type referring to a member in an unevaluated context. Canonicalization
doesn't address these cases either though, so we can address them as-needed in
follow-up commits.
rdar://41330135
Differential revision: https://reviews.llvm.org/D49439
Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=338165&r1=338164&r2=338165&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Jul 27 14:23:48 2018
@@ -1659,6 +1659,23 @@ DeclResult Sema::CheckClassTemplate(
}
namespace {
+/// Tree transform to "extract" a transformed type from a class template's
+/// constructor to a deduction guide.
+class ExtractTypeForDeductionGuide
+ : public TreeTransform<ExtractTypeForDeductionGuide> {
+public:
+ typedef TreeTransform<ExtractTypeForDeductionGuide> Base;
+ ExtractTypeForDeductionGuide(Sema &SemaRef) : Base(SemaRef) {}
+
+ TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); }
+
+ QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
+ return TransformType(
+ TLB,
+ TL.getTypedefNameDecl()->getTypeSourceInfo()->getTypeLoc());
+ }
+};
+
/// Transform to convert portions of a constructor declaration into the
/// corresponding deduction guide, per C++1z [over.match.class.deduct]p1.
struct ConvertConstructorToDeductionGuideTransform {
@@ -1880,9 +1897,7 @@ private:
MultiLevelTemplateArgumentList &Args) {
TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
TypeSourceInfo *NewDI;
- if (!Args.getNumLevels())
- NewDI = OldDI;
- else if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
+ if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
// Expand out the one and only element in each inner pack.
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
NewDI =
@@ -1898,23 +1913,17 @@ private:
if (!NewDI)
return nullptr;
- // Canonicalize the type. This (for instance) replaces references to
- // typedef members of the current instantiations with the definitions of
- // those typedefs, avoiding triggering instantiation of the deduced type
- // during deduction.
- // FIXME: It would be preferable to retain type sugar and source
- // information here (and handle this in substitution instead).
- NewDI = SemaRef.Context.getTrivialTypeSourceInfo(
- SemaRef.Context.getCanonicalType(NewDI->getType()),
- OldParam->getLocation());
+ // Extract the type. This (for instance) replaces references to typedef
+ // members of the current instantiations with the definitions of those
+ // typedefs, avoiding triggering instantiation of the deduced type during
+ // deduction.
+ NewDI = ExtractTypeForDeductionGuide(SemaRef).transform(NewDI);
// Resolving a wording defect, we also inherit default arguments from the
// constructor.
ExprResult NewDefArg;
if (OldParam->hasDefaultArg()) {
- NewDefArg = Args.getNumLevels()
- ? SemaRef.SubstExpr(OldParam->getDefaultArg(), Args)
- : OldParam->getDefaultArg();
+ NewDefArg = SemaRef.SubstExpr(OldParam->getDefaultArg(), Args);
if (NewDefArg.isInvalid())
return nullptr;
}
@@ -1929,6 +1938,7 @@ private:
NewDefArg.get());
NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(),
OldParam->getFunctionScopeIndex());
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
return NewParam;
}
Modified: cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp?rev=338165&r1=338164&r2=338165&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp Fri Jul 27 14:23:48 2018
@@ -373,6 +373,35 @@ void bar(D<int>& d) {
}
}
+namespace rdar41330135 {
+template <int> struct A {};
+template <class T>
+struct S {
+ template <class U>
+ S(T a, U t, A<sizeof(t)>);
+};
+template <class T> struct D {
+ D(T t, A<sizeof(t)>);
+};
+int f() {
+ S s(0, 0, A<sizeof(int)>());
+ D d(0, A<sizeof(int)>());
+}
+
+namespace test_dupls {
+template<unsigned long> struct X {};
+template<typename T> struct A {
+ A(T t, X<sizeof(t)>);
+};
+A a(0, {});
+template<typename U> struct B {
+ B(U u, X<sizeof(u)>);
+};
+B b(0, {});
+}
+
+}
+
#else
// expected-no-diagnostics
More information about the cfe-commits
mailing list