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
This commit is contained in:
Nathan Sidwell 2005-06-02 17:52:28 +00:00 committed by Nathan Sidwell
parent 646221d67d
commit 3e3935a94c
14 changed files with 107 additions and 31 deletions

View File

@ -1,5 +1,18 @@
2005-06-02 Nathan Sidwell <nathan@codesourcery.com>
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.

View File

@ -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) \

View File

@ -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);

View File

@ -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. */

View File

@ -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 &

View File

@ -1,3 +1,15 @@
2005-06-02 Nathan Sidwell <nathan@codesourcery.com>
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 <dorit@il.ibm.com>
PR tree-optimization/21734

View File

@ -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" }
}

View File

@ -0,0 +1,19 @@
// Copyright (C) 2005 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 2 Jun 2005 <nathan@codesourcery.com>
// PR 21280
// Origin: Jens Maurer <jens.maurer@gmx.net>
#include "interface2.h"
struct A
{
A() { }
virtual ~A() { }
};
int main()
{
A a;
C<A> c(a);
}

View File

@ -0,0 +1,11 @@
#pragma interface
template<class T>
struct C
{
explicit C(const T& t) : a(t) { }
virtual ~C() { }
T a;
};

View File

@ -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" }
}

View File

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

View File

@ -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" }
}

View File

@ -1,8 +1,8 @@
// { dg-do assemble }
// { dg-do compile }
// Origin: Mark Mitchell <mark@codesourcery.com>
template <class T>
struct S {
struct S { // { dg-error "assignment" }
S();
T t;
};
@ -10,5 +10,5 @@ struct S {
void f()
{
S<const int> s;
s = s; // { dg-error "" } generated assignment operator is illegal
s = s; // { dg-error "synthesized" }
}

View File

@ -1,9 +1,16 @@
// { dg-do assemble }
// { dg-do compile }
template <class T = int>
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 <class B>
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<> >(); }