rsmith added inline comments.
================ Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:4683-4686 + "Member '%0' marked with 'exclude_from_explicit_instantiation' attribute is " + "not defined but an explicit template instantiation declaration exists. " + "Reliance on this member being defined by an explicit template instantiation " + "will lead to link errors.">; ---------------- ldionne wrote: > rsmith wrote: > > Diagnostics should start with a lowercase letter and not end with a period. > > > > That said, I'm not sure I see why this diagnostic is correct / useful. If > > the entity is never used, then there's no link error. And if it is ever > > used, then you should get an implicit instantiation like normal, and we > > already have a diagnostic for the case where an entity is implicitly > > instantiated and no definition is available. > > Diagnostics should start with a lowercase letter and not end with a period. > > Done. > > > That said, I'm not sure I see why this diagnostic is correct / useful. If > > the entity is never used, then there's no link error. And if it is ever > > used, then you should get an implicit instantiation like normal, and we > > already have a diagnostic for the case where an entity is implicitly > > instantiated and no definition is available. > > This is not what happens right now. If you don't provide a definition but you > try to call the function, an extern call will be produced (and that will > result in a link error because any potential explicit instantiation won't > provide the function). For example: > > ``` > cat <<EOF | ./install/bin/clang++ -cc1 -stdlib=libc++ -xc++ -emit-llvm -o - - > template <class T> > struct Foo { > __attribute__((exclude_from_explicit_instantiation)) static void > static_member_function(); > }; > > extern template struct Foo<int>; > > int main() { > Foo<int>::static_member_function(); > } > EOF > ``` > > Results in the following LLVM IR: > > ``` > ; Function Attrs: noinline norecurse nounwind optnone > define i32 @main() #0 { > entry: > call void @_ZN3FooIiE22static_member_functionEv() > ret i32 0 > } > > declare void @_ZN3FooIiE22static_member_functionEv() #1 > ``` > > I guess we should be getting a warning or an error on the point of implicit > instantiation instead, or is this behavior acceptable? > I don't think your example is fundamentally any different from: ``` template <class T> struct Foo { static void static_member_function(); }; int main() { Foo<int>::static_member_function(); } ``` which likewise produces a declaration of `_ZN3FooIiE22static_member_functionEv`. That case produces a `-Wundefined-func-template` warning; your example should do the same. Repository: rC Clang https://reviews.llvm.org/D51789 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits