This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix PR3797
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 01 Jun 2002 23:28:39 +0700
- Subject: [C++ PATCH] Fix PR3797
- Reply-to: lerdsuwa at users dot sourceforge dot net
Hi
This patch fixes PR3797 where the inlining parameters of primary
template influences specialization while it shouldn't do so.
As seen from the testcase provided in the patch, the primary
template for S<T>::foo() is defined in-class, hence it should be inlined.
However for the specialization S<int>::foo() also inherits this inlining
property which violates [temp.expl.spec] para 14. The patch fixes
by only propagate inlining properties when the new declaration is
not a specialization of the olddecl.
Bootstrapped and tested with no regressions. Ok to commit to the
main trunk?
--Kriang
2002-06-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/3797
* decl.c (duplicate_decls): Don't propagate inlining parameters from
olddecl to newdecl when newdecl is a specialization of the
instantiation olddecl.
diff -cprN gcc-main-save/gcc/cp/decl.c gcc-main-new/gcc/cp/decl.c
*** gcc-main-save/gcc/cp/decl.c Thu May 16 20:34:06 2002
--- gcc-main-new/gcc/cp/decl.c Thu May 30 22:36:55 2002
*************** duplicate_decls (newdecl, olddecl)
*** 3446,3453 ****
DECL_VIRTUAL_CONTEXT (newdecl) = DECL_VIRTUAL_CONTEXT (olddecl);
if (DECL_CONTEXT (olddecl))
DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
- if (DECL_PENDING_INLINE_INFO (newdecl) == 0)
- DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl);
DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl);
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
DECL_PURE_VIRTUAL_P (newdecl) |= DECL_PURE_VIRTUAL_P (olddecl);
--- 3446,3451 ----
*************** duplicate_decls (newdecl, olddecl)
*** 3693,3709 ****
olddecl);
SET_DECL_TEMPLATE_SPECIALIZATION (olddecl);
}
! DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl);
! /* If either decl says `inline', this fn is inline, unless its
! definition was passed already. */
! if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE)
! DECL_INLINE (olddecl) = 1;
! DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
! DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
! = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
/* Preserve abstractness on cloned [cd]tors. */
DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
--- 3691,3716 ----
olddecl);
SET_DECL_TEMPLATE_SPECIALIZATION (olddecl);
+
+ /* [temp.expl.spec/14] We don't inline explicit specialization
+ just because the primary template says so. */
}
! else
! {
! if (DECL_PENDING_INLINE_INFO (newdecl) == 0)
! DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl);
! DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl);
! /* If either decl says `inline', this fn is inline, unless
! its definition was passed already. */
! if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE)
! DECL_INLINE (olddecl) = 1;
! DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
!
! DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
! = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
! }
/* Preserve abstractness on cloned [cd]tors. */
DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/inline1.C gcc-main-new/gcc/testsuite/g++.dg/template/inline1.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/inline1.C Thu Jan 1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/inline1.C Sat Jun 1 22:37:26 2002
***************
*** 0 ****
--- 1,19 ----
+ // { do-do compile }
+ // { dg-final { scan-assembler "_ZN1SIiE3fooEv" } }
+ // Origin: Martin Sebor <sebor@roguewave.com>
+
+ // PR c++/3797
+ // The inlining of primary template should not imply inlining
+ // specializations.
+
+ template <class T>
+ struct S
+ {
+ int foo () { return 0; }
+ };
+
+ template <>
+ int S<int>::foo ();
+
+ template <>
+ int S<int>::foo () { return 1; }