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
This commit is contained in:
parent
f2d9afece3
commit
efe49da0ba
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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;}
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@ struct foo
|
||||
|
||||
static const bar bars[];
|
||||
|
||||
int bad ()
|
||||
void bad ()
|
||||
{
|
||||
this->*(bars[0].b) = 42; // { dg-bogus "read-only" "" }
|
||||
}
|
||||
|
@ -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__));
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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])
|
||||
{
|
||||
|
@ -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 -
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -8,4 +8,5 @@ struct X
|
||||
void (X::* fee ())()
|
||||
{
|
||||
lab: goto lab;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <stddef.h>
|
||||
extern "C" void abort();
|
||||
#include <stdlib.h>
|
||||
|
||||
class toto {
|
||||
public:
|
||||
|
@ -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;
|
||||
|
@ -8,7 +8,7 @@ public:
|
||||
|
||||
class C {
|
||||
public:
|
||||
bool f (S::E()) { }
|
||||
bool f (S::E()) { return true; }
|
||||
virtual void foo();
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
int f(){}
|
||||
int f(){ return 0; }
|
||||
};
|
||||
|
||||
void foo() {
|
||||
|
@ -23,6 +23,7 @@ struct A {
|
||||
if (match_arg != &o)
|
||||
fail = 1;
|
||||
match_arg = &o;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -9,7 +9,7 @@ public:
|
||||
|
||||
X::x()
|
||||
{ // ERROR -
|
||||
}
|
||||
} // WARNING - no return
|
||||
|
||||
X::~x()
|
||||
{ // ERROR -
|
||||
|
@ -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() {
|
||||
|
@ -11,7 +11,7 @@ struct S
|
||||
|
||||
struct T
|
||||
{
|
||||
static int f() {}
|
||||
static int f() { return 0; }
|
||||
};
|
||||
|
||||
static const S s = { &T::f };
|
||||
|
@ -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)
|
||||
|
@ -6,5 +6,6 @@ struct S {
|
||||
|
||||
virtual int f() {
|
||||
new S[+f()];
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
@ -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;};
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,7 @@ public:
|
||||
};
|
||||
|
||||
struct Operation {
|
||||
double eval(double) {}
|
||||
double eval(double) { return 0; }
|
||||
};
|
||||
|
||||
int main() {
|
||||
|
Loading…
Reference in New Issue
Block a user