[C++ PATCH] Fix PR3797

Kriang Lerdsuwanakij lerdsuwa@users.sourceforge.net
Sat Jun 1 09:27:00 GMT 2002


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; }



More information about the Gcc-patches mailing list