The GIMPLE FE currently invokes parser_build_unary_op to build unary GENERIC which has the operand subject to C promotion rules which does not match GIMPLE. The following adds a wrapper around the build_unary_op worker which conveniently has an argument to indicate whether to skip such promotion.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR c/118742 gcc/c/ * gimple-parser.cc (gimple_parser_build_unary_op): New wrapper around build_unary_op. (c_parser_gimple_unary_expression): Use it. * gcc.dg/gimplefe-56.c: New testcase. --- gcc/c/gimple-parser.cc | 49 +++++++++++++++++++++++++----- gcc/testsuite/gcc.dg/gimplefe-56.c | 24 +++++++++++++++ 2 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/gimplefe-56.c diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc index 54ecf22151c..90b9beb1e9f 100644 --- a/gcc/c/gimple-parser.cc +++ b/gcc/c/gimple-parser.cc @@ -125,6 +125,39 @@ static tree c_parser_gimple_paren_condition (gimple_parser &); static void c_parser_gimple_expr_list (gimple_parser &, vec<tree> *); +/* Much like parser_build_unary_op, but avoid applying default conversions. */ + +static c_expr +gimple_parser_build_unary_op (location_t loc, + enum tree_code code, struct c_expr arg) +{ + struct c_expr result; + + result.original_code = code; + result.original_type = NULL; + result.m_decimal = 0; + + if (reject_gcc_builtin (arg.value)) + { + result.value = error_mark_node; + } + else + { + result.value = build_unary_op (loc, code, arg.value, true); + + if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value)) + overflow_warning (loc, result.value, arg.value); + } + + /* We are typically called when parsing a prefix token at LOC acting on + ARG. Reflect this by updating the source range of the result to + start at LOC and end at the end of ARG. */ + set_c_expr_source_range (&result, + loc, arg.get_finish ()); + + return result; +} + /* See if VAL is an identifier matching __BB<num> and return <num> in *INDEX. */ @@ -1203,7 +1236,7 @@ c_parser_gimple_unary_expression (gimple_parser &parser) c_parser_consume_token (parser); op = c_parser_gimple_postfix_expression (parser); mark_exp_read (op.value); - return parser_build_unary_op (op_loc, ADDR_EXPR, op); + return gimple_parser_build_unary_op (op_loc, ADDR_EXPR, op); case CPP_MULT: { c_parser_consume_token (parser); @@ -1228,15 +1261,15 @@ c_parser_gimple_unary_expression (gimple_parser &parser) case CPP_PLUS: c_parser_consume_token (parser); op = c_parser_gimple_postfix_expression (parser); - return parser_build_unary_op (op_loc, CONVERT_EXPR, op); + return gimple_parser_build_unary_op (op_loc, CONVERT_EXPR, op); case CPP_MINUS: c_parser_consume_token (parser); op = c_parser_gimple_postfix_expression (parser); - return parser_build_unary_op (op_loc, NEGATE_EXPR, op); + return gimple_parser_build_unary_op (op_loc, NEGATE_EXPR, op); case CPP_COMPL: c_parser_consume_token (parser); op = c_parser_gimple_postfix_expression (parser); - return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op); + return gimple_parser_build_unary_op (op_loc, BIT_NOT_EXPR, op); case CPP_NOT: c_parser_error (parser, "%<!%> not valid in GIMPLE"); return ret; @@ -1246,11 +1279,11 @@ c_parser_gimple_unary_expression (gimple_parser &parser) case RID_REALPART: c_parser_consume_token (parser); op = c_parser_gimple_postfix_expression (parser); - return parser_build_unary_op (op_loc, REALPART_EXPR, op); + return gimple_parser_build_unary_op (op_loc, REALPART_EXPR, op); case RID_IMAGPART: c_parser_consume_token (parser); op = c_parser_gimple_postfix_expression (parser); - return parser_build_unary_op (op_loc, IMAGPART_EXPR, op); + return gimple_parser_build_unary_op (op_loc, IMAGPART_EXPR, op); default: return c_parser_gimple_postfix_expression (parser); } @@ -1261,13 +1294,13 @@ c_parser_gimple_unary_expression (gimple_parser &parser) { c_parser_consume_token (parser); op = c_parser_gimple_postfix_expression (parser); - return parser_build_unary_op (op_loc, ABS_EXPR, op); + return gimple_parser_build_unary_op (op_loc, ABS_EXPR, op); } else if (strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0) { c_parser_consume_token (parser); op = c_parser_gimple_postfix_expression (parser); - return parser_build_unary_op (op_loc, ABSU_EXPR, op); + return gimple_parser_build_unary_op (op_loc, ABSU_EXPR, op); } else if (strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0) return c_parser_gimple_parentized_binary_expression (parser, diff --git a/gcc/testsuite/gcc.dg/gimplefe-56.c b/gcc/testsuite/gcc.dg/gimplefe-56.c new file mode 100644 index 00000000000..72c66ae463d --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-56.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +_Bool __GIMPLE (ssa,startwith("optimized")) g1(int i) +{ + _Bool _1; + _Bool _2; + + __BB(2): + _1 = i_3(D) == 1; + _2 = ~_1; + return _2; +} + +signed char __GIMPLE (ssa,startwith("optimized")) g2(signed char i) +{ + signed char _1; + signed char _2; + + __BB(2): + _1 = i_3(D); + _2 = -_1; + return _2; +} -- 2.43.0