From 094a5fe2659e4bf82420bfe1cdb57cc799a37644 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 27 Oct 2007 13:58:26 +0200 Subject: [PATCH] re PR c++/33842 (Broken diagnostic: 'offsetof_expr' not supported by dump_expr) PR c++/33842 * cxx-pretty-print.h (pp_cxx_offsetof_expression): New prototype. * cxx-pretty-print.c (pp_cxx_primary_expression): Handle OFFSETOF_EXPR. (pp_cxx_offsetof_expression_1, pp_cxx_offsetof_expression): New functions. * error.c (dump_expr): Handle OFFSETOF_EXPR. * g++.dg/template/error34.C: New test. From-SVN: r129677 --- gcc/cp/ChangeLog | 10 ++++++ gcc/cp/cxx-pretty-print.c | 48 +++++++++++++++++++++++++ gcc/cp/cxx-pretty-print.h | 1 + gcc/cp/error.c | 4 +++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/template/error34.C | 29 +++++++++++++++ 6 files changed, 97 insertions(+) create mode 100644 gcc/testsuite/g++.dg/template/error34.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0ef16bf5de27..c103fe99288a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2007-10-27 Jakub Jelinek + + PR c++/33842 + * cxx-pretty-print.h (pp_cxx_offsetof_expression): New prototype. + * cxx-pretty-print.c (pp_cxx_primary_expression): Handle + OFFSETOF_EXPR. + (pp_cxx_offsetof_expression_1, pp_cxx_offsetof_expression): New + functions. + * error.c (dump_expr): Handle OFFSETOF_EXPR. + 2007-10-26 Jason Merrill PR c++/24791 diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index 7ad46c666374..5cbf82cc8592 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -357,6 +357,7 @@ pp_cxx_id_expression (cxx_pretty_printer *pp, tree t) GNU Extensions: __builtin_va_arg ( assignment-expression , type-id ) + __builtin_offsetof ( type-id, offsetof-expression ) __has_nothrow_assign ( type-id ) __has_nothrow_constructor ( type-id ) @@ -421,6 +422,10 @@ pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t) pp_cxx_va_arg_expression (pp, t); break; + case OFFSETOF_EXPR: + pp_cxx_offsetof_expression (pp, t); + break; + default: pp_c_primary_expression (pp_c_base (pp), t); break; @@ -2177,6 +2182,49 @@ pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t) pp_cxx_right_paren (pp); } +static bool +pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t) +{ + switch (TREE_CODE (t)) + { + case ARROW_EXPR: + if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR + && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))) + { + pp_cxx_type_id (pp, TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)))); + pp_cxx_separate_with (pp, ','); + return true; + } + return false; + case COMPONENT_REF: + if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0))) + return false; + if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR) + pp_cxx_dot (pp); + pp_cxx_expression (pp, TREE_OPERAND (t, 1)); + return true; + case ARRAY_REF: + if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0))) + return false; + pp_left_bracket (pp); + pp_cxx_expression (pp, TREE_OPERAND (t, 1)); + pp_right_bracket (pp); + return true; + default: + return false; + } +} + +void +pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t) +{ + pp_cxx_identifier (pp, "offsetof"); + pp_cxx_left_paren (pp); + if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0))) + pp_cxx_expression (pp, TREE_OPERAND (t, 0)); + pp_cxx_right_paren (pp); +} + void pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t) { diff --git a/gcc/cp/cxx-pretty-print.h b/gcc/cp/cxx-pretty-print.h index 66943ac0246d..744ee5916bcf 100644 --- a/gcc/cp/cxx-pretty-print.h +++ b/gcc/cp/cxx-pretty-print.h @@ -72,6 +72,7 @@ void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree); void pp_cxx_trait_expression (cxx_pretty_printer *, tree); void pp_cxx_typeid_expression (cxx_pretty_printer *, tree); void pp_cxx_va_arg_expression (cxx_pretty_printer *, tree); +void pp_cxx_offsetof_expression (cxx_pretty_printer *, tree); void pp_cxx_delete_expression (cxx_pretty_printer *, tree); #endif /* GCC_CXX_PRETTY_PRINT_H */ diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 5f78a1bea6b1..5a54e8c9ada8 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2048,6 +2048,10 @@ dump_expr (tree t, int flags) pp_cxx_va_arg_expression (cxx_pp, t); break; + case OFFSETOF_EXPR: + pp_cxx_offsetof_expression (cxx_pp, t); + break; + case DELETE_EXPR: case VEC_DELETE_EXPR: pp_cxx_delete_expression (cxx_pp, t); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5549ece02821..837c35acdf9f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-10-27 Jakub Jelinek + + PR c++/33842 + * g++.dg/template/error34.C: New test. + 2007-10-27 Uros Bizjak * g++.dg/tree-ssa/ivopts-1.C: Also search for "offset: 4294967292". diff --git a/gcc/testsuite/g++.dg/template/error34.C b/gcc/testsuite/g++.dg/template/error34.C new file mode 100644 index 000000000000..d0cbcaef28e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error34.C @@ -0,0 +1,29 @@ +// PR c++/33842 +// { dg-do compile } + +template struct A +{ + A<__builtin_offsetof(T, x)>(); // { dg-error "type/value mismatch|offsetof\\(T, x\\)" } +}; + +template struct B +{ + B<__builtin_offsetof(T, x.y)>(); // { dg-error "type/value mismatch|offsetof\\(T, x.y\\)" } +}; + +template struct C +{ + C<__builtin_offsetof(T, x[6])>(); // { dg-error "type/value mismatch|offsetof\\(T, x\\\[6\\\]\\)" } +}; + +template struct D +{ + D<__builtin_offsetof(T, x.y[6].z)>(); // { dg-error "type/value mismatch|offsetof\\(T, x.y\\\[6\\\].z\\)" } +}; + +struct E { int x; }; + +template struct F +{ + F<__builtin_offsetof(E, x)>(); // { dg-error "type/value mismatch|offsetof\\(E, x\\)" } +};