From: Nathan Froyd Date: Thu, 18 Nov 2010 16:24:56 +0000 (+0000) Subject: re PR c/33193 (slopiness in __real/__imag) X-Git-Tag: releases/gcc-4.6.0~2499 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fb52b50a920a7571af3de43d679fa42483c56a96;p=thirdparty%2Fgcc.git re PR c/33193 (slopiness in __real/__imag) gcc/ PR c/33193 * c-typeck.c (build_unary_op): Call build_real_imag_expr for REALPART_EXPR and IMAGPART_EXPR. gcc/c-family/ PR c/33193 * c-common.h (build_real_imag_expr): Declare. * c-semantics.c (build_real_imag_expr): Define. gcc/cp/ PR c/33193 * typeck.c (cp_build_unary_op): Call build_real_imag_expr for REALPART_EXPR and IMAGPART_EXPR. gcc/testsuite/ PR c/33193 * c-c++-common/pr33193.c: New test. From-SVN: r166909 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7aa714c802f2..53750914b661 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-11-18 Nathan Froyd + + PR c/33193 + * c-typeck.c (build_unary_op): Call build_real_imag_expr for + REALPART_EXPR and IMAGPART_EXPR. + 2010-11-18 Richard Guenther PR tree-optimization/46172 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 81e636c28f50..86fbd1335106 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2010-11-18 Nathan Froyd + + PR c/33193 + * c-common.h (build_real_imag_expr): Declare. + * c-semantics.c (build_real_imag_expr): Define. + 2010-11-17 Joseph Myers * c-opts.c (c_common_parse_file): Take no arguments. diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 76842d2ded1b..3de32cf6ddaa 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -822,6 +822,7 @@ extern void warn_for_omitted_condop (location_t, tree); extern tree do_case (location_t, tree, tree); extern tree build_stmt (location_t, enum tree_code, ...); extern tree build_case_label (location_t, tree, tree, tree); +extern tree build_real_imag_expr (location_t, enum tree_code, tree); /* These functions must be defined by each front-end which implements a variant of the C language. They are used in c-common.c. */ diff --git a/gcc/c-family/c-semantics.c b/gcc/c-family/c-semantics.c index 0eccd5189e4b..d26d8718021b 100644 --- a/gcc/c-family/c-semantics.c +++ b/gcc/c-family/c-semantics.c @@ -140,3 +140,35 @@ build_case_label (location_t loc, { return build_stmt (loc, CASE_LABEL_EXPR, low_value, high_value, label_decl); } + +/* Build a REALPART_EXPR or IMAGPART_EXPR, according to CODE, from ARG. */ + +tree +build_real_imag_expr (location_t location, enum tree_code code, tree arg) +{ + tree ret; + tree arg_type = TREE_TYPE (arg); + + gcc_assert (code == REALPART_EXPR || code == IMAGPART_EXPR); + + if (TREE_CODE (arg_type) == COMPLEX_TYPE) + { + ret = build1 (code, TREE_TYPE (TREE_TYPE (arg)), arg); + SET_EXPR_LOCATION (ret, location); + } + else if (INTEGRAL_TYPE_P (arg_type) || SCALAR_FLOAT_TYPE_P (arg_type)) + { + ret = (code == REALPART_EXPR + ? arg + : omit_one_operand_loc (location, arg_type, + integer_zero_node, arg)); + } + else + { + error_at (location, "wrong type argument to %s", + code == REALPART_EXPR ? "__real" : "__imag"); + ret = error_mark_node; + } + + return ret; +} diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 2bfa97be68e6..9aca720fd71a 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -3561,26 +3561,10 @@ build_unary_op (location_t location, goto return_build_unary_op; case REALPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - ret = TREE_REALPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - ret = fold_build1_loc (location, - REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); - else - ret = arg; - if (eptype && TREE_CODE (eptype) == COMPLEX_TYPE) - eptype = TREE_TYPE (eptype); - goto return_build_unary_op; - case IMAGPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - ret = TREE_IMAGPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - ret = fold_build1_loc (location, - IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); - else - ret = omit_one_operand_loc (location, TREE_TYPE (arg), - integer_zero_node, arg); + ret = build_real_imag_expr (location, code, arg); + if (ret == error_mark_node) + return error_mark_node; if (eptype && TREE_CODE (eptype) == COMPLEX_TYPE) eptype = TREE_TYPE (eptype); goto return_build_unary_op; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8c76af67bcd3..6f9bb075f288 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2010-11-18 Nathan Froyd + + PR c/33193 + * typeck.c (cp_build_unary_op): Call build_real_imag_expr for + REALPART_EXPR and IMAGPART_EXPR. + 2010-11-16 Jason Merrill * call.c (convert_like_real): Don't make a temp for copy-list-init. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 92a7d9ed6dea..df31d875dca0 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5098,26 +5098,12 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, break; case REALPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_REALPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - { - arg = build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); - return fold_if_not_in_template (arg); - } - else - return arg; - case IMAGPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_IMAGPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - { - arg = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); - return fold_if_not_in_template (arg); - } + arg = build_real_imag_expr (input_location, code, arg); + if (arg == error_mark_node) + return arg; else - return cp_convert (TREE_TYPE (arg), integer_zero_node); + return fold_if_not_in_template (arg); case PREINCREMENT_EXPR: case POSTINCREMENT_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9eace4d767ac..a5b14f964a37 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-11-18 Nathan Froyd + + PR c/33193 + * c-c++-common/pr33193.c: New test. + 2010-11-18 Richard Guenther PR tree-optimization/46172 diff --git a/gcc/testsuite/c-c++-common/pr33193.c b/gcc/testsuite/c-c++-common/pr33193.c new file mode 100644 index 000000000000..2d1929848f88 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr33193.c @@ -0,0 +1,19 @@ +/* PR c/33193 */ +/* { dg-do compile } */ + +struct a {float x, y; }; + +float f(struct a b) +{ + /* The error messages here are different between C and C++, so just + make sure we get an error. */ + float x = __real b; /* { dg-error "" } */ + float y = __imag b; /* { dg-error "" } */ + return x / y; +} +int f1(int *b) +{ + float x = __imag b; /* { dg-error "wrong type argument" } */ + float y = __real b; /* { dg-error "wrong type argument" } */ + return x - y; +}