I'm sure the root case of this bug is the same as that of pr83503 but the latter is about a warning and this one is about GCC emitting the wrong code and so it might be worth tracking each separately (and possibly with different priorities). Alternatively, they can be merged as long as both test cases end up in the test suite one the underlying bug is fixed. Unlike in pr83504 (which was about overloads and ended up being invalid), the test case below shows that G++ applies attribute const from the primary template to that of specializations of the template, even though the two are unrelated functions, and even when the specialization has the pure attribute. This bug affects all GCC releases. Clang 3.5 and older and ICC behave correctly. Clang 3.6 and later has the same bug as GCC. $ cat pr83503.C && gcc -O2 -S -Wall pr83503.C -fdump-tree-optimized=/dev/stdout extern "C" void abort (); void* __attribute__ ((const)) f (void*); template <class T> T __attribute__ ((const)) g (T); int i; int __attribute__ ((pure)) f (int); // body could be: { return i; } template <> int __attribute__ ((pure)) g<int> (int); // body could be: { return i; } void call_pure_overload (int x) { i = 1; int i0 = f (x); // call made (good) i = 2; int i1 = f (x); // call made (good) if (i0 == i1) // retained abort (); } void call_pure_specialization (int x) { i = 1; int i0 = g (x); // call eliminated (wrong) i = 2; int i1 = g (x); // call eliminated (wrong) if (i0 == i1) // folded to false (wrong) abort (); } ;; Function void call_pure_overload(int) (_Z18call_pure_overloadi, funcdef_no=0, decl_uid=2267, cgraph_uid=0, symbol_order=1) void call_pure_overload(int) (int x) { int _4; int _6; <bb 2>: i = 1; _4 = f (x_3(D)); i = 2; _6 = f (x_3(D)); if (_4 == _6) goto <bb 3>; else goto <bb 4>; <bb 3>: abort (); <bb 4>: return; } ;; Function void call_pure_specialization(int) (_Z24call_pure_specializationi, funcdef_no=1, decl_uid=2272, cgraph_uid=1, symbol_order=2) (executed once) void call_pure_specialization(int) (int x) { <bb 2>: i = 2; abort (); }
A solution for this bug is necessary to fix pr83503 and pr84158. I'm working on a patch.
Patch: https://gcc.gnu.org/ml/gcc-patches/2018-02/msg00154.html
Author: msebor Date: Tue Feb 27 22:28:21 2018 New Revision: 258045 URL: https://gcc.gnu.org/viewcvs?rev=258045&root=gcc&view=rev Log: PR c++/83871 - wrong code for attribute const and pure on distinct template specializations PR c++/83503 - [8 Regression] bogus -Wattributes for const and pure on function template specialization gcc/ChangeLog: PR c++/83871 * gcc/doc/invoke.texi (-Wmissing-attributes): New option. * gcc/print-tree.c (print_node): Handle DECL_UNINLINABLE. gcc/c-family/ChangeLog: PR c++/83871 * c.opt (-Wmissing-attributes): New option. gcc/cp/ChangeLog: PR c++/83871 PR c++/83503 * cp-tree.h (warn_spec_missing_attributes): New function. ((check_explicit_specialization): Add an argument. Call the above function. * decl.c (duplicate_decls): Avoid applying primary function template's attributes to its explicit specializations. cp/pt.c (warn_spec_missing_attributes): Define. gcc/testsuite/ChangeLog: PR c++/83871 PR c++/83503 * g++.dg/Wmissing-attributes.C: New test. * g++.dg/ext/attr-const-pure.C: New test. * g++.dg/ext/attr-const.C: New test. * g++.dg/ext/attr-deprecated-2.C: New test. * g++.dg/ext/attr-malloc-2.C: New test. * g++.dg/ext/attr-malloc.C: New test. * g++.dg/ext/attr-noinline-2.C: New test. * g++.dg/ext/attr-noinline.C: New test. * g++.dg/ext/attr-nonnull.C: New test. * g++.dg/ext/attr-noreturn-2.C: New test. * g++.dg/ext/attr-noreturn.C: New test. * g++.dg/ext/attr-nothrow-2.C: New test. * g++.dg/ext/attr-nothrow.C: New test. * g++.dg/ext/attr-optimize.C: New test. * g++.dg/ext/attr-pure.C: New test. * g++.dg/ext/attr-returns-nonnull.C: New test. * g++.dg/ext/attr-warning.C: New test. Added: trunk/gcc/testsuite/g++.dg/Wmissing-attributes.C trunk/gcc/testsuite/g++.dg/ext/attr-const-pure.C trunk/gcc/testsuite/g++.dg/ext/attr-const.C trunk/gcc/testsuite/g++.dg/ext/attr-deprecated-2.C trunk/gcc/testsuite/g++.dg/ext/attr-malloc-2.C trunk/gcc/testsuite/g++.dg/ext/attr-malloc.C trunk/gcc/testsuite/g++.dg/ext/attr-noinline-2.C trunk/gcc/testsuite/g++.dg/ext/attr-noinline.C trunk/gcc/testsuite/g++.dg/ext/attr-nonnull.C trunk/gcc/testsuite/g++.dg/ext/attr-noreturn-2.C trunk/gcc/testsuite/g++.dg/ext/attr-noreturn.C trunk/gcc/testsuite/g++.dg/ext/attr-nothrow-2.C trunk/gcc/testsuite/g++.dg/ext/attr-nothrow.C trunk/gcc/testsuite/g++.dg/ext/attr-optimize.C trunk/gcc/testsuite/g++.dg/ext/attr-pure.C trunk/gcc/testsuite/g++.dg/ext/attr-returns-nonnull.C trunk/gcc/testsuite/g++.dg/ext/attr-warning.C Modified: trunk/gcc/ChangeLog trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c.opt trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-tree.h trunk/gcc/cp/decl.c trunk/gcc/cp/pt.c trunk/gcc/doc/invoke.texi trunk/gcc/print-tree.c trunk/gcc/testsuite/ChangeLog
Fixed via r258045.
Author: jakub Date: Wed Feb 28 09:43:10 2018 New Revision: 258059 URL: https://gcc.gnu.org/viewcvs?rev=258059&root=gcc&view=rev Log: PR c++/83871 PR c++/83503 * g++.dg/ext/attr-warning.C: Remove -fdump-tree-optimized from dg-options. * g++.dg/ext/attr-nonnull.C: Likewise. * g++.dg/ext/attr-noinline.C: Fix syntax in scan-tree-dump-not directives. * g++.dg/ext/attr-noinline-2.C: Likewise. * g++.dg/ext/attr-noreturn-2.C: Use -fdump-tree-optimized instead of -fdump-tree-eh in dg-options. Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/ext/attr-noinline-2.C trunk/gcc/testsuite/g++.dg/ext/attr-noinline.C trunk/gcc/testsuite/g++.dg/ext/attr-nonnull.C trunk/gcc/testsuite/g++.dg/ext/attr-noreturn-2.C trunk/gcc/testsuite/g++.dg/ext/attr-warning.C
Author: jakub Date: Wed Feb 28 18:56:36 2018 New Revision: 258079 URL: https://gcc.gnu.org/viewcvs?rev=258079&root=gcc&view=rev Log: PR c++/83871 PR c++/83503 * pt.c (INCLUDE_STRING): Remove define. (warn_spec_missing_attributes): Use pretty_printer instead of std::string. Fix up inform call so that the list of attributes is in %s argument. Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c