1 | // RUN: rm -rf %t |
2 | // RUN: %clang_cc1 -x c++ -I %S/Inputs/redecl-templates %s -verify -std=c++14 |
3 | // RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/redecl-templates %s -verify -std=c++14 |
4 | // expected-no-diagnostics |
5 | |
6 | template<int N> struct A {}; |
7 | template<int N> using X = A<N>; |
8 | |
9 | template<int N> constexpr void f() {} |
10 | template<int N> constexpr void g() { f<N>(); } |
11 | |
12 | template<int N> extern int v; |
13 | template<int N> int &w = v<N>; |
14 | |
15 | #include "a.h" |
16 | |
17 | // Be careful not to mention A here, that'll import the decls from "a.h". |
18 | int g(X<1> *); |
19 | X<1> *p = 0; |
20 | |
21 | // This will implicitly instantiate A<1> if we haven't imported the explicit |
22 | // specialization declaration from "a.h". |
23 | int k = g(p); |
24 | // Likewise for f and v. |
25 | void h() { g<1>(); } |
26 | int &x = w<1>; |
27 | |
28 | // This is OK: we declared the explicit specialization before we triggered |
29 | // instantiation of this specialization. |
30 | template<> struct A<1> {}; |
31 | template<> constexpr void f<1>() {} |
32 | template<> int v<1>; |
33 | |