Bug 83871 - wrong code for attribute const and pure on distinct template specializations
Summary: wrong code for attribute const and pure on distinct template specializations
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: 8.0
Assignee: Martin Sebor
URL:
Keywords: patch, wrong-code
Depends on:
Blocks: 83503 84158
  Show dependency treegraph
 
Reported: 2018-01-15 19:01 UTC by Martin Sebor
Modified: 2018-02-28 18:57 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 6.4.0, 7.3.0, 8.0
Last reconfirmed: 2018-02-03 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2018-01-15 19:01:24 UTC
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 ();

}
Comment 1 Martin Sebor 2018-02-03 03:04:39 UTC
A solution for this bug is necessary to fix pr83503 and pr84158.  I'm working on a patch.
Comment 2 Martin Sebor 2018-02-08 21:54:54 UTC
Patch: https://gcc.gnu.org/ml/gcc-patches/2018-02/msg00154.html
Comment 3 Martin Sebor 2018-02-27 22:28:54 UTC
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
Comment 4 Martin Sebor 2018-02-27 22:29:38 UTC
Fixed via r258045.
Comment 5 Jakub Jelinek 2018-02-28 09:43:45 UTC
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
Comment 6 Jakub Jelinek 2018-02-28 18:57:08 UTC
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