re PR c++/83045 (-Wreturn-type regression in C++)
authorJakub Jelinek <jakub@gcc.gnu.org>
Tue, 21 Nov 2017 17:40:34 +0000 (18:40 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 21 Nov 2017 17:40:34 +0000 (18:40 +0100)
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

36 files changed:
gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wlogical-op-2.c
gcc/testsuite/c-c++-common/pr61405.c
gcc/testsuite/g++.dg/debug/pr53466.C
gcc/testsuite/g++.dg/ipa/pr61800.C
gcc/testsuite/g++.dg/ipa/pr63470.C
gcc/testsuite/g++.dg/ipa/pr68672-1.C
gcc/testsuite/g++.dg/lto/20090221_0.C
gcc/testsuite/g++.dg/lto/20091026-1_1.C
gcc/testsuite/g++.dg/lto/pr54625-1_1.C
gcc/testsuite/g++.dg/opt/combine.C
gcc/testsuite/g++.dg/pr49847.C
gcc/testsuite/g++.dg/pr58438.C
gcc/testsuite/g++.dg/pr59445.C
gcc/testsuite/g++.dg/tm/pr60004.C
gcc/testsuite/g++.dg/torture/pr33627.C
gcc/testsuite/g++.dg/torture/pr43257.C
gcc/testsuite/g++.dg/torture/pr52772.C
gcc/testsuite/g++.dg/torture/pr54684.C
gcc/testsuite/g++.dg/torture/pr55740.C
gcc/testsuite/g++.dg/torture/pr56694.C
gcc/testsuite/g++.dg/torture/pr58369.C
gcc/testsuite/g++.dg/torture/pr59265.C
gcc/testsuite/g++.dg/torture/pr60648.C
gcc/testsuite/g++.dg/torture/pr64280.C
gcc/testsuite/g++.dg/torture/pr64669.C
gcc/testsuite/g++.dg/torture/pr68470.C
gcc/testsuite/g++.dg/torture/pr71281.C
gcc/testsuite/g++.dg/torture/predcom-1.C
gcc/testsuite/g++.dg/tree-ssa/ssa-dse-2.C
gcc/testsuite/g++.dg/ubsan/return-3.C
gcc/testsuite/g++.dg/warn/pr83045.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch13.C
gcc/testsuite/g++.old-deja/g++.eh/crash1.C
gcc/tree-cfg.c

index 35f06c5d3b91ff3666457cf4146c5782f0b6deb4..d631cb694d1d746ed08de40c18eb6e637bf8d355 100644 (file)
@@ -1,7 +1,14 @@
+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>
 
-       * tree-inline.c (expand_call_inline):
-         Remove not needed xstrdup_for_dump.
+       * tree-inline.c (expand_call_inline): Remove not needed
+       xstrdup_for_dump.
 
 2017-11-21  James Cowgill  <James.Cowgill@imgtec.com>
            Jakub Jelinek  <jakub@redhat.com>
index 030435bad3fdc13e61b1ff48881c00b75836ee72..eb333c1251a0a929f7beb7e09154ea2e1cee519a 100644 (file)
@@ -1,3 +1,41 @@
+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>
 
        * gcc.target/i386/movbe-1.c: Update scan string for movbe
index 6360ef98090e2d2be682ba7f034bfe6cea343030..5d8a3fcd91da61d4961661fd5074914643f75b1e 100644 (file)
@@ -9,4 +9,5 @@ fn (int a, int b)
     return a;
   if ((a + 1) || (a + 1)) /* { dg-warning "logical .or. of equal expressions" } */
     return b;
+  return -1;
 }
index 9c05a84764a6ef70a91da69a53621b6de527c5d6..f186926617fc9a08752488555245586942d3088d 100644 (file)
@@ -16,6 +16,7 @@ fn0 (struct S *s)
     case B:
       return 2;
     }
+  return 3;
 }
 
 int
@@ -28,4 +29,5 @@ fn1 (TS *s)
     case B:
       return 2;
     }
+  return 3;
 }
index ecd88bcd187dd75c3d78ca74b5b13691ecb89086..0ab90d478d4b81f9148772612b700f1e8ae4d7b7 100644 (file)
@@ -1,5 +1,5 @@
 // { 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 gimple gimple_seq_node;
index 3bc796f9903430a460e34a08b6c436f0781754d5..e5336f2f120ea1eecb1b72272d84a22010acd786 100644 (file)
@@ -1,7 +1,7 @@
 /* PR ipa/61800 */
 /* { dg-do compile } */
 /* { dg-require-visibility "" } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-return-type" } */
 
 #pragma GCC visibility push(hidden)
 class A
index ffef0a284deea4ba3b4b4c332d576e27327d38df..f2dc111c6b9c47ad065f6d04a38efb74d0ef469d 100644 (file)
@@ -1,6 +1,6 @@
 /* PR ipa/63470.C */
 /* { dg-do compile } */
-/* { dg-options "-O2 -finline-functions" } */
+/* { dg-options "-O2 -finline-functions -Wno-return-type" } */
 
 class A
 {
index fddabe17a434765729124c6682433873d8806850..4e30d66baaec784873e435a4291f2351fbf88ad1 100644 (file)
@@ -1,6 +1,6 @@
 // PR ipa/68672
 // { 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 *a;
index 5bf031906c7e1c221c244611905d10188a7d0646..ccbe4533e289c21264eb25655278b542fa93a218 100644 (file)
@@ -25,6 +25,7 @@ struct Baz
  Baz(Bar &a):a(a) { }
 };
 
+#pragma GCC diagnostic ignored "-Wreturn-type"
 struct Zonk
 {
  Baz baz;
index 28816100e290077e05245a0600ea41936221f418..35ca21859ba714fd114f73cffdc178851b4726ce 100644 (file)
@@ -1,4 +1,6 @@
 #include "20091026-1_a.h"
+
+#pragma GCC diagnostic ignored "-Wreturn-type"
 extern cHead networks;
 class cNetworkType;
 inline cNetworkType *findNetwork(const char *s)
index 2d0d5bfbadf254d23b0da9d797928188e4df2c74..3d5f05e361d5246301ce864806cc038c451256a9 100644 (file)
@@ -1,5 +1,6 @@
 extern "C" double sin (double);
 typedef double UnaryFunType (double);
+#pragma GCC diagnostic ignored "-Wreturn-type"
 class A
 {
 public:
index a1325a0dca9329c4cccf5756c7689c63a963ab47..08aa9900b180f9582e15e7b34d7a2fb7ad2c8ac4 100644 (file)
@@ -1,5 +1,5 @@
 // { 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 "" }
 
 class QBasicAtomicInt
index b047713c309cbbb39fc5ac27ccb1889ccef4487b..42bd5a18159a99b37908455dc5f4418696db80ce 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O -fnon-call-exceptions" } */
+/* { dg-options "-O -fnon-call-exceptions -Wno-return-type" } */
 int f (float g)
 {
   try { return g >= 0; }
index 4c62cb26ce8324e0e39f42fab1147ee6ce1a77d8..820f070080699dd452e41c65d6466beaa0c0b89c 100644 (file)
@@ -1,5 +1,5 @@
 /* { 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 {};
 struct A {
   gimple_code code;
index 99d6df251953593286955ec9d8439a650b5731a7..660e4aa2e35c6f03e748e67369cc3b01c2b7bbc7 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-return-type" } */
 
 template <typename _Iterator> struct A;
 template <typename _Tp> struct A<_Tp *> {
index b8c2c0e032b11cc26d1de143b481e9aab4720b88..9034336da305587f4a8b8d83a57de405ce0a87ca 100644 (file)
@@ -7,4 +7,4 @@ int f() {
         if (a == 5)
             return 1;
     }
-}
+}      // { dg-warning "control reaches end of non-void function" }
index 9265bd95f05ca2604d91b571fcb6a48762395a55..c17453641d6baa45a391e6c2af0d0c46f0489866 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-additional-options "-Wno-return-type" } */
 
 typedef unsigned int UT_uint32;
 typedef UT_uint32 PT_DocPosition;
index a3e75574adb908d2aa3fe0b86513cba7f9f224df..fab5f09c31a3bd194cc5cc25cbfb74a22b70be4d 100644 (file)
@@ -7,7 +7,7 @@ static void *func (int n)
 {
   void *p;
   if (p == 0) throw ::A ();
-}
+}      // { dg-warning "control reaches end of non-void function" }
 
 static void *func (int n, B const &)
 {
index 0109f13767687f9d59d6be69cea50383b5d44c17..bc5d3a1ddf503ba892ef994ff60b701c516b850a 100644 (file)
@@ -1,4 +1,5 @@
 // { dg-do compile }
+// { dg-additional-options "-Wno-return-type" }
 
 typedef __SIZE_TYPE__ size_t;
 
index 4934011e45fcec3119b1dd358c5e1f0722d3dee5..d13dd8f6f7420361eb50c60149bc8c7b041aa5c3 100644 (file)
@@ -60,4 +60,4 @@ bool visit_ref_for_mod_analysis (gimple stmt __attribute__ ((__unused__)),
       ((void)(__builtin_expect(!(index >= 0), 0) ? __builtin_unreachable(), 0 : 0));
       ipa_set_param_used (info, index, true);
     }
-}
+}      // { dg-warning "control reaches end of non-void function" }
index cdd84254399a66e3b68ed9b0190ae475c7486877..9597c28f965456ffa743814358fc742fadbb5aa9 100644 (file)
@@ -16,4 +16,4 @@ bool IsValidPath( char const * filename )
       if ( *run ) 
        ++run;
     }
-}
+}      // { dg-warning "control reaches end of non-void function" }
index d3de05101695d7ba57e00c1988fc494b2a33da8b..774bac4c61547c9411d70ba1255d3cc41f191fc9 100644 (file)
@@ -20,7 +20,7 @@ inline GVector& GVector::operator+= (const GVector& v)
   if (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];
-};
+};     // { dg-warning "control reaches end of non-void function" }
 void eval(GVector* m_gradient, GVector* vect_cpy_grad, int n)
 {
 #pragma omp sections
index 9284e2ca7684a04d183e72ab2570d9aac477e406..7ae06ad56fe34cfa6271c3919fdc581922e4da73 100644 (file)
@@ -1,4 +1,5 @@
 // { dg-do compile }
+// { dg-additional-options "-Wno-return-type" }
 // Reduced from boost-1.54
 
 int pow(int, int);
index 880c454da10345ff2c1aa4b3ad53f3803fe9a346..d48efe59395ffcf5de5f5d4890f336fce2a59d58 100644 (file)
@@ -1,5 +1,5 @@
 // { dg-do compile }
-// { dg-options "-fprofile-use -std=gnu++11" }
+// { dg-options "-fprofile-use -std=gnu++11 -Wno-return-type" }
 
 class A {
   int m_fn1() const;
index 48cf0afb52b20a329587f6fb424798945d58a40f..5e391e72e353488d5b731eb9c10d5212d8bcd308 100644 (file)
@@ -51,7 +51,7 @@ inline component fn2 (direction p1)
     case P:
       return component (3);
     }
-}
+}      // { dg-warning "control reaches end of non-void function" }
 
 void fn3 ()
 {
index e756e02eca1f49f13c486f66fc4028b8d0c6899d..5c569e864b4c70a311292e8d1ca146b3f2f08067 100644 (file)
@@ -39,4 +39,4 @@ F::m_fn2 ()
     else
       D ();
   A b;
-}
+}      // { dg-warning "control reaches end of non-void function" }
index a4e7d3a8a2847675a7b1201fe9d2ef7e56af2b6f..c43b3add18ee29c14eafa6e3e9de0a2cac7a76b0 100644 (file)
@@ -1,3 +1,5 @@
+// { dg-additional-options "-Wno-return-type" }
+
 typedef unsigned int source_location;
 typedef source_location location_t;
 extern void error_at (location_t, const char *, ...)
index 5dd558d15d20b06ecd9439e41a318a240902df8f..ea5701aa151d792595a17802b98c942d4bdd1d5c 100644 (file)
@@ -11,7 +11,7 @@ struct D {
     C *m_fn2() {
        if (a)
          __builtin_abort();
-    }
+    }  // { dg-warning "control reaches end of non-void function" }
 };
 D getd();
 
