aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-02-01 14:32:51 -0500
committerJason Merrill <jason@gcc.gnu.org>2002-02-01 14:32:51 -0500
commitefe49da0ba74c2fa1efe212d9c91cbdb1680c06d (patch)
treead77fd5a8517b02ca6dc9e00f1c365c442c92888
parentf2d9afece3fb462b7abd8209a8d5d7119b28c0cd (diff)
downloadgcc-efe49da0ba74c2fa1efe212d9c91cbdb1680c06d.zip
gcc-efe49da0ba74c2fa1efe212d9c91cbdb1680c06d.tar.gz
gcc-efe49da0ba74c2fa1efe212d9c91cbdb1680c06d.tar.bz2
re PR c++/4872 (missed warning (no return) -- regression from 2.95)
PR c++/4872 * decl.c (finish_function): Warn about a non-void function with no return statement and no abnormal exit. * cp-tree.h (struct cp_language_function): Add returns_abnormally. (current_function_returns_abnormally): New macro. * call.c (build_call): Set it. From-SVN: r49407
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/call.c3
-rw-r--r--gcc/cp/cp-tree.h7
-rw-r--r--gcc/cp/decl.c12
-rw-r--r--gcc/testsuite/g++.dg/abi/empty4.C2
-rw-r--r--gcc/testsuite/g++.dg/other/const2.C2
-rw-r--r--gcc/testsuite/g++.dg/other/deprecated.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bob/inherit2.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/byval2.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators17.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/eh50.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/eh51.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net20.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net40.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net45.C3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p10511.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p11012.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p7325.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/crash25.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/for1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/init12.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/new.C5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/new4.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/rtti1.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/spec1.C2
26 files changed, 64 insertions, 26 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index af18329..0bd68be 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
2002-02-01 Jason Merrill <jason@redhat.com>
+ PR c++/4872
+ * decl.c (finish_function): Warn about a non-void function with
+ no return statement and no abnormal exit.
+ * cp-tree.h (struct cp_language_function): Add returns_abnormally.
+ (current_function_returns_abnormally): New macro.
+ * call.c (build_call): Set it.
+
* typeck.c (build_component_ref): Always complain about offsetof
constructs on non-PODs. Only make it an error for members of
virtual bases.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index cf6f0b4..925bd06 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -408,6 +408,9 @@ build_call (function, parms)
nothrow = ((decl && TREE_NOTHROW (decl))
|| TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (function))));
+ if (decl && TREE_THIS_VOLATILE (decl))
+ current_function_returns_abnormally = 1;
+
if (decl && TREE_DEPRECATED (decl))
warn_deprecated_use (decl);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f7cddac..703720e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -821,6 +821,7 @@ struct cp_language_function
int returns_value;
int returns_null;
+ int returns_abnormally;
int in_function_try_handler;
int x_expanding_p;
@@ -883,6 +884,12 @@ struct cp_language_function
#define current_function_returns_null cp_function_chain->returns_null
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a call to a noreturn function is seen. */
+
+#define current_function_returns_abnormally \
+ cp_function_chain->returns_abnormally
+
/* Non-zero if we should generate RTL for functions that we process.
When this is zero, we just accumulate tree structure, without
interacting with the back end. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a5d9c64..097b562 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -14247,6 +14247,18 @@ finish_function (flags)
if (!processing_template_decl && calls_setjmp_p (fndecl))
DECL_UNINLINABLE (fndecl) = 1;
+ /* Complain if there's just no return statement. */
+ if (!processing_template_decl
+ && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
+ && !current_function_returns_value
+ && !DECL_NAME (DECL_RESULT (fndecl))
+ /* Don't complain if we abort or throw. */
+ && !current_function_returns_abnormally
+ /* If we have -Wreturn-type, let flow complain. Unless we're an
+ inline function, as we might never be compiled separately. */
+ && (!warn_return_type || DECL_INLINE (fndecl))
+ warning ("no return statement in function returning non-void");
+
/* Clear out memory we no longer need. */
free_after_parsing (cfun);
/* Since we never call rest_of_compilation, we never clear
diff --git a/gcc/testsuite/g++.dg/abi/empty4.C b/gcc/testsuite/g++.dg/abi/empty4.C
index fe3d9a8..d20a55c 100644
--- a/gcc/testsuite/g++.dg/abi/empty4.C
+++ b/gcc/testsuite/g++.dg/abi/empty4.C
@@ -18,7 +18,7 @@ struct NonPod
NonPod () {m = 0x12345678;}
NonPod (long m_) {m = m_;}
- NonPod &operator= (NonPod const &src) {now = m; m = src.m;}
+ NonPod &operator= (NonPod const &src) {now = m; m = src.m; return *this;}
NonPod (NonPod const &src) {m = src.m;}
};
diff --git a/gcc/testsuite/g++.dg/other/const2.C b/gcc/testsuite/g++.dg/other/const2.C
index 25778fa..86dde1e 100644
--- a/gcc/testsuite/g++.dg/other/const2.C
+++ b/gcc/testsuite/g++.dg/other/const2.C
@@ -10,7 +10,7 @@ struct foo
static const bar bars[];
- int bad ()
+ void bad ()
{
this->*(bars[0].b) = 42; // { dg-bogus "read-only" "" }
}
diff --git a/gcc/testsuite/g++.dg/other/deprecated.C b/gcc/testsuite/g++.dg/other/deprecated.C
index 40d9dba..1056070 100644
--- a/gcc/testsuite/g++.dg/other/deprecated.C
+++ b/gcc/testsuite/g++.dg/other/deprecated.C
@@ -13,10 +13,10 @@ INT1 should_be_unavailable; /* { dg-warning "`INT1' is deprecated" "" } */
INT1a should_not_be_deprecated;
INT1 f1(void) __attribute__ ((deprecated));
-INT1 f2(void) {} /* { dg-warning "`INT1' is deprecated" "" } */
+INT1 f2(void) { return 0; } /* { dg-warning "`INT1' is deprecated" "" } */
INT2 f3(void) __attribute__ ((__deprecated__));
-INT2 f4(void) {} /* { dg-warning "`INT2' is deprecated" "" } */
+INT2 f4(void) { return 0; } /* { dg-warning "`INT2' is deprecated" "" } */
int f5(INT2 x); /* { dg-warning "`INT2' is deprecated" "" } */
int f6(INT2 x) __attribute__ ((__deprecated__));
diff --git a/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C b/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C
index fe9e73b..a7aa4fe 100644
--- a/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C
+++ b/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C
@@ -1,11 +1,13 @@
// Build don't link:
+#include <stdlib.h>
+
class A {
public:
void z();
A(void) {}
private:
A(const A &) { abort(); } // ERROR -
- const A& operator =(const A &) { abort(); } // WARNING - no return stmt XFAIL *-*-*
+ const A& operator =(const A &) { abort(); }
};
class B : public A {
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C b/gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C
index a624954..4c352c8 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C
@@ -25,10 +25,10 @@ struct00 global_function_1 () {
struct struct0 {
int struct0_member_function_0 () {
- } // ERROR - XFAIL
+ } // ERROR -
struct0 struct0_member_function_1 () {
- } // ERROR - XFAIL
+ } // ERROR -
};
struct struct1 {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/byval2.C b/gcc/testsuite/g++.old-deja/g++.jason/byval2.C
index 490e625..6202581 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/byval2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/byval2.C
@@ -13,8 +13,8 @@ public:
void operator -= (const Char );
};
-inline Char operator - (const Char a, const Char b) {}
-inline char operator == (const Char a, const char b) {}
+inline Char operator - (const Char a, const Char b) { return Char(0); }
+inline char operator == (const Char a, const char b) { return 0; }
char mystrcmp(Char s[31], Char t[31])
{
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators17.C b/gcc/testsuite/g++.old-deja/g++.law/operators17.C
index 9c1a03b..7674233 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators17.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators17.C
@@ -7,6 +7,6 @@
// Subject: 4 bugs in g++ 2.3.3
// Message-ID: <9304291053.AA00090@mencon>
- struct A {
- A& operator = (const A& a) {}// ERROR - XFAIL
- };
+struct A {
+ A& operator = (const A& a) {}// WARNING -
+};
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh50.C b/gcc/testsuite/g++.old-deja/g++.mike/eh50.C
index 84ccadd..702bbda 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/eh50.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/eh50.C
@@ -7,7 +7,7 @@ void my_unexpected() {
throw 42;
}
-template <class T> int foo(T) throw (int) { throw "Hi"; }
+template <class T> void foo(T) throw (int) { throw "Hi"; }
main() {
std::set_unexpected (my_unexpected);
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh51.C b/gcc/testsuite/g++.old-deja/g++.mike/eh51.C
index 9ebeb4e..f1b90b4 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/eh51.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/eh51.C
@@ -7,7 +7,7 @@ void my_unexpected() {
throw 42;
}
-template <class T> int foo(T) throw (T) { throw "Hi"; }
+template <class T> void foo(T) throw (T) { throw "Hi"; }
main() {
std::set_unexpected (my_unexpected);
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net20.C b/gcc/testsuite/g++.old-deja/g++.mike/net20.C
index 916ba43..731f6c1 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net20.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net20.C
@@ -8,4 +8,5 @@ struct X
void (X::* fee ())()
{
lab: goto lab;
+ return 0;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net40.C b/gcc/testsuite/g++.old-deja/g++.mike/net40.C
index 10e16e6..db0df8a 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net40.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net40.C
@@ -1,5 +1,5 @@
#include <stddef.h>
-extern "C" void abort();
+#include <stdlib.h>
class toto {
public:
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net45.C b/gcc/testsuite/g++.old-deja/g++.mike/net45.C
index 388af8f..fca48e9 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net45.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net45.C
@@ -12,8 +12,7 @@ struct myint {
}
myint(const myint& mi) {
}
- myint& operator=(const myint& mi) {
- }
+ myint& operator=(const myint& mi) { return *this; }
};
extern pair<const myint, myint> a;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p10511.C b/gcc/testsuite/g++.old-deja/g++.mike/p10511.C
index b92b4f7..abe12e4 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p10511.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p10511.C
@@ -8,7 +8,7 @@ public:
class C {
public:
- bool f (S::E()) { }
+ bool f (S::E()) { return true; }
virtual void foo();
};
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p11012.C b/gcc/testsuite/g++.old-deja/g++.mike/p11012.C
index aca77d4..407c83a 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p11012.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p11012.C
@@ -4,7 +4,7 @@
class Foo {
public:
- int f(){}
+ int f(){ return 0; }
};
void foo() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p7325.C b/gcc/testsuite/g++.old-deja/g++.mike/p7325.C
index e6d76f5..e481ccd 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p7325.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p7325.C
@@ -23,6 +23,7 @@ struct A {
if (match_arg != &o)
fail = 1;
match_arg = &o;
+ return *this;
}
};
diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash25.C b/gcc/testsuite/g++.old-deja/g++.other/crash25.C
index 2f471fb..0c39be8 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/crash25.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/crash25.C
@@ -9,7 +9,7 @@ public:
X::x()
{ // ERROR -
-}
+} // WARNING - no return
X::~x()
{ // ERROR -
diff --git a/gcc/testsuite/g++.old-deja/g++.other/for1.C b/gcc/testsuite/g++.old-deja/g++.other/for1.C
index 31cd741..e737a41 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/for1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/for1.C
@@ -7,6 +7,7 @@ struct S {
int operator()(int)
{
i = 1;
+ return i;
}
typedef int I;
@@ -24,6 +25,7 @@ struct T {
int operator()(int)
{
j = 1;
+ return j;
}
void f() {
diff --git a/gcc/testsuite/g++.old-deja/g++.other/init12.C b/gcc/testsuite/g++.old-deja/g++.other/init12.C
index ee0a029..9e4a436 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/init12.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/init12.C
@@ -11,7 +11,7 @@ struct S
struct T
{
- static int f() {}
+ static int f() { return 0; }
};
static const S s = { &T::f };
diff --git a/gcc/testsuite/g++.old-deja/g++.other/new.C b/gcc/testsuite/g++.old-deja/g++.other/new.C
index e283957..4518762 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/new.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/new.C
@@ -1,13 +1,16 @@
// Build don't link:
-typedef __SIZE_TYPE__ size_t;
+#include <new>
+
inline void *
operator new(size_t alloc_sz, const char *fname, unsigned lineno)
{
+ return ::operator new (alloc_sz);
}
inline void *
operator new[](size_t alloc_sz, const char *fname, unsigned lineno)
{
+ return ::operator new[] (alloc_sz);
}
inline void
operator delete(void *ptr, const char *fname, unsigned lineno)
diff --git a/gcc/testsuite/g++.old-deja/g++.other/new4.C b/gcc/testsuite/g++.old-deja/g++.other/new4.C
index b9931b1..2eb0954 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/new4.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/new4.C
@@ -6,5 +6,6 @@ struct S {
virtual int f() {
new S[+f()];
+ return 0;
}
};
diff --git a/gcc/testsuite/g++.old-deja/g++.other/rtti1.C b/gcc/testsuite/g++.old-deja/g++.other/rtti1.C
index 7377e15..603c7d2 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/rtti1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/rtti1.C
@@ -39,15 +39,15 @@ class XX {
public:
int xxi;
float xxf;
- int xxf1 () {};
- int xxf2 (int k) {};
+ int xxf1 () { return 0; };
+ int xxf2 (int k) { return 0; };
};
class YY {
public:
int yyi;
double yyd;
- int yyf1 (float f) {};
+ int yyf1 (float f) { return 0; };
double yyf2 () {return yyd;};
};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec1.C b/gcc/testsuite/g++.old-deja/g++.pt/spec1.C
index 7467293..ab18ff8 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/spec1.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/spec1.C
@@ -13,7 +13,7 @@ public:
};
struct Operation {
- double eval(double) {}
+ double eval(double) { return 0; }
};
int main() {