Commit 826eccc6 by Jakub Jelinek

re PR c++/83045 (-Wreturn-type regression in C++)

	PR c++/83045
	* tree-cfg.c (pass_warn_function_return::execute): Formatting fix.
	Also warn if seen __builtin_unreachable () call with BUILTINS_LOCATION.
	Use LOCATION_LOCUS when comparing against UNKNOWN_LOCATION.

	* c-c++-common/pr61405.c (fn0, fn1): Add return stmts.
	* c-c++-common/Wlogical-op-2.c (fn): Likewise.
	* g++.dg/debug/pr53466.C: Add -Wno-return-type to dg-options.
	* g++.dg/opt/combine.C: Likewise.
	* g++.dg/ubsan/return-3.C: Likewise.
	* g++.dg/pr59445.C: Likewise.
	* g++.dg/pr49847.C: Likewise.
	* g++.dg/ipa/pr61800.C: Likewise.
	* g++.dg/ipa/pr63470.C: Likewise.
	* g++.dg/ipa/pr68672-1.C: Likewise.
	* g++.dg/pr58438.C: Likewise.
	* g++.dg/torture/pr59265.C: Likewise.
	* g++.dg/tree-ssa/ssa-dse-2.C: Likewise.
	* g++.old-deja/g++.eh/catch13.C: Likewise.
	* g++.old-deja/g++.eh/crash1.C: Likewise.
	* g++.dg/tm/pr60004.C: Expect -Wreturn-type warning.
	* g++.dg/torture/pr55740.C: Likewise.
	* g++.dg/torture/pr43257.C: Likewise.
	* g++.dg/torture/pr64280.C: Likewise.
	* g++.dg/torture/pr54684.C: Likewise.
	* g++.dg/torture/pr56694.C: Likewise.
	* g++.dg/torture/pr68470.C: Likewise.
	* g++.dg/torture/pr60648.C: Likewise.
	* g++.dg/torture/pr71281.C: Likewise.
	* g++.dg/torture/pr52772.C: Add -Wno-return-type dg-additional-options.
	* g++.dg/torture/pr64669.C: Likewise.
	* g++.dg/torture/pr58369.C: Likewise.
	* g++.dg/torture/pr33627.C: Likewise.
	* g++.dg/torture/predcom-1.C: Add
	#pragma GCC diagnostic ignored "-Wreturn-type".
	* g++.dg/lto/20090221_0.C: Likewise.
	* g++.dg/lto/20091026-1_1.C: Likewise.
	* g++.dg/lto/pr54625-1_1.C: Likewise.
	* g++.dg/warn/pr83045.C: New test.

