mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 15:11:08 +08:00
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:
parent
646221d67d
commit
3e3935a94c
@ -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.
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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 &
|
||||
|
@ -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
|
||||
|
@ -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" }
|
||||
}
|
||||
|
19
gcc/testsuite/g++.dg/opt/interface2.C
Normal file
19
gcc/testsuite/g++.dg/opt/interface2.C
Normal 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);
|
||||
}
|
11
gcc/testsuite/g++.dg/opt/interface2.h
Normal file
11
gcc/testsuite/g++.dg/opt/interface2.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma interface
|
||||
|
||||
template<class T>
|
||||
struct C
|
||||
{
|
||||
explicit C(const T& t) : a(t) { }
|
||||
virtual ~C() { }
|
||||
T a;
|
||||
};
|
||||
|
||||
|
@ -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" }
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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" }
|
||||
}
|
||||
|
@ -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" }
|
||||
}
|
||||
|
@ -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<> >(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user