diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-12-21 15:51:19 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-12-21 15:51:19 +0100 |
commit | bccc50d44c8b79ecb6b0237912e96369e5625d17 (patch) | |
tree | 2b7fe3b05edf700cf89f2391169f78c73ef31628 /gcc | |
parent | 2091795abd48effcbfe9407b7954021473175b0a (diff) | |
download | gcc-bccc50d44c8b79ecb6b0237912e96369e5625d17.zip gcc-bccc50d44c8b79ecb6b0237912e96369e5625d17.tar.gz gcc-bccc50d44c8b79ecb6b0237912e96369e5625d17.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wreturn-4.C | 48 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr51644.c | 33 | ||||
-rw-r--r-- | gcc/tree-eh.c | 15 | ||||
-rw-r--r-- | gcc/tree-inline.c | 3 |
6 files changed, 115 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c0b6d76..86c7dc6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-12-21 Jakub Jelinek <jakub@redhat.com> + + 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 <aldyh@redhat.com> PR middle-end/51472 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9228371..b0e247c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-12-21 Jakub Jelinek <jakub@redhat.com> + + 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 <michael.v.zolotukhin@intel.com> * 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 0000000..7d751f2 --- /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 <typename T> +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 <JSObject> 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 0000000..2038a0c --- /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 <stdarg.h> + +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 0631ee1..cad37e6 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 13ad815..9d111d2 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); |