diff options
author | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-12-26 18:20:14 +0000 |
---|---|---|
committer | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-12-26 18:20:14 +0000 |
commit | 2df457620208e53ee3febc057463e5b20fc7d085 (patch) | |
tree | 3b3f68cfdf157cf39c688a14d74c859083f1a06c /gcc | |
parent | f358d8ebf53c62cf4d84d2d2e2c86f43396d18c6 (diff) | |
download | gcc-2df457620208e53ee3febc057463e5b20fc7d085.tar.gz |
cp:
PR c++/4803
* decl2.c (mark_used): Defer inline functions.
(finish_file): Merge deferred_fns loops. Check all used
inline functions have a definition.
* method.c (make_thunk): Thunks are not inline.
testsuite:
* g++.dg/warn/inline1.C: New test.
* g++.old-deja/g++.brendan/crash64.C: Remove spurious inlines.
* g++.old-deja/g++.jason/synth10.C: Likewise.
* g++.old-deja/g++.mike/net31.C: Likewise.
* g++.old-deja/g++.mike/p8786.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@60521 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 50 | ||||
-rw-r--r-- | gcc/cp/method.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/inline1.C | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.brendan/crash64.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.jason/synth10.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.mike/net31.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.mike/p8786.C | 2 |
9 files changed, 73 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2291b733b58..08177c091fa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2002-12-26 Nathan Sidwell <nathan@codesourcery.com> + PR c++/4803 + * decl2.c (mark_used): Defer inline functions. + (finish_file): Merge deferred_fns loops. Check all used + inline functions have a definition. + * method.c (make_thunk): Thunks are not inline. + PR c++/5116, c++/764 * call.c (build_new_op): Make sure template class operands are instantiated. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 3d717e8475b..1607e379090 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2791,12 +2791,13 @@ finish_file () reconsider = 1; } - /* Go through the various inline functions, and see if any need - synthesizing. */ for (i = 0; i < deferred_fns_used; ++i) { tree decl = VARRAY_TREE (deferred_fns, i); + import_export_decl (decl); + + /* Does it need synthesizing? */ if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) && TREE_USED (decl) && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl))) @@ -2811,30 +2812,21 @@ finish_file () pop_from_top_level (); reconsider = 1; } - } - /* We lie to the back-end, pretending that some functions are - not defined when they really are. This keeps these functions - from being put out unnecessarily. But, we must stop lying - when the functions are referenced, or if they are not comdat - since they need to be put out now. - This is done in a separate for cycle, because if some deferred - function is contained in another deferred function later in - deferred_fns varray, rest_of_compilation would skip this - function and we really cannot expand the same function twice. */ - for (i = 0; i < deferred_fns_used; ++i) - { - tree decl = VARRAY_TREE (deferred_fns, i); - + /* We lie to the back-end, pretending that some functions + are not defined when they really are. This keeps these + functions from being put out unnecessarily. But, we must + stop lying when the functions are referenced, or if they + are not comdat since they need to be put out now. This + is done in a separate for cycle, because if some deferred + function is contained in another deferred function later + in deferred_fns varray, rest_of_compilation would skip + this function and we really cannot expand the same + function twice. */ if (DECL_NOT_REALLY_EXTERN (decl) && DECL_INITIAL (decl) && DECL_NEEDED_P (decl)) DECL_EXTERNAL (decl) = 0; - } - - for (i = 0; i < deferred_fns_used; ++i) - { - tree decl = VARRAY_TREE (deferred_fns, i); /* If we're going to need to write this function out, and there's already a body for it, create RTL for it now. @@ -2890,6 +2882,16 @@ finish_file () } while (reconsider); + /* All used inline functions must have a definition at this point. */ + for (i = 0; i < deferred_fns_used; ++i) + { + tree decl = VARRAY_TREE (deferred_fns, i); + + if (TREE_USED (decl) && DECL_DECLARED_INLINE_P (decl) + && !(TREE_ASM_WRITTEN (decl) || DECL_SAVED_TREE (decl))) + cp_warning_at ("inline function `%D' used but never defined", decl); + } + /* We give C linkage to static constructors and destructors. */ push_lang_context (lang_name_c); @@ -4665,6 +4667,12 @@ mark_used (decl) TREE_USED (decl) = 1; if (processing_template_decl) return; + + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) + && !TREE_ASM_WRITTEN (decl)) + /* Remember it, so we can check it was defined. */ + defer_fn (decl); + if (!skip_evaluation) assemble_external (decl); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 12a66f6526d..e5a3bd974fb 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -344,6 +344,8 @@ make_thunk (tree function, bool this_adjusting, DECL_NO_STATIC_CHAIN (thunk) = 1; /* The THUNK is not a pending inline, even if the FUNCTION is. */ DECL_PENDING_INLINE_P (thunk) = 0; + DECL_INLINE (thunk) = 0; + DECL_DECLARED_INLINE_P (thunk) = 0; /* Nor has it been deferred. */ DECL_DEFERRED_FN (thunk) = 0; /* Add it to the list of thunks associated with FUNCTION. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a68ab21957b..c54c1c2c1c0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2002-12-26 Nathan Sidwell <nathan@codesourcery.com> + * g++.dg/warn/inline1.C: New test. + * g++.old-deja/g++.brendan/crash64.C: Remove spurious inlines. + * g++.old-deja/g++.jason/synth10.C: Likewise. + * g++.old-deja/g++.mike/net31.C: Likewise. + * g++.old-deja/g++.mike/p8786.C: Likewise. + * g++.dg/template/friend10.C: New test. * g++.dg/template/conv5.C: New test. diff --git a/gcc/testsuite/g++.dg/warn/inline1.C b/gcc/testsuite/g++.dg/warn/inline1.C new file mode 100644 index 00000000000..24836e744eb --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/inline1.C @@ -0,0 +1,23 @@ +// { dg-do compile } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 26 Dec 2002 <nathan@codesourcery.com> + +// PR 4803. Used inline functions must have a definition. + +inline void Foo1 (); // { dg-warning "inline function" "" } +inline void Bar1 (); +template <typename T> inline void Foo2(T); // { dg-warning "inline function" "" } +template <typename T> inline void Bar2(T); + +void Baz () +{ + Foo1 (); + Foo2 (1); + + Bar1 (); + Bar2 (1); +} + +inline void Bar1 () {} +template <typename T> inline void Bar2(T) {} diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C index ccba22e245a..6c2825802f4 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C @@ -4,8 +4,8 @@ typedef long unsigned int size_t; typedef void (*RF_Ptr)(void *); struct _im_pers_mem_spec { - inline _im_pers_mem_spec(void ); - inline _im_pers_mem_spec(auto int of, auto int n); + _im_pers_mem_spec(void ); + _im_pers_mem_spec(auto int of, auto int n); }; struct _type_desc { diff --git a/gcc/testsuite/g++.old-deja/g++.jason/synth10.C b/gcc/testsuite/g++.old-deja/g++.jason/synth10.C index d94e6bdebe9..07a372586c0 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/synth10.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/synth10.C @@ -7,14 +7,14 @@ class A; class AH { public: - inline AH ( A * p = 0 ); + AH ( A * p = 0 ); AH ( const AH & from ) : pointer( from.pointer ) { inc(); } ~ AH () { dec(); } private: A * pointer; - inline void inc() const; - inline void dec() const; + void inc() const; + void dec() const; }; class A diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net31.C b/gcc/testsuite/g++.old-deja/g++.mike/net31.C index 3ecf81c7349..05617a8b4ff 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/net31.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/net31.C @@ -13,7 +13,7 @@ class foo_b { foo_b(); ~foo_b(); foo_b(const foo_b&); - inline double& operator()(int); + double& operator()(int); foo_b& operator=(foo_b&); void bar_a(int); }; diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p8786.C b/gcc/testsuite/g++.old-deja/g++.mike/p8786.C index b5443c0fa6b..0565fb2558a 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p8786.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p8786.C @@ -4,7 +4,7 @@ class B { public: - inline ~B(); + ~B(); }; class D : public B { |