|
5 | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | 6 | // |
7 | 7 | //===----------------------------------------------------------------------===// |
8 | | -// ADDITIONAL_COMPILE_FLAGS: -freflection-latest -fparameter-reflection |
| 8 | +// ADDITIONAL_COMPILE_FLAGS: -freflection-latest -fparameter-reflection -Wno-unused-parameter -Wno-deprecated-declarations |
9 | 9 |
|
10 | 10 | // <experimental/meta> |
11 | 11 |
|
@@ -47,4 +47,40 @@ static_assert(!has_identifier(param0("f"))); |
47 | 47 | static_assert(has_identifier(param0("g"))); |
48 | 48 | static_assert(identifier_of(param0("g")) == "width"); |
49 | 49 |
|
| 50 | +template <class T> struct P { |
| 51 | + template <class... Args> void h(int value, Args... rest); |
| 52 | +}; |
| 53 | +template <class T> template <class... Args> |
| 54 | +void P<T>::h(int val, Args... rest) {} |
| 55 | + |
| 56 | +template void P<int>::h<float>(int, float); |
| 57 | + |
| 58 | +// The non-pack parameter "value"/"val" is inconsistently named. The pack sits at |
| 59 | +// pattern index 1, i.e. AFTER the queried index 0, so the query still walks the |
| 60 | +// pattern's declaration chain and detects the inconsistency. |
| 61 | +static_assert(!has_identifier(parameters_of(^^P<int>::h<float>)[0])); |
| 62 | + |
| 63 | +// A named parameter positioned AFTER a function parameter pack. Instantiating |
| 64 | +// with TWO pack elements makes "tail" land at instantiation index 3, while it |
| 65 | +// sits at index 2 in the pattern (where the pack is a single parameter). Because |
| 66 | +// a pack precedes the queried index, the query cannot safely index the pattern's |
| 67 | +// shorter parameter list and falls back to the instantiation. This must neither |
| 68 | +// misindex nor crash -- getParamDecl(3) on the 3-parameter pattern would be |
| 69 | +// out-of-bounds. |
| 70 | +template <class T> struct Q { |
| 71 | + template <class... Args> void k(int value, Args... rest, int tail); |
| 72 | +}; |
| 73 | +template <class T> template <class... Args> |
| 74 | +void Q<T>::k(int val, Args... rest, int tail) {} |
| 75 | + |
| 76 | +template void Q<int>::k<float, double>(int, float, double, int); |
| 77 | + |
| 78 | +// Pre-pack parameter (index 0): inconsistent name, detected via the pattern. |
| 79 | +static_assert(!has_identifier(parameters_of(^^Q<int>::k<float, double>)[0])); |
| 80 | + |
| 81 | +// Trailing parameter after the pack (instantiation index 3, pattern index 2): |
| 82 | +// must not crash; reports its consistently-spelled name. |
| 83 | +static_assert(has_identifier(parameters_of(^^Q<int>::k<float, double>)[3])); |
| 84 | +static_assert(identifier_of(parameters_of(^^Q<int>::k<float, double>)[3]) == "tail"); |
| 85 | + |
50 | 86 | int main(int, char**) { return 0; } |
0 commit comments