@@ -5781,7 +5781,11 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */)
&& DECL_OMP_DECLARE_REDUCTION_P (decl)))
maybe_instantiate_decl (decl);
- if (processing_template_decl || in_template_function ())
+ /* We don't want to instantiate templates based on uses from other
+ uninstantiated templates. Since processing_template_decl is cleared
+ during instantiate_non_dependent_expr, we check current_template_parms
+ as well. */
+ if (processing_template_decl || current_template_parms)
return true;
/* Check this too in case we're within instantiate_non_dependent_expr. */
@@ -610,6 +610,9 @@ maybe_instantiate_nsdmi_init (tree member, tsubst_flags_t complain)
push_deferring_access_checks (dk_no_deferred);
pushed = true;
}
+ /* Make sure current_template_parms is cleared so that mark_used
+ is uninhibited. */
+ auto ctpo = make_temp_override (current_template_parms, NULL_TREE);
/* If we didn't push_to_top_level, still step out of constructor
scope so build_base_path doesn't try to use its __in_chrg. */
new file mode 100644
@@ -0,0 +1,23 @@
+// PR c++/109506
+// { dg-do link { target c++11 } }
+// { dg-additional-options "-fchecking=2" }
+
+template<class T>
+struct foo {
+ foo() { };
+};
+
+template<class T>
+class bar {
+ foo<int> alloc_{};
+};
+
+template<class T>
+bar<int> func1() {
+ return bar<int>{};
+}
+
+int main() {
+ func1<int>();
+}
+
@@ -1,7 +1,7 @@
// PR c++/89973
// { dg-do compile { target c++14 } }
-constexpr int a(); // { dg-warning "used but never defined" }
+constexpr int a();
template <typename>
constexpr void *b = a(); // { dg-error "invalid conversion" }