aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Froyd <froydnj@codesourcery.com>2010-11-18 16:24:56 +0000
committerNathan Froyd <froydnj@gcc.gnu.org>2010-11-18 16:24:56 +0000
commitfb52b50a920a7571af3de43d679fa42483c56a96 (patch)
tree45ef94c714a23d36859dc3c9c965f946052c1cbc /gcc
parentcfaa55890b6f9fb5fde5c84fc51326427dc48259 (diff)
downloadgcc-fb52b50a920a7571af3de43d679fa42483c56a96.zip
gcc-fb52b50a920a7571af3de43d679fa42483c56a96.tar.gz
gcc-fb52b50a920a7571af3de43d679fa42483c56a96.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/c-family/c-semantics.c32
-rw-r--r--gcc/c-typeck.c22
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck.c22
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/pr33193.c19
9 files changed, 82 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7aa714c..5375091 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-11-18 Nathan Froyd <froydnj@codesourcery.com>
+
+ 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 <rguenther@suse.de>
PR tree-optimization/46172
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 81e636c..86fbd13 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2010-11-18 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c/33193
+ * c-common.h (build_real_imag_expr): Declare.
+ * c-semantics.c (build_real_imag_expr): Define.
+
2010-11-17 Joseph Myers <joseph@codesourcery.com>
* 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 76842d2..3de32cf 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 0eccd51..d26d871 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 2bfa97b..9aca720 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 8c76af6..6f9bb07 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2010-11-18 Nathan Froyd <froydnj@codesourcery.com>
+
+ 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 <jason@redhat.com>
* 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 92a7d9e..df31d87 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 9eace4d..a5b14f9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-11-18 Nathan Froyd <froydnj@codesourcery.com>
+
+ PR c/33193
+ * c-c++-common/pr33193.c: New test.
+
2010-11-18 Richard Guenther <rguenther@suse.de>
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 0000000..2d19298
--- /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;
+}