diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-21 15:47:49 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-21 15:47:49 +0000 |
commit | 7e6fef85fa30a2efcb3424ac4c4580ece43f6b70 (patch) | |
tree | 62b12d022d86e21d5d3cc6b6d10dd4d31dd8afe3 | |
parent | 00f6295120f341592f13b7526e1dddf1dc91fe73 (diff) | |
download | gcc-7e6fef85fa30a2efcb3424ac4c4580ece43f6b70.tar.gz |
PR target/64669
* ccmp.c (used_in_cond_stmt_p): Remove.
(expand_ccmp_expr): Don't use it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219951 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ccmp.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr64669.C | 63 |
3 files changed, 71 insertions, 39 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eda4b2d72fb..3f1dda4188d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-01-21 Richard Henderson <rth@redhat.com> + + PR target/64669 + * ccmp.c (used_in_cond_stmt_p): Remove. + (expand_ccmp_expr): Don't use it. + 2015-01-21 Nick Clifton <nickc@redhat.com> * config/rl78/rl78.c (rl78_calculate_death_notes): Look inside diff --git a/gcc/ccmp.c b/gcc/ccmp.c index 903d5a865de..5d1755402d1 100644 --- a/gcc/ccmp.c +++ b/gcc/ccmp.c @@ -90,9 +90,8 @@ along with GCC; see the file COPYING3. If not see - gen_ccmp_first expands the first compare in CCMP. - gen_ccmp_next expands the following compares. - * If the final result is not used in a COND_EXPR (checked by function - used_in_cond_stmt_p), it calls cstorecc4 pattern to store the CC to a - general register. + * We use cstorecc4 pattern to convert the CCmode intermediate to + the integer mode result that expand_normal is expecting. Since the operands of the later compares might clobber CC reg, we do not emit the insns during expand. We keep the insn sequences in two seq @@ -156,31 +155,6 @@ ccmp_candidate_p (gimple g) return false; } -/* Check whether EXP is used in a GIMPLE_COND statement or not. */ -static bool -used_in_cond_stmt_p (tree exp) -{ - bool expand_cond = false; - imm_use_iterator ui; - gimple use_stmt; - FOR_EACH_IMM_USE_STMT (use_stmt, ui, exp) - if (gimple_code (use_stmt) == GIMPLE_COND) - { - tree op1 = gimple_cond_rhs (use_stmt); - if (integer_zerop (op1)) - expand_cond = true; - BREAK_FROM_IMM_USE_STMT (ui); - } - else if (gimple_code (use_stmt) == GIMPLE_ASSIGN - && gimple_expr_code (use_stmt) == COND_EXPR) - { - if (gimple_assign_rhs1 (use_stmt) == exp) - expand_cond = true; - } - - return expand_cond; -} - /* PREV is the CC flag from precvious compares. The function expands the next compare based on G which ops previous compare with CODE. PREP_SEQ returns all insns to prepare opearands for compare. @@ -301,20 +275,9 @@ expand_ccmp_expr (gimple g) enum machine_mode cc_mode = CCmode; tree lhs = gimple_assign_lhs (g); - /* TMP should be CC. If it is used in a GIMPLE_COND, just return it. - Note: Target needs to define "cbranchcc4". */ - if (used_in_cond_stmt_p (lhs)) - { - emit_insn (prep_seq); - emit_insn (gen_seq); - return tmp; - } - #ifdef SELECT_CC_MODE cc_mode = SELECT_CC_MODE (NE, tmp, const0_rtx); #endif - /* If TMP is not used in a GIMPLE_COND, store it with a csctorecc4_optab. - Note: Target needs to define "cstorecc4". */ icode = optab_handler (cstore_optab, cc_mode); if (icode != CODE_FOR_nothing) { diff --git a/gcc/testsuite/g++.dg/torture/pr64669.C b/gcc/testsuite/g++.dg/torture/pr64669.C new file mode 100644 index 00000000000..b207739e6d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr64669.C @@ -0,0 +1,63 @@ +typedef unsigned int source_location; +typedef source_location location_t; +extern void error_at (location_t, const char *, ...) + __attribute__ ((__format__ (__gcc_tdiag__, 2, 3))) + __attribute__ ((__nonnull__ (2))); + +class Lex +{ + static int fetch_char (const char *str, unsigned int *value); + location_t location () const; + const char *advance_one_utf8_char (const char *, unsigned int *, bool *); + const char *advance_one_char (const char *, bool, unsigned int *, bool *); + int lineoff_; + int lineno_; +}; + +int +Lex::fetch_char (const char *p, unsigned int *value) +{ + unsigned char c = *p; + if (c <= 0x7f) + { + return 1; + } + else if ((c & 0xe0) == 0xc0 && (p[1] & 0xc0) == 0x80) + { + *value = (((c & 0x1f) << 6) + (p[1] & 0x3f)); + } + { + *value = (((c & 0xf) << 12) + (p[2] & 0x3f)); + } +} + +const char * +Lex::advance_one_utf8_char (const char *p, unsigned int *value, + bool * issued_error) +{ + *issued_error = false; + if (*p == '\0') + { + *issued_error = true; + return p + 1; + } + int adv = Lex::fetch_char (p, value); + if (*value == 0xfeff && (this->lineno_ != 1 || this->lineoff_ != 0)) + { + *issued_error = true; + } + return p + adv; +} + +const char * +Lex::advance_one_char (const char *p, bool is_single_quote, + unsigned int *value, bool * is_character) +{ + { + bool issued_error; + const char *ret = this->advance_one_utf8_char (p, value, &issued_error); + if (is_single_quote + && (*value == '\'' || *value == '\n') && !issued_error) + error_at (this->location (), "invalid character literal"); + } +} |