summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Sema/TemplateDeduction.h7
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp2
-rw-r--r--clang/test/SemaTemplate/deduction.cpp17
3 files changed, 25 insertions, 1 deletions
diff --git a/clang/include/clang/Sema/TemplateDeduction.h b/clang/include/clang/Sema/TemplateDeduction.h
index f787c2689d8..c0af9f3260b 100644
--- a/clang/include/clang/Sema/TemplateDeduction.h
+++ b/clang/include/clang/Sema/TemplateDeduction.h
@@ -67,6 +67,13 @@ public:
TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete;
+ enum ForBaseTag { ForBase };
+ /// Create temporary template deduction info for speculatively deducing
+ /// against a base class of an argument's type.
+ TemplateDeductionInfo(ForBaseTag, const TemplateDeductionInfo &Info)
+ : Deduced(Info.Deduced), Loc(Info.Loc), DeducedDepth(Info.DeducedDepth),
+ ExplicitArgs(Info.ExplicitArgs) {}
+
/// Returns the location at which template argument is
/// occurring.
SourceLocation getLocation() const {
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 6b865a601f9..1e321d63791 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -1818,7 +1818,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
// If this is a base class, try to perform template argument
// deduction from it.
if (NextT != RecordT) {
- TemplateDeductionInfo BaseInfo(Info.getLocation());
+ TemplateDeductionInfo BaseInfo(TemplateDeductionInfo::ForBase, Info);
Sema::TemplateDeductionResult BaseResult =
DeduceTemplateArguments(S, TemplateParams, SpecParam,
QualType(NextT, 0), BaseInfo, Deduced);
diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp
index 7268912dd6c..5218543ab8a 100644
--- a/clang/test/SemaTemplate/deduction.cpp
+++ b/clang/test/SemaTemplate/deduction.cpp
@@ -564,3 +564,20 @@ namespace nested_packs {
}
#endif
}
+
+namespace PR44890 {
+ template<typename ...Ts>
+ struct tuple {};
+
+ template<int I, typename ...Ts>
+ int get0(const tuple<Ts...> &t) { return 0; }
+
+ template<typename ...Ts> struct tuple_wrapper : tuple<Ts...> {
+ template<int I> int get() { return get0<0, Ts...>(*this); }
+ };
+
+ int f() {
+ tuple_wrapper<int> w;
+ return w.get<0>();
+ }
+}
OpenPOWER on IntegriCloud