aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2005-06-02 17:52:28 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2005-06-02 17:52:28 +0000
commit3e3935a94ce8702a788cd3e76eab584ed09277e8 (patch)
treea0248ab483fa16d5d61e52a91d59af7f8fbedf6f
parent646221d67de0d8ddfe9b35570c8e52a544e20194 (diff)
downloadgcc-3e3935a94ce8702a788cd3e76eab584ed09277e8.zip
gcc-3e3935a94ce8702a788cd3e76eab584ed09277e8.tar.gz
gcc-3e3935a94ce8702a788cd3e76eab584ed09277e8.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/Make-lang.in2
-rw-r--r--gcc/cp/decl.c3
-rw-r--r--gcc/cp/decl2.c20
-rw-r--r--gcc/cp/method.c21
-rw-r--r--gcc/testsuite/ChangeLog12
-rw-r--r--gcc/testsuite/g++.dg/init/ctor4.C4
-rw-r--r--gcc/testsuite/g++.dg/opt/interface2.C19
-rw-r--r--gcc/testsuite/g++.dg/opt/interface2.h11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bob/inherit2.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/opeq3.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/assign1.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash20.C13
14 files changed, 107 insertions, 31 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7524d5e..22e0833 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 9b33211..30b15fc 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 83c6719..6f1394b 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 732e429..48febf7 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 843f414..b64a31d 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 9222799..224ed08 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/init/ctor4.C b/gcc/testsuite/g++.dg/init/ctor4.C
index b217b20..70643ec 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 0000000..e75e425
--- /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 <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);
+}
diff --git a/gcc/testsuite/g++.dg/opt/interface2.h b/gcc/testsuite/g++.dg/opt/interface2.h
new file mode 100644
index 0000000..dc05904
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/interface2.h
@@ -0,0 +1,11 @@
+#pragma interface
+
+template<class T>
+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 e943a1c..9a64de4 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 a2c84fa..d93181e 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 50b749e..1267faf 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 5f6ad34..9f2a4bf 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 <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" }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash20.C b/gcc/testsuite/g++.old-deja/g++.pt/crash20.C
index 44f6c8c..f910294 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 <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<> >(); }