From 66e681911005962f96d56daf1a2b80bfe89cfbd2 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 12 Nov 2008 09:18:45 +0100 Subject: [PATCH] re PR c++/35334 (Broken diagnostic for complex cast) PR c++/35334 * c-pretty-print.c (pp_c_complex_expr): New function. (pp_c_postfix_expression) : Call it. * error.c (dump_expr): Handle COMPLEX_EXPR. * gcc.dg/pr35334.c: New test. * g++.dg/other/error29.C: New test. From-SVN: r141783 --- gcc/ChangeLog | 4 +++ gcc/c-pretty-print.c | 45 +++++++++++++++++++++++++++- gcc/cp/ChangeLog | 5 ++++ gcc/cp/error.c | 1 + gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/g++.dg/other/error29.C | 21 +++++++++++++ gcc/testsuite/gcc.dg/pr35334.c | 22 ++++++++++++++ 7 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/other/error29.C create mode 100644 gcc/testsuite/gcc.dg/pr35334.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6bb36f5de6f..b8c38c1f5e6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2008-11-12 Jakub Jelinek + PR c++/35334 + * c-pretty-print.c (pp_c_complex_expr): New function. + (pp_c_postfix_expression) : Call it. + PR target/35366 * expr.c (expand_expr_addr_expr_1): If EXP needs bigger alignment than INNER and INNER is a constant, forcibly align INNER as much diff --git a/gcc/c-pretty-print.c b/gcc/c-pretty-print.c index 67a466ba749..9ee2738ca82 100644 --- a/gcc/c-pretty-print.c +++ b/gcc/c-pretty-print.c @@ -975,6 +975,46 @@ pp_c_compound_literal (c_pretty_printer *pp, tree e) } } +/* Pretty-print a COMPLEX_EXPR expression. */ + +static void +pp_c_complex_expr (c_pretty_printer *pp, tree e) +{ + /* Handle a few common special cases, otherwise fallback + to printing it as compound literal. */ + tree type = TREE_TYPE (e); + tree realexpr = TREE_OPERAND (e, 0); + tree imagexpr = TREE_OPERAND (e, 1); + + /* Cast of an COMPLEX_TYPE expression to a different COMPLEX_TYPE. */ + if (TREE_CODE (realexpr) == NOP_EXPR + && TREE_CODE (imagexpr) == NOP_EXPR + && TREE_TYPE (realexpr) == TREE_TYPE (type) + && TREE_TYPE (imagexpr) == TREE_TYPE (type) + && TREE_CODE (TREE_OPERAND (realexpr, 0)) == REALPART_EXPR + && TREE_CODE (TREE_OPERAND (imagexpr, 0)) == IMAGPART_EXPR + && TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0) + == TREE_OPERAND (TREE_OPERAND (imagexpr, 0), 0)) + { + pp_c_type_cast (pp, type); + pp_expression (pp, TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0)); + return; + } + + /* Cast of an scalar expression to COMPLEX_TYPE. */ + if ((integer_zerop (imagexpr) || real_zerop (imagexpr)) + && TREE_TYPE (realexpr) == TREE_TYPE (type)) + { + pp_c_type_cast (pp, type); + if (TREE_CODE (realexpr) == NOP_EXPR) + realexpr = TREE_OPERAND (realexpr, 0); + pp_expression (pp, realexpr); + return; + } + + pp_c_compound_literal (pp, e); +} + /* constant: integer-constant floating-constant @@ -1406,10 +1446,13 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e) case COMPLEX_CST: case VECTOR_CST: - case COMPLEX_EXPR: pp_c_compound_literal (pp, e); break; + case COMPLEX_EXPR: + pp_c_complex_expr (pp, e); + break; + case COMPOUND_LITERAL_EXPR: e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e)); /* Fall through. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 81941e262f1..8cfdf61255e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2008-11-12 Jakub Jelinek + + PR c++/35334 + * error.c (dump_expr): Handle COMPLEX_EXPR. + 2008-11-10 Jakub Jelinek PR c++/38021 diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 4064ad400e2..3aa9b595fa7 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2068,6 +2068,7 @@ dump_expr (tree t, int flags) case UNGE_EXPR: case UNEQ_EXPR: case LTGT_EXPR: + case COMPLEX_EXPR: pp_expression (cxx_pp, t); break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index df1cb8621f1..922525fea72 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-11-12 Jakub Jelinek + + PR c++/35334 + * gcc.dg/pr35334.c: New test. + * g++.dg/other/error29.C: New test. + 2008-11-12 Tobias Burnus PR fortran/38065 diff --git a/gcc/testsuite/g++.dg/other/error29.C b/gcc/testsuite/g++.dg/other/error29.C new file mode 100644 index 00000000000..a46405875e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/error29.C @@ -0,0 +1,21 @@ +// PR c++/35334 +// { dg-do compile } +// { dg-bogus "not supported by" "" { target *-*-* } 0 } + +__complex__ unsigned int i; +int j; +char k; +__complex__ double l; +double m; +float n; + +void +foo () +{ + ((__complex__ int)i)(); // { dg-error "cannot be used as a function" } + ((__complex__ int)j)(); // { dg-error "cannot be used as a function" } + ((__complex__ int)k)(); // { dg-error "cannot be used as a function" } + ((__complex__ long double)l)(); // { dg-error "cannot be used as a function" } + ((__complex__ long double)m)(); // { dg-error "cannot be used as a function" } + ((__complex__ long double)n)(); // { dg-error "cannot be used as a function" } +} diff --git a/gcc/testsuite/gcc.dg/pr35334.c b/gcc/testsuite/gcc.dg/pr35334.c new file mode 100644 index 00000000000..d4c642e3471 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr35334.c @@ -0,0 +1,22 @@ +/* PR c++/35334 */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ +/* { dg-bogus "not supported by" "" { target *-*-* } 0 } */ + +__complex__ unsigned int i; +int j; +char k; +__complex__ double l; +double m; +float n; + +void +foo () +{ + ((__complex__ int)i)(); /* { dg-error "is not a function" } */ + ((__complex__ int)j)(); /* { dg-error "is not a function" } */ + ((__complex__ int)k)(); /* { dg-error "is not a function" } */ + ((__complex__ long double)l)(); /* { dg-error "is not a function" } */ + ((__complex__ long double)m)(); /* { dg-error "is not a function" } */ + ((__complex__ long double)n)(); /* { dg-error "is not a function" } */ +} -- 2.30.2