From: Jakub Jelinek Date: Wed, 21 Dec 2011 14:51:19 +0000 (+0100) Subject: re PR middle-end/51644 (va_list vs. warning: ‘noreturn’ function does return is not... X-Git-Tag: releases/gcc-4.7.0~1371 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bccc50d44c8b79ecb6b0237912e96369e5625d17;p=thirdparty%2Fgcc.git re PR middle-end/51644 (va_list vs. warning: ‘noreturn’ function does return is not fixable) PR middle-end/51644 PR middle-end/51647 * tree-eh.c (decide_copy_try_finally): At -O0, return true even when ndests is not 1, if there are only gimple_clobber_p (or debug) stmts in the finally sequence. * tree-inline.c (estimate_num_insns): Return 0 for gimple_clobber_p stmts. * gcc.dg/pr51644.c: New test. * g++.dg/warn/Wreturn-4.C: New test. From-SVN: r182589 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c0b6d763f387..86c7dc612372 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-12-21 Jakub Jelinek + + PR middle-end/51644 + PR middle-end/51647 + * tree-eh.c (decide_copy_try_finally): At -O0, return true + even when ndests is not 1, if there are only gimple_clobber_p + (or debug) stmts in the finally sequence. + * tree-inline.c (estimate_num_insns): Return 0 for gimple_clobber_p + stmts. + 2011-12-21 Aldy Hernandez PR middle-end/51472 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 922837197ea7..b0e247c04139 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-12-21 Jakub Jelinek + + PR middle-end/51644 + PR middle-end/51647 + * gcc.dg/pr51644.c: New test. + * g++.dg/warn/Wreturn-4.C: New test. + 2011-12-21 Michael Zolotukhin * gcc.dg/vect/no-section-anchors-vect-31.c: Adjust array size and test diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-4.C b/gcc/testsuite/g++.dg/warn/Wreturn-4.C new file mode 100644 index 000000000000..7d751f2ded01 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wreturn-4.C @@ -0,0 +1,48 @@ +// PR middle-end/51647 +// { dg-do compile } +// { dg-options "-Wall" } + +enum PropertyAttributes { NONE = 1 }; +enum PropertyType { NORMAL = 0, FIELD = 1 }; +class LookupResult; + +template +struct Handle +{ + inline explicit Handle (T *obj) __attribute__ ((always_inline)) {} + inline T *operator-> () const __attribute__ ((always_inline)) { return 0; } +}; + +struct JSObject +{ + bool IsGlobalObject () { return false; } +}; + +struct Isolate +{ + LookupResult *top_lookup_result () { return 0; } +}; + +struct LookupResult +{ + explicit LookupResult (Isolate *isolate) {} + JSObject *holder () { return 0; } + PropertyType type () { return NORMAL; } +}; + +int +test (LookupResult *lookup) +{ + Handle holder (lookup->holder ()); + switch (lookup->type ()) + { + case NORMAL: + if (holder->IsGlobalObject ()) + return 2; + else + return 3; + break; + default: + return 4; + } +} // { dg-bogus "control reaches end of non-void function" } diff --git a/gcc/testsuite/gcc.dg/pr51644.c b/gcc/testsuite/gcc.dg/pr51644.c new file mode 100644 index 000000000000..2038a0c4b930 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr51644.c @@ -0,0 +1,33 @@ +/* PR middle-end/51644 */ +/* { dg-do compile } */ +/* { dg-options "-Wall -fexceptions" } */ + +#include + +extern void baz (int, va_list) __attribute__ ((__noreturn__)); + +__attribute__ ((__noreturn__)) +void +foo (int s, ...) +{ + va_list ap; + va_start (ap, s); + baz (s, ap); + va_end (ap); +} /* { dg-bogus "function does return" } */ + +__attribute__ ((__noreturn__)) +void +bar (int s, ...) +{ + va_list ap1; + va_start (ap1, s); + { + va_list ap2; + va_start (ap2, s); + baz (s, ap1); + baz (s, ap2); + va_end (ap2); + } + va_end (ap1); +} /* { dg-bogus "function does return" } */ diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 0631ee1cf8dd..cad37e672420 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -1538,7 +1538,20 @@ decide_copy_try_finally (int ndests, bool may_throw, gimple_seq finally) } if (!optimize) - return ndests == 1; + { + gimple_stmt_iterator gsi; + + if (ndests == 1) + return true; + + for (gsi = gsi_start (finally); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + if (!is_gimple_debug (stmt) && !gimple_clobber_p (stmt)) + return false; + } + return true; + } /* Finally estimate N times, plus N gotos. */ f_estimate = count_insns_seq (finally, &eni_size_weights); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 13ad8153fa9a..9d111d2a4d79 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3482,6 +3482,9 @@ estimate_num_insns (gimple stmt, eni_weights *weights) likely be a real store, so the cost of the GIMPLE_ASSIGN is the cost of moving something into "a", which we compute using the function estimate_move_cost. */ + if (gimple_clobber_p (stmt)) + return 0; /* ={v} {CLOBBER} stmt expands to nothing. */ + lhs = gimple_assign_lhs (stmt); rhs = gimple_assign_rhs1 (stmt);