| // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s |
| |
| // Test that the exclude_from_explicit_instantiation attribute is ignored |
| // for local classes and members thereof. |
| |
| #define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) // expected-note 0+{{expanded from macro}} |
| |
| namespace N0 { |
| |
| template<typename T> |
| void f() { |
| struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION A { // expected-warning {{attribute ignored on local class}} |
| // expected-note@-1 2{{in instantiation of}} |
| EXCLUDE_FROM_EXPLICIT_INSTANTIATION void g(T t) { // expected-warning {{attribute ignored on local class member}} |
| *t; // expected-error {{indirection requires pointer operand ('int' invalid)}} |
| } |
| |
| struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION B { // expected-warning {{attribute ignored on local class}} |
| void h(T t) { |
| *t; // expected-error {{indirection requires pointer operand ('int' invalid)}} |
| } |
| }; |
| }; |
| } |
| |
| template void f<int>(); // expected-note 2{{in instantiation of}} |
| |
| } |
| |
| // This is a reduced example from libc++ which required that 'value' |
| // be prefixed with 'this->' because the definition of 'Local::operator A' |
| // was not instantiated when the definition of 'g' was. |
| namespace N1 { |
| |
| struct A { }; |
| |
| struct B { |
| operator A() { |
| return A(); |
| } |
| }; |
| |
| template<typename T> |
| auto f(T t) { |
| return A(t); |
| } |
| |
| template<typename T> |
| auto g(T t) { |
| struct Local { |
| T value; |
| |
| EXCLUDE_FROM_EXPLICIT_INSTANTIATION // expected-warning {{attribute ignored on local class member}} |
| operator A() { |
| return A(value); |
| } |
| }; |
| |
| return f(Local(t)); |
| } |
| |
| auto x = g(B()); |
| |
| } |