From-SVN: r255018
parent 8fccb0a6
2017-11-21 Jakub Jelinek <jakub@redhat.com>
PR c++/83045
* tree-cfg.c (pass_warn_function_return::execute): Formatting fix.
Also warn if seen __builtin_unreachable () call with BUILTINS_LOCATION.
Use LOCATION_LOCUS when comparing against UNKNOWN_LOCATION.
2017-11-21 Martin Liska <mliska@suse.cz> 2017-11-21 Martin Liska <mliska@suse.cz>
* tree-inline.c (expand_call_inline): * tree-inline.c (expand_call_inline): Remove not needed
Remove not needed xstrdup_for_dump. xstrdup_for_dump.
2017-11-21 James Cowgill <James.Cowgill@imgtec.com> 2017-11-21 James Cowgill <James.Cowgill@imgtec.com>
Jakub Jelinek <jakub@redhat.com> Jakub Jelinek <jakub@redhat.com>
2017-11-21 Jakub Jelinek <jakub@redhat.com>
PR c++/83045
* c-c++-common/pr61405.c (fn0, fn1): Add return stmts.
* c-c++-common/Wlogical-op-2.c (fn): Likewise.
* g++.dg/debug/pr53466.C: Add -Wno-return-type to dg-options.
* g++.dg/opt/combine.C: Likewise.
* g++.dg/ubsan/return-3.C: Likewise.
* g++.dg/pr59445.C: Likewise.
* g++.dg/pr49847.C: Likewise.
* g++.dg/ipa/pr61800.C: Likewise.
* g++.dg/ipa/pr63470.C: Likewise.
* g++.dg/ipa/pr68672-1.C: Likewise.
* g++.dg/pr58438.C: Likewise.
* g++.dg/torture/pr59265.C: Likewise.
* g++.dg/tree-ssa/ssa-dse-2.C: Likewise.
* g++.old-deja/g++.eh/catch13.C: Likewise.
* g++.old-deja/g++.eh/crash1.C: Likewise.
* g++.dg/tm/pr60004.C: Expect -Wreturn-type warning.
* g++.dg/torture/pr55740.C: Likewise.
* g++.dg/torture/pr43257.C: Likewise.
* g++.dg/torture/pr64280.C: Likewise.
* g++.dg/torture/pr54684.C: Likewise.
* g++.dg/torture/pr56694.C: Likewise.
* g++.dg/torture/pr68470.C: Likewise.
* g++.dg/torture/pr60648.C: Likewise.
* g++.dg/torture/pr71281.C: Likewise.
* g++.dg/torture/pr52772.C: Add -Wno-return-type dg-additional-options.
* g++.dg/torture/pr64669.C: Likewise.
* g++.dg/torture/pr58369.C: Likewise.
* g++.dg/torture/pr33627.C: Likewise.
* g++.dg/torture/predcom-1.C: Add
#pragma GCC diagnostic ignored "-Wreturn-type".
* g++.dg/lto/20090221_0.C: Likewise.
* g++.dg/lto/20091026-1_1.C: Likewise.
* g++.dg/lto/pr54625-1_1.C: Likewise.
* g++.dg/warn/pr83045.C: New test.
2017-11-21 Uros Bizjak <ubizjak@gmail.com> 2017-11-21 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/movbe-1.c: Update scan string for movbe * gcc.target/i386/movbe-1.c: Update scan string for movbe
......
...@@ -9,4 +9,5 @@ fn (int a, int b) ...@@ -9,4 +9,5 @@ fn (int a, int b)
return a; return a;
if ((a + 1) || (a + 1)) /* { dg-warning "logical .or. of equal expressions" } */ if ((a + 1) || (a + 1)) /* { dg-warning "logical .or. of equal expressions" } */
return b; return b;
return -1;
} }
...@@ -16,6 +16,7 @@ fn0 (struct S *s) ...@@ -16,6 +16,7 @@ fn0 (struct S *s)
case B: case B:
return 2; return 2;
} }
return 3;
} }
int int
...@@ -28,4 +29,5 @@ fn1 (TS *s) ...@@ -28,4 +29,5 @@ fn1 (TS *s)
case B: case B:
return 2; return 2;
} }
return 3;
} }
// { dg-do compile } // { dg-do compile }
// { dg-options "-foptimize-sibling-calls -fcompare-debug" } // { dg-options "-foptimize-sibling-calls -fcompare-debug -Wno-return-type" }
typedef union gimple_statement_d *gimple; typedef union gimple_statement_d *gimple;
typedef gimple gimple_seq_node; typedef gimple gimple_seq_node;
......
/* PR ipa/61800 */ /* PR ipa/61800 */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-require-visibility "" } */ /* { dg-require-visibility "" } */
/* { dg-options "-O2" } */ /* { dg-options "-O2 -Wno-return-type" } */
#pragma GCC visibility push(hidden) #pragma GCC visibility push(hidden)
class A class A
......
/* PR ipa/63470.C */ /* PR ipa/63470.C */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -finline-functions" } */ /* { dg-options "-O2 -finline-functions -Wno-return-type" } */
class A class A
{ {
......
// PR ipa/68672 // PR ipa/68672
// { dg-do compile } // { dg-do compile }
// { dg-options "-O -finline-small-functions -fpartial-inlining --param=partial-inlining-entry-probability=100" } // { dg-options "-O -finline-small-functions -fpartial-inlining --param=partial-inlining-entry-probability=100 -Wno-return-type" }
void f2 (void *); void f2 (void *);
void *a; void *a;
......
...@@ -25,6 +25,7 @@ struct Baz ...@@ -25,6 +25,7 @@ struct Baz
Baz(Bar &a):a(a) { } Baz(Bar &a):a(a) { }
}; };
#pragma GCC diagnostic ignored "-Wreturn-type"
struct Zonk struct Zonk
{ {
Baz baz; Baz baz;
......
#include "20091026-1_a.h" #include "20091026-1_a.h"
#pragma GCC diagnostic ignored "-Wreturn-type"
extern cHead networks; extern cHead networks;
class cNetworkType; class cNetworkType;
inline cNetworkType *findNetwork(const char *s) inline cNetworkType *findNetwork(const char *s)
......
extern "C" double sin (double); extern "C" double sin (double);
typedef double UnaryFunType (double); typedef double UnaryFunType (double);
#pragma GCC diagnostic ignored "-Wreturn-type"
class A class A
{ {
public: public:
......
// { dg-do assemble { target fpic } } // { dg-do assemble { target fpic } }
// { dg-options "-O2 -fweb -fPIC -fvisibility=hidden" } // { dg-options "-O2 -fweb -fPIC -fvisibility=hidden -Wno-return-type" }
// { dg-require-visibility "" } // { dg-require-visibility "" }
class QBasicAtomicInt class QBasicAtomicInt
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O -fnon-call-exceptions" } */ /* { dg-options "-O -fnon-call-exceptions -Wno-return-type" } */
int f (float g) int f (float g)
{ {
try { return g >= 0; } try { return g >= 0; }
......
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-march=amdfam10 -O3 -fprofile-generate" } */ /* { dg-options "-march=amdfam10 -O3 -fprofile-generate -Wno-return-type" } */
enum gimple_code {}; enum gimple_code {};
struct A { struct A {
gimple_code code; gimple_code code;
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2" } */ /* { dg-options "-O2 -Wno-return-type" } */
template <typename _Iterator> struct A; template <typename _Iterator> struct A;
template <typename _Tp> struct A<_Tp *> { template <typename _Tp> struct A<_Tp *> {
......
...@@ -7,4 +7,4 @@ int f() { ...@@ -7,4 +7,4 @@ int f() {
if (a == 5) if (a == 5)
return 1; return 1;
} }
} } // { dg-warning "control reaches end of non-void function" }
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-additional-options "-Wno-return-type" } */
typedef unsigned int UT_uint32; typedef unsigned int UT_uint32;
typedef UT_uint32 PT_DocPosition; typedef UT_uint32 PT_DocPosition;
......
...@@ -7,7 +7,7 @@ static void *func (int n) ...@@ -7,7 +7,7 @@ static void *func (int n)
{ {
void *p; void *p;
if (p == 0) throw ::A (); if (p == 0) throw ::A ();
} } // { dg-warning "control reaches end of non-void function" }
static void *func (int n, B const &) static void *func (int n, B const &)
{ {
......
// { dg-do compile } // { dg-do compile }
// { dg-additional-options "-Wno-return-type" }
typedef __SIZE_TYPE__ size_t; typedef __SIZE_TYPE__ size_t;
......
...@@ -60,4 +60,4 @@ bool visit_ref_for_mod_analysis (gimple stmt __attribute__ ((__unused__)), ...@@ -60,4 +60,4 @@ bool visit_ref_for_mod_analysis (gimple stmt __attribute__ ((__unused__)),
((void)(__builtin_expect(!(index >= 0), 0) ? __builtin_unreachable(), 0 : 0)); ((void)(__builtin_expect(!(index >= 0), 0) ? __builtin_unreachable(), 0 : 0));
ipa_set_param_used (info, index, true); ipa_set_param_used (info, index, true);
} }
} } // { dg-warning "control reaches end of non-void function" }
...@@ -16,4 +16,4 @@ bool IsValidPath( char const * filename ) ...@@ -16,4 +16,4 @@ bool IsValidPath( char const * filename )
if ( *run ) if ( *run )
++run; ++run;
} }
} } // { dg-warning "control reaches end of non-void function" }
...@@ -20,7 +20,7 @@ inline GVector& GVector::operator+= (const GVector& v) ...@@ -20,7 +20,7 @@ inline GVector& GVector::operator+= (const GVector& v)
if (m_num != v.m_num) if (m_num != v.m_num)
throw GException::vector_mismatch(m_num, v.m_num); throw GException::vector_mismatch(m_num, v.m_num);
for (int i = 0; i < m_num; ++i) m_data[i] += v.m_data[i]; for (int i = 0; i < m_num; ++i) m_data[i] += v.m_data[i];
}; }; // { dg-warning "control reaches end of non-void function" }
void eval(GVector* m_gradient, GVector* vect_cpy_grad, int n) void eval(GVector* m_gradient, GVector* vect_cpy_grad, int n)
{ {
#pragma omp sections #pragma omp sections
......
// { dg-do compile } // { dg-do compile }
// { dg-additional-options "-Wno-return-type" }
// Reduced from boost-1.54 // Reduced from boost-1.54
int pow(int, int); int pow(int, int);
......
// { dg-do compile } // { dg-do compile }
// { dg-options "-fprofile-use -std=gnu++11" } // { dg-options "-fprofile-use -std=gnu++11 -Wno-return-type" }
class A { class A {
int m_fn1() const; int m_fn1() const;
......
...@@ -51,7 +51,7 @@ inline component fn2 (direction p1) ...@@ -51,7 +51,7 @@ inline component fn2 (direction p1)
case P: case P:
return component (3); return component (3);
} }
} } // { dg-warning "control reaches end of non-void function" }
void fn3 () void fn3 ()
{ {
......
...@@ -39,4 +39,4 @@ F::m_fn2 () ...@@ -39,4 +39,4 @@ F::m_fn2 ()
else else
D (); D ();
A b; A b;
} } // { dg-warning "control reaches end of non-void function" }
// { dg-additional-options "-Wno-return-type" }
typedef unsigned int source_location; typedef unsigned int source_location;
typedef source_location location_t; typedef source_location location_t;
extern void error_at (location_t, const char *, ...) extern void error_at (location_t, const char *, ...)
......
...@@ -11,7 +11,7 @@ struct D { ...@@ -11,7 +11,7 @@ struct D {
C *m_fn2() { C *m_fn2() {
if (a) if (a)
__builtin_abort(); __builtin_abort();
} } // { dg-warning "control reaches end of non-void function" }
}; };
D getd(); D getd();
......
...@@ -47,7 +47,7 @@ public: ...@@ -47,7 +47,7 @@ public:
reference m_fn3(unsigned){ reference m_fn3(unsigned){
if (m_fn2()) if (m_fn2())
fn1(); fn1();
} } // { dg-warning "control reaches end of non-void function" }
}; };
H<H<H<unsigned>>> c; H<H<H<unsigned>>> c;
......
/* Test for ICE in predictive commoning with empty loop header block /* Test for ICE in predictive commoning with empty loop header block
on arm-none-linux-*. */ on arm-none-linux-*. */
#pragma GCC diagnostic ignored "-Wreturn-type"
struct Foo struct Foo
{ {
double *ptr; double *ptr;
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-dse2-details" } */ /* { dg-options "-O2 -fdump-tree-dse2-details -Wno-return-type" } */
typedef __SIZE_TYPE__ size_t; typedef __SIZE_TYPE__ size_t;
extern "C" extern "C"
......
// { dg-do compile } // { dg-do compile }
// { dg-options "-fsanitize=return" } // { dg-options "-fsanitize=return -Wno-return-type" }
struct S { S (); ~S (); }; struct S { S (); ~S (); };
......
// PR c++/83045
// { dg-do compile }
// { dg-options "-Wreturn-type -O2" }
void foo (void);
int
bar (int a)
{
if (a != 0)
foo ();
} /* { dg-warning "no return statement in function returning non-void" } */
int
baz (int a)
{
if (a != 0)
__builtin_abort ();
} /* { dg-warning "control reaches end of non-void function" } */
// { dg-do assemble } // { dg-do assemble }
// { dg-options "-O2" } // { dg-options "-O2 -Wno-return-type" }
// Copyright (C) 2001 Free Software Foundation, Inc. // Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Jakub Jelinek 2 May 2001 <jakub@redhat.com> // Contributed by Jakub Jelinek 2 May 2001 <jakub@redhat.com>
......
// { dg-do assemble } // { dg-do assemble }
// { dg-options "-O1 -fno-inline-functions" } // { dg-options "-O1 -fno-inline-functions -Wno-return-type" }
struct A struct A
{ {
......
...@@ -9049,7 +9049,8 @@ pass_warn_function_return::execute (function *fun) ...@@ -9049,7 +9049,8 @@ pass_warn_function_return::execute (function *fun)
if ((gimple_code (last) == GIMPLE_RETURN if ((gimple_code (last) == GIMPLE_RETURN
|| gimple_call_builtin_p (last, BUILT_IN_RETURN)) || gimple_call_builtin_p (last, BUILT_IN_RETURN))
&& location == UNKNOWN_LOCATION && location == UNKNOWN_LOCATION
&& (location = gimple_location (last)) != UNKNOWN_LOCATION && ((location = LOCATION_LOCUS (gimple_location (last)))
!= UNKNOWN_LOCATION)
&& !optimize) && !optimize)
break; break;
/* When optimizing, replace return stmts in noreturn functions /* When optimizing, replace return stmts in noreturn functions
...@@ -9075,7 +9076,6 @@ pass_warn_function_return::execute (function *fun) ...@@ -9075,7 +9076,6 @@ pass_warn_function_return::execute (function *fun)
without returning a value. */ without returning a value. */
else if (warn_return_type > 0 else if (warn_return_type > 0
&& !TREE_NO_WARNING (fun->decl) && !TREE_NO_WARNING (fun->decl)
&& EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) > 0
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl)))) && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl))))
{ {
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds)
...@@ -9087,13 +9087,43 @@ pass_warn_function_return::execute (function *fun) ...@@ -9087,13 +9087,43 @@ pass_warn_function_return::execute (function *fun)
&& !gimple_no_warning_p (last)) && !gimple_no_warning_p (last))
{ {
location = gimple_location (last); location = gimple_location (last);
if (location == UNKNOWN_LOCATION) if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION)
location = fun->function_end_locus; location = fun->function_end_locus;
warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function"); warning_at (location, OPT_Wreturn_type,
"control reaches end of non-void function");
TREE_NO_WARNING (fun->decl) = 1; TREE_NO_WARNING (fun->decl) = 1;
break; break;
} }
} }
/* The C++ FE turns fallthrough from the end of non-void function
into __builtin_unreachable () call with BUILTINS_LOCATION.
Recognize those too. */
basic_block bb;
if (!TREE_NO_WARNING (fun->decl))
FOR_EACH_BB_FN (bb, fun)
if (EDGE_COUNT (bb->succs) == 0)
{
gimple *last = last_stmt (bb);
if (last
&& (LOCATION_LOCUS (gimple_location (last))
== BUILTINS_LOCATION)
&& gimple_call_builtin_p (last, BUILT_IN_UNREACHABLE))
{
gimple_stmt_iterator gsi = gsi_for_stmt (last);
gsi_prev_nondebug (&gsi);
gimple *prev = gsi_stmt (gsi);
if (prev == NULL)
location = UNKNOWN_LOCATION;
else
location = gimple_location (prev);
if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION)
location = fun->function_end_locus;
warning_at (location, OPT_Wreturn_type,
"control reaches end of non-void function");
TREE_NO_WARNING (fun->decl) = 1;
break;
}
}
} }
return 0; return 0;
} }
......
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