1 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s 2 3 // Test that the exclude_from_explicit_instantiation attribute is ignored 4 // for local classes and members thereof. 5 6 #define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) // expected-note 0+{{expanded from macro}} 7 8 namespace N0 { 9 10 template<typename T> f()11 void f() { 12 struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION A { // expected-warning {{attribute ignored on local class}} 13 // expected-note@-1 2{{in instantiation of}} 14 EXCLUDE_FROM_EXPLICIT_INSTANTIATION void g(T t) { // expected-warning {{attribute ignored on local class member}} 15 *t; // expected-error {{indirection requires pointer operand ('int' invalid)}} 16 } 17 18 struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION B { // expected-warning {{attribute ignored on local class}} 19 void h(T t) { 20 *t; // expected-error {{indirection requires pointer operand ('int' invalid)}} 21 } 22 }; 23 }; 24 } 25 26 template void f<int>(); // expected-note 2{{in instantiation of}} 27 28 } 29 30 // This is a reduced example from libc++ which required that 'value' 31 // be prefixed with 'this->' because the definition of 'Local::operator A' 32 // was not instantiated when the definition of 'g' was. 33 namespace N1 { 34 35 struct A { }; 36 37 struct B { operator AN1::B38 operator A() { 39 return A(); 40 } 41 }; 42 43 template<typename T> f(T t)44 auto f(T t) { 45 return A(t); 46 } 47 48 template<typename T> g(T t)49 auto g(T t) { 50 struct Local { 51 T value; 52 53 EXCLUDE_FROM_EXPLICIT_INSTANTIATION // expected-warning {{attribute ignored on local class member}} 54 operator A() { 55 return A(value); 56 } 57 }; 58 59 return f(Local(t)); 60 } 61 62 auto x = g(B()); 63 64 } 65