index 7d429a95b1ba6c57ef7a2426a98bae52629c3145..7c68b56015adfc5018170bce813cf8245f549b8a 100644 (file)
@@ -47,7 +47,7 @@ public:
     reference m_fn3(unsigned){
        if (m_fn2())
          fn1();
-    }
+    }  // { dg-warning "control reaches end of non-void function" }
 };
 
 H<H<H<unsigned>>> c;
index 9e9a4b38cfa9fc4f2a4d56d0cff46fc8e5b2b6ea..ff68fd0e9aff5c7fa51f1ee075dc80046e266632 100644 (file)
@@ -1,6 +1,8 @@
 /* Test for ICE in predictive commoning with empty loop header block
    on arm-none-linux-*.  */
 
+#pragma GCC diagnostic ignored "-Wreturn-type"
+
 struct Foo
 {
   double *ptr;
index 913df2223747f4942cfac1eb9395d24b74ca03c8..ca7e18f66a9a93667b17397dd6dbbc50f4f19484 100644 (file)
@@ -1,5 +1,5 @@
 /* { 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;
 extern "C"
index 95f345deb320cf61e0aaa1d9702ba6bf7a2f5dea..ee90e59ab2b225741585049ce15fb9e82e0bb509 100644 (file)
@@ -1,5 +1,5 @@
 // { dg-do compile }
-// { dg-options "-fsanitize=return" }
+// { dg-options "-fsanitize=return -Wno-return-type" }
 
 struct S { S (); ~S (); };
 
diff --git a/gcc/testsuite/g++.dg/warn/pr83045.C b/gcc/testsuite/g++.dg/warn/pr83045.C
new file mode 100644 (file)
index 0000000..3709d36
--- /dev/null
@@ -0,0 +1,19 @@
+// 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" } */
index 2e0fdc8e7b5ba7cd7ce6dc855300780fc88294a2..90c533e5e4acb778a55f881c76076dc48603c57f 100644 (file)
@@ -1,5 +1,5 @@
 // { dg-do assemble  }
-// { dg-options "-O2" }
+// { dg-options "-O2 -Wno-return-type" }
 // Copyright (C) 2001 Free Software Foundation, Inc.
 // Contributed by Jakub Jelinek 2 May 2001 <jakub@redhat.com>
 
index a4440c7bd95a5fb3635049836d3f9b32a2c77d2e..e4c83700c989b4630ceca1709e92f2bf999c6e08 100644 (file)
@@ -1,5 +1,5 @@
 // { dg-do assemble  }
-// { dg-options "-O1 -fno-inline-functions" }
+// { dg-options "-O1 -fno-inline-functions -Wno-return-type" }
 
 struct A
 {
index 491ac059c59112d36ec0e37a2224cfc278d55a39..bdcb04f8c4aaeec7ddb0730d788f7e982d1f4362 100644 (file)
@@ -9049,7 +9049,8 @@ pass_warn_function_return::execute (function *fun)
          if ((gimple_code (last) == GIMPLE_RETURN
               || gimple_call_builtin_p (last, BUILT_IN_RETURN))
              && location == UNKNOWN_LOCATION
-             && (location = gimple_location (last)) != UNKNOWN_LOCATION
+             && ((location = LOCATION_LOCUS (gimple_location (last)))
+                 != UNKNOWN_LOCATION)
              && !optimize)
            break;
          /* When optimizing, replace return stmts in noreturn functions
@@ -9075,7 +9076,6 @@ pass_warn_function_return::execute (function *fun)
      without returning a value.  */
   else if (warn_return_type > 0
           && !TREE_NO_WARNING (fun->decl)
-          && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) > 0
           && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl))))
     {
       FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds)
@@ -9087,13 +9087,43 @@ pass_warn_function_return::execute (function *fun)
              && !gimple_no_warning_p (last))
            {
              location = gimple_location (last);
-             if (location == UNKNOWN_LOCATION)
+             if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION)
                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;
              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;
 }