https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83871
Bug ID: 83871 Summary: wrong code for attribute const and pure on distinct template specializations Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- 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 (); }