xref: /llvm-project/clang/test/SemaCXX/libcxx_valarray_hack.cpp (revision 0d923af49270ef4beb5d479dac5bda80fc0082ef)
1*0d923af4SRichard Smith // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify
2*0d923af4SRichard Smith 
3*0d923af4SRichard Smith // This is a test for a hack in Clang that works around an issue with libc++'s
4*0d923af4SRichard Smith // <valarray> implementation. The <valarray> header contains explicit
5*0d923af4SRichard Smith // instantiations of functions that it declared with the internal_linkage
6*0d923af4SRichard Smith // attribute, which are ill-formed by [temp.explicit]p13 (and meaningless).
7*0d923af4SRichard Smith 
8*0d923af4SRichard Smith #ifdef BE_THE_HEADER
9*0d923af4SRichard Smith 
10*0d923af4SRichard Smith #pragma GCC system_header
11*0d923af4SRichard Smith namespace std {
12*0d923af4SRichard Smith   using size_t = __SIZE_TYPE__;
13*0d923af4SRichard Smith   template<typename T> struct valarray {
valarraystd::valarray14*0d923af4SRichard Smith     __attribute__((internal_linkage)) valarray(size_t) {}
~valarraystd::valarray15*0d923af4SRichard Smith     __attribute__((internal_linkage)) ~valarray() {}
16*0d923af4SRichard Smith   };
17*0d923af4SRichard Smith 
18*0d923af4SRichard Smith   extern template valarray<size_t>::valarray(size_t);
19*0d923af4SRichard Smith   extern template valarray<size_t>::~valarray();
20*0d923af4SRichard Smith }
21*0d923af4SRichard Smith 
22*0d923af4SRichard Smith #else
23*0d923af4SRichard Smith 
24*0d923af4SRichard Smith #define BE_THE_HEADER
25*0d923af4SRichard Smith #include "libcxx_valarray_hack.cpp"
26*0d923af4SRichard Smith 
27*0d923af4SRichard Smith template<typename T> struct foo {
xfoo28*0d923af4SRichard Smith   __attribute__((internal_linkage)) void x() {};
29*0d923af4SRichard Smith };
30*0d923af4SRichard Smith extern template void foo<int>::x(); // expected-error {{explicit instantiation declaration of 'x' with internal linkage}}
31*0d923af4SRichard Smith 
32*0d923af4SRichard Smith #endif
33