blob: e5113b2e0e1bee5c560f376047f984104b3d30e3 [file]
// { dg-additional-options "-fmodules-ts -Wtemplate-names-tu-local" }
// { dg-module-cmi M }
// Ignore exposures in these cases
export module M;
namespace {
inline namespace ns {
struct internal_t {};
template <typename T> struct internal_tmpl_t {};
int internal_x;
void internal_ovl(int&) {}
void internal_ovl(internal_t) {}
template <typename T> void internal_tmpl() {}
}
}
export struct ok_inst_tag {};
// The function body for a non-inline function or function template
export void function() {
internal_t i {};
internal_tmpl_t<int> ii {};
internal_ovl(internal_x);
internal_tmpl<int>();
}
export template <typename T> void function_tmpl() {
internal_t i {};
internal_tmpl_t<T> ii {};
internal_ovl(internal_x);
internal_tmpl<T>();
}
template void function_tmpl<ok_inst_tag>();
template <> void function_tmpl<ok_inst_tag*>() {}
// The initializer for a (non-inline) variable or variable template
export int var
= (internal_t{}, internal_tmpl_t<int>{},
internal_ovl(internal_x), internal_tmpl<int>(), 0);
export template <typename T> int var_tmpl
= (internal_t{}, internal_tmpl_t<T>{},
internal_ovl(internal_x), internal_tmpl<T>(), 0);
template <typename T> int var_tmpl<T*> // { dg-warning "refers to TU-local entity" }
= (internal_t{}, internal_tmpl_t<T*>{},
internal_ovl(internal_x), internal_tmpl<T*>(), 0);
template int var_tmpl<ok_inst_tag>;
template <> int var_tmpl<ok_inst_tag*> = 0;
export int* ptr = &internal_x;
export template <typename T> int* ptr_tmpl = &internal_x; // { dg-warning "refers to TU-local entity" }
export int& constant_ref = internal_x;
static_assert (&constant_ref == &internal_x);
// Support exposures in inline vars with dynamic initialisers
export inline int dynamic_var = (internal_ovl(internal_x), 0);
// Friend declarations in a class definition
export struct klass { // { dg-bogus "TU-local" }
friend ns::internal_t;
friend ns::internal_tmpl_t<int>;
friend void ns::internal_ovl(int&);
friend void ns::internal_ovl(internal_t);
friend void ns::internal_tmpl<int>();
template <typename> friend struct ns::internal_tmpl_t;
template <typename> friend void ns::internal_tmpl();
};
export template <typename T>
class klass_tmpl { // { dg-bogus "TU-local" }
friend ns::internal_t;
friend ns::internal_tmpl_t<int>;
friend void ns::internal_ovl(int&);
friend void ns::internal_ovl(internal_t);
friend void ns::internal_tmpl<int>();
template <typename> friend struct ns::internal_tmpl_t;
template <typename> friend void ns::internal_tmpl();
};
template <typename T> class klass_tmpl<T*> { // { dg-bogus "TU-local" }
friend ns::internal_t;
friend ns::internal_tmpl_t<int>;
friend void ns::internal_ovl(int&);
friend void ns::internal_ovl(internal_t);
friend void ns::internal_tmpl<int>();
template <typename> friend struct ns::internal_tmpl_t;
template <typename> friend void ns::internal_tmpl();
};
// Any reference to a non-volatile const object or reference with internal or
// no linkage initialized with a constant expression that is not an ODR-use
static const int value = 123;
static const int& ref = 456;
static const internal_t internal {};
void f(int) {}
export inline void no_odr_use() {
int x = value;
int y = ref;
int z = (internal, 0);
value;
bool b = value < value;
f(value);
}