Commit 3e3935a9 by Nathan Sidwell Committed by Nathan Sidwell

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
parent 646221d6
2005-06-02 Nathan Sidwell <nathan@codesourcery.com> 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 * decl.c (start_decl): Simplify specialization handling. Remove
unneeded CLASSTYPE_TEMPLATE_INSTANTIATION check. unneeded CLASSTYPE_TEMPLATE_INSTANTIATION check.
* mangle.c (discriminator_for_local_entity): Use VEC_index. * mangle.c (discriminator_for_local_entity): Use VEC_index.
......
...@@ -260,7 +260,7 @@ cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_ ...@@ -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 \ cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
except.h $(TARGET_H) except.h $(TARGET_H)
cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_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/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/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) \ cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \
......
...@@ -9879,7 +9879,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags) ...@@ -9879,7 +9879,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
int doing_friend = 0; int doing_friend = 0;
struct cp_binding_level *bl; struct cp_binding_level *bl;
tree current_function_parms; 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. */ /* Sanity check. */
gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE); gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE);
......
...@@ -2966,6 +2966,10 @@ cp_finish_file (void) ...@@ -2966,6 +2966,10 @@ cp_finish_file (void)
finish_function doesn't clean things up, and we end finish_function doesn't clean things up, and we end
up with CURRENT_FUNCTION_DECL set. */ up with CURRENT_FUNCTION_DECL set. */
push_to_top_level (); 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); synthesize_method (decl);
pop_from_top_level (); pop_from_top_level ();
reconsider = true; reconsider = true;
...@@ -3228,6 +3232,14 @@ mark_used (tree decl) ...@@ -3228,6 +3232,14 @@ mark_used (tree decl)
{ {
if (DECL_DEFERRED_FN (decl)) if (DECL_DEFERRED_FN (decl))
return; 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); note_vague_linkage_fn (decl);
} }
...@@ -3245,14 +3257,6 @@ mark_used (tree decl) ...@@ -3245,14 +3257,6 @@ mark_used (tree decl)
pointing to the class location. */ pointing to the class location. */
&& current_function_decl) && 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); synthesize_method (decl);
/* If we've already synthesized the method we don't need to /* If we've already synthesized the method we don't need to
instantiate it, so we can return right away. */ instantiate it, so we can return right away. */
......
...@@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */
#include "tm_p.h" #include "tm_p.h"
#include "target.h" #include "target.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "diagnostic.h"
/* Various flags to control the mangling process. */ /* Various flags to control the mangling process. */
...@@ -731,6 +732,8 @@ do_build_assign_ref (tree fndecl) ...@@ -731,6 +732,8 @@ do_build_assign_ref (tree fndecl)
finish_compound_stmt (compound_stmt); finish_compound_stmt (compound_stmt);
} }
/* Synthesize FNDECL, a non-static member function. */
void void
synthesize_method (tree fndecl) synthesize_method (tree fndecl)
{ {
...@@ -739,17 +742,19 @@ synthesize_method (tree fndecl) ...@@ -739,17 +742,19 @@ synthesize_method (tree fndecl)
bool need_body = true; bool need_body = true;
tree stmt; tree stmt;
location_t save_input_location = input_location; 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 /* If we've been asked to synthesize a clone, just synthesize the
cloned function instead. Doing so will automatically fill in the cloned function instead. Doing so will automatically fill in the
body for the clone. */ body for the clone. */
if (DECL_CLONED_FUNCTION_P (fndecl)) if (DECL_CLONED_FUNCTION_P (fndecl))
{ fndecl = DECL_CLONED_FUNCTION (fndecl);
DECL_SOURCE_LOCATION (DECL_CLONED_FUNCTION (fndecl)) =
DECL_SOURCE_LOCATION (fndecl);
synthesize_method (DECL_CLONED_FUNCTION (fndecl));
return;
}
/* We may be in the middle of deferred access check. Disable /* We may be in the middle of deferred access check. Disable
it now. */ it now. */
...@@ -799,6 +804,10 @@ synthesize_method (tree fndecl) ...@@ -799,6 +804,10 @@ synthesize_method (tree fndecl)
pop_function_context_from (context); pop_function_context_from (context);
pop_deferring_access_checks (); 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 & /* Use EXTRACTOR to locate the relevant function called for each base &
......
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> 2005-06-02 Dorit Nuzman <dorit@il.ibm.com>
PR tree-optimization/21734 PR tree-optimization/21734
......
...@@ -6,7 +6,7 @@ public: ...@@ -6,7 +6,7 @@ public:
foo(); foo();
}; };
class bar: public foo { class bar: public foo {// { dg-error "uninitialized" }
private: private:
int &a; int &a;
}; };
...@@ -16,5 +16,5 @@ foo::foo() { ...@@ -16,5 +16,5 @@ foo::foo() {
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
bar x; // { dg-error "uninitialized" } bar x; // { dg-error "synthesized" }
} }
// 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);
}
#pragma interface
template<class T>
struct C
{
explicit C(const T& t) : a(t) { }
virtual ~C() { }
T a;
};
...@@ -6,11 +6,11 @@ public: ...@@ -6,11 +6,11 @@ public:
void z(); void z();
A(void) {} A(void) {}
private: private:
A(const A &) { abort(); } // { dg-error "" } A(const A &) { abort(); } // { dg-error "private" }
const A& operator =(const A &) { abort(); } const A& operator =(const A &) { abort(); }
}; };
class B : public A { class B : public A { // { dg-error "within" }
public: public:
B(void) {} B(void) {}
}; };
...@@ -20,5 +20,5 @@ void f(B b) { ...@@ -20,5 +20,5 @@ void f(B b) {
void g() { void g() {
B h; B h;
f(h); // { dg-error "" } f(h); // { dg-error "synthesized|argument" }
} }
...@@ -23,9 +23,9 @@ struct0::struct0 (int, void *) // { dg-error "note" } ...@@ -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; } int main () { return 0; }
// { dg-do assemble } // { dg-do assemble }
// Bug: g++ generates code for assignment in invalid situations. // Bug: g++ generates code for assignment in invalid situations.
class X { class X { // { dg-error "assignment" }
int& a; int& a;
public: public:
X(int& i): a(i) { }; X(int& i): a(i) { };
...@@ -11,5 +11,5 @@ void foo () ...@@ -11,5 +11,5 @@ void foo ()
{ {
int one=1, two=2; int one=1, two=2;
X a(one), b(two); X a(one), b(two);
a = b; // { dg-error "" } no assignment semantics defined a = b; // { dg-error "synthesized" }
} }
// { dg-do assemble } // { dg-do compile }
// Origin: Mark Mitchell <mark@codesourcery.com> // Origin: Mark Mitchell <mark@codesourcery.com>
template <class T> template <class T>
struct S { struct S { // { dg-error "assignment" }
S(); S();
T t; T t;
}; };
...@@ -10,5 +10,5 @@ struct S { ...@@ -10,5 +10,5 @@ struct S {
void f() void f()
{ {
S<const int> s; S<const int> s;
s = s; // { dg-error "" } generated assignment operator is illegal s = s; // { dg-error "synthesized" }
} }
// { dg-do assemble } // { dg-do compile }
template <class T = int> 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> 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<> >(); } int main (void) { func< A<> >(); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment