http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46643
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> 2010-11-24 18:37:53 UTC --- It looks as though 4.4 had a problem with templates too, here S<T> is a POD but there's no warning for foo::bar template<typename> struct S { }; template<typename T> class foo { public: S<T> bar() __attribute__((warn_unused_result)); int baz() __attribute__((warn_unused_result)); }; template<typename T> inline S<T> foo<T>::bar() { return S<T>(); } template<typename T> inline int foo<T>::baz() { return 0; } int main(void) { foo<int> b; b.bar(); b.baz(); return 0; } That seems to be fixed in 4.5 and 4.6 Not quite as simple as non-POD either, here S is a non-POD but there's a warning: struct S { S() { } }; template<typename T> class foo { public: S bar() __attribute__((warn_unused_result)); }; template<typename T> inline S foo<T>::bar() { return S(); } int main(void) { foo<int> b; b.bar(); } Change the user-declared constructor to a user-declared destructor and the warning is missing