From: Nathan Sidwell Date: Thu, 2 Jun 2005 17:52:28 +0000 (+0000) Subject: re PR c++/21280 (#pragma interface, templates, and "inline function used but never... X-Git-Tag: misc/cutover-cvs2svn~2697 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3e3935a94ce8702a788cd3e76eab584ed09277e8;p=thirdparty%2Fgcc.git re PR c++/21280 (#pragma interface, templates, and "inline function used but never defined") cp: PR c++/21280 * Make-lang.in (method.o): Add diagnostic.h * decl.c (start_preparsed_function): Use decl's location for file info. * decl2.c (cp_finish_file): Set input_location before synthesizing a function. (mark_used): When deferring a synthesized function, save current location. Do not set function's location when actually synthesizing it. * method.c: #include diagnostic.h. (synthesize_method): Set the functions source location. Show needed location if errors are emitted. testsuite: PR c++/21280 * g++.dg/opt/interface2.h: New. * g++.dg/opt/interface2.C: New. * g++.dg/init/ctor4.C: Adjust error lines. * g++.old-deja/g++.bob/inherit2.C: Likewise. * g++.old-deja/g++.bugs/900205_04.C: Likewise. * g++.old-deja/g++.jason/opeq3.C: Likewise. * g++.old-deja/g++.pt/assign1.C: Likewise. * g++.old-deja/g++.pt/crash20.C: Likewise. From-SVN: r100500 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7524d5e557b7..22e08335d7fe 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,18 @@ 2005-06-02 Nathan Sidwell + PR c++/21280 + * Make-lang.in (method.o): Add diagnostic.h + * decl.c (start_preparsed_function): Use decl's location for file + info. + * decl2.c (cp_finish_file): Set input_location before synthesizing + a function. + (mark_used): When deferring a synthesized function, save current + location. Do not set function's location when actually + synthesizing it. + * method.c: #include diagnostic.h. + (synthesize_method): Set the functions source location. Show + needed location if errors are emitted. + * decl.c (start_decl): Simplify specialization handling. Remove unneeded CLASSTYPE_TEMPLATE_INSTANTIATION check. * mangle.c (discriminator_for_local_entity): Use VEC_index. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 9b33211e6f1e..30b15fc4d625 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -260,7 +260,7 @@ cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_ cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \ except.h $(TARGET_H) cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \ - $(TM_P_H) $(TARGET_H) gt-cp-method.h + $(TM_P_H) $(TARGET_H) diagnostic.h gt-cp-method.h cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h flags.h toplev.h convert.h cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 83c67198dc72..6f1394ba5131 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9879,7 +9879,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags) int doing_friend = 0; struct cp_binding_level *bl; tree current_function_parms; - struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename)); + struct c_fileinfo *finfo + = get_fileinfo (lbasename (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)))); /* Sanity check. */ gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 732e429a1346..48febf714d05 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2966,6 +2966,10 @@ cp_finish_file (void) finish_function doesn't clean things up, and we end up with CURRENT_FUNCTION_DECL set. */ push_to_top_level (); + /* The decl's location will mark where it was first + needed. Save that so synthesize method can indicate + where it was needed from, in case of error */ + input_location = DECL_SOURCE_LOCATION (decl); synthesize_method (decl); pop_from_top_level (); reconsider = true; @@ -3228,6 +3232,14 @@ mark_used (tree decl) { if (DECL_DEFERRED_FN (decl)) return; + + /* Remember the current location for a function we will end up + synthesizing. Then we can inform the user where it was + required in the case of error. */ + if (DECL_ARTIFICIAL (decl) && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) + && !DECL_THUNK_P (decl)) + DECL_SOURCE_LOCATION (decl) = input_location; + note_vague_linkage_fn (decl); } @@ -3245,14 +3257,6 @@ mark_used (tree decl) pointing to the class location. */ && current_function_decl) { - /* Put the function definition at the position where it is needed, - rather than within the body of the class. That way, an error - during the generation of the implicit body points at the place - where the attempt to generate the function occurs, giving the - user a hint as to why we are attempting to generate the - function. */ - DECL_SOURCE_LOCATION (decl) = input_location; - synthesize_method (decl); /* If we've already synthesized the method we don't need to instantiate it, so we can return right away. */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 843f414bb9b5..b64a31d3fd0a 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */ #include "tm_p.h" #include "target.h" #include "tree-pass.h" +#include "diagnostic.h" /* Various flags to control the mangling process. */ @@ -731,6 +732,8 @@ do_build_assign_ref (tree fndecl) finish_compound_stmt (compound_stmt); } +/* Synthesize FNDECL, a non-static member function. */ + void synthesize_method (tree fndecl) { @@ -739,17 +742,19 @@ synthesize_method (tree fndecl) bool need_body = true; tree stmt; location_t save_input_location = input_location; + int error_count = errorcount; + int warning_count = warningcount; + /* Reset the source location, we might have been previously + deferred, and thus have saved where we were first needed. */ + DECL_SOURCE_LOCATION (fndecl) + = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl))); + /* If we've been asked to synthesize a clone, just synthesize the cloned function instead. Doing so will automatically fill in the body for the clone. */ if (DECL_CLONED_FUNCTION_P (fndecl)) - { - DECL_SOURCE_LOCATION (DECL_CLONED_FUNCTION (fndecl)) = - DECL_SOURCE_LOCATION (fndecl); - synthesize_method (DECL_CLONED_FUNCTION (fndecl)); - return; - } + fndecl = DECL_CLONED_FUNCTION (fndecl); /* We may be in the middle of deferred access check. Disable it now. */ @@ -799,6 +804,10 @@ synthesize_method (tree fndecl) pop_function_context_from (context); pop_deferring_access_checks (); + + if (error_count != errorcount || warning_count != warningcount) + warning ("%Hsynthesized method %qD first required here ", + &input_location, fndecl); } /* Use EXTRACTOR to locate the relevant function called for each base & diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9222799790f9..224ed080422d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2005-06-02 Nathan Sidwell + + PR c++/21280 + * g++.dg/opt/interface2.h: New. + * g++.dg/opt/interface2.C: New. + * g++.dg/init/ctor4.C: Adjust error lines. + * g++.old-deja/g++.bob/inherit2.C: Likewise. + * g++.old-deja/g++.bugs/900205_04.C: Likewise. + * g++.old-deja/g++.jason/opeq3.C: Likewise. + * g++.old-deja/g++.pt/assign1.C: Likewise. + * g++.old-deja/g++.pt/crash20.C: Likewise. + 2005-06-02 Dorit Nuzman PR tree-optimization/21734 diff --git a/gcc/testsuite/g++.dg/init/ctor4.C b/gcc/testsuite/g++.dg/init/ctor4.C index b217b2040001..70643ec4e10c 100644 --- a/gcc/testsuite/g++.dg/init/ctor4.C +++ b/gcc/testsuite/g++.dg/init/ctor4.C @@ -6,7 +6,7 @@ public: foo(); }; -class bar: public foo { +class bar: public foo {// { dg-error "uninitialized" } private: int &a; }; @@ -16,5 +16,5 @@ foo::foo() { int main(int argc, char **argv) { - bar x; // { dg-error "uninitialized" } + bar x; // { dg-error "synthesized" } } diff --git a/gcc/testsuite/g++.dg/opt/interface2.C b/gcc/testsuite/g++.dg/opt/interface2.C new file mode 100644 index 000000000000..e75e425893d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/interface2.C @@ -0,0 +1,19 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 2 Jun 2005 + +// PR 21280 +// Origin: Jens Maurer + +#include "interface2.h" + +struct A +{ + A() { } + virtual ~A() { } +}; + +int main() +{ + A a; + C c(a); +} diff --git a/gcc/testsuite/g++.dg/opt/interface2.h b/gcc/testsuite/g++.dg/opt/interface2.h new file mode 100644 index 000000000000..dc0590472303 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/interface2.h @@ -0,0 +1,11 @@ +#pragma interface + +template +struct C +{ + explicit C(const T& t) : a(t) { } + virtual ~C() { } + T a; +}; + + diff --git a/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C b/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C index e943a1caa18d..9a64de4dc3e1 100644 --- a/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C +++ b/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C @@ -6,11 +6,11 @@ public: void z(); A(void) {} private: - A(const A &) { abort(); } // { dg-error "" } + A(const A &) { abort(); } // { dg-error "private" } const A& operator =(const A &) { abort(); } }; -class B : public A { +class B : public A { // { dg-error "within" } public: B(void) {} }; @@ -20,5 +20,5 @@ void f(B b) { void g() { B h; - f(h); // { dg-error "" } + f(h); // { dg-error "synthesized|argument" } } diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C b/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C index a2c84fadb9e1..d93181ebb1e1 100644 --- a/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C +++ b/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C @@ -23,9 +23,9 @@ struct0::struct0 (int, void *) // { dg-error "note" } { } -struct struct0_derived_struct_0 : public struct0 { // { dg-error "" } +struct struct0_derived_struct_0 : public struct0 { // { dg-error "no matching" } }; -struct0_derived_struct_0 object; +struct0_derived_struct_0 object; // { dg-error "synthesized" } int main () { return 0; } diff --git a/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C b/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C index 50b749eb628c..1267fafbe492 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C @@ -1,7 +1,7 @@ // { dg-do assemble } // Bug: g++ generates code for assignment in invalid situations. -class X { +class X { // { dg-error "assignment" } int& a; public: X(int& i): a(i) { }; @@ -11,5 +11,5 @@ void foo () { int one=1, two=2; X a(one), b(two); - a = b; // { dg-error "" } no assignment semantics defined + a = b; // { dg-error "synthesized" } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/assign1.C b/gcc/testsuite/g++.old-deja/g++.pt/assign1.C index 5f6ad3455131..9f2a4bf065b9 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/assign1.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/assign1.C @@ -1,8 +1,8 @@ -// { dg-do assemble } +// { dg-do compile } // Origin: Mark Mitchell template -struct S { +struct S { // { dg-error "assignment" } S(); T t; }; @@ -10,5 +10,5 @@ struct S { void f() { S s; - s = s; // { dg-error "" } generated assignment operator is illegal + s = s; // { dg-error "synthesized" } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash20.C b/gcc/testsuite/g++.old-deja/g++.pt/crash20.C index 44f6c8c447a1..f910294e65cc 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/crash20.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash20.C @@ -1,9 +1,16 @@ -// { dg-do assemble } +// { dg-do compile } template -struct A { const T x; A() : x(0) { } A(T x) : x(x) { } }; +struct A { // { dg-error "assignment" } + const T x; + A() : x(0) { } A(T x) : x(x) { } +}; template -void func () { B y; y = B(); } // { dg-error "" } can't use default assignment +void func () +{ + B y; + y = B(); // { dg-error "synthesized" } +} int main (void) { func< A<> >(); }