perform_instantiation_time_access_checks (pattern, args);
perform_deferred_access_checks (tf_warning_or_error);
+
+ /* Now that we've gone through all the members, instantiate those
+ marked with attribute used. We must do this in the context of
+ the class -- not the context we pushed from, as that might be
+ inside a template and change the behaviour of mark_used. */
+ for (tree x : used)
+ mark_used (x);
+
pop_nested_class ();
maximum_field_alignment = saved_maximum_field_alignment;
if (!fn_context)
if (TYPE_CONTAINS_VPTR_P (type) && CLASSTYPE_KEY_METHOD (type))
vec_safe_push (keyed_classes, type);
- /* Now that we've gone through all the members, instantiate those
- marked with attribute used. */
- for (tree x : used)
- mark_used (x);
-
return type;
}
--- /dev/null
+// { dg-do compile }
+
+template<typename T> struct X {
+ void g () {}
+ void f () __attribute__((__used__)) {}
+};
+
+extern X<int> x; // X<int> incomplete here
+
+template <typename T>
+void Frob (T t) {
+ x.g(); // X<int> completed here, X<int>::f's body marked for instantiation
+}
+
+// Make sure X<int>::f is emitted
+// { dg-final { scan-assembler "_ZN1XIiE1fEv:" } }