diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-10-07 21:37:46 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-10-07 21:37:46 +0200 |
commit | be845b04a8e13e91e7ecd76b60254c7d0acfda2e (patch) | |
tree | 7b14e19adcc90c0ed591c2745b010b6ffcf52ade /gcc/cp | |
parent | 082139830afb428628657a7520659a01ae00b852 (diff) | |
download | gcc-be845b04a8e13e91e7ecd76b60254c7d0acfda2e.zip gcc-be845b04a8e13e91e7ecd76b60254c7d0acfda2e.tar.gz gcc-be845b04a8e13e91e7ecd76b60254c7d0acfda2e.tar.bz2 |
Implement LWG2296 helper intrinsic c-family/
Implement LWG2296 helper intrinsic
c-family/
* c-common.h (enum rid): Add RID_ADDRESSOF.
* c-common.c (c_common_reswords): Add __builtin_addressof.
cp/
* parser.c (cp_parser_postfix_expression): Handle RID_ADDRESSOF.
* cp-objcp-common.c (cp_common_init_ts): Handle ADDRESSOF_EXPR.
* constexpr.c (potential_constant_expression_1): Likewise.
* error.c (dump_expr): Likewise.
* typeck.c (cp_build_addressof): New function.
* cp-tree.h (cp_build_addressof): Declare.
* cxx-pretty-print.h (pp_cxx_addressof_expression): Declare.
* cp-tree.def (ADDRESSOF_EXPR): New tree code.
* cxx-pretty-print.c (cxx_pretty_printer::primary_expression): Handle
ADDRESSOF_EXPR. Add __builtin_addressof and
__has_unique_object_representations into syntax in function comment.
(pp_cxx_addressof_expression): New function.
* pt.c (tsubst_copy_and_build): Handle ADDRESSOF_EXPR.
testsuite/
* g++.dg/cpp0x/addressof1.C: New test.
* g++.dg/cpp0x/addressof2.C: New test.
From-SVN: r240873
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 6 | ||||
-rw-r--r-- | gcc/cp/cp-objcp-common.c | 1 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/cxx-pretty-print.c | 15 | ||||
-rw-r--r-- | gcc/cp/cxx-pretty-print.h | 1 | ||||
-rw-r--r-- | gcc/cp/error.c | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 37 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 23 |
11 files changed, 102 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 085e0a5..ce875ce 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2016-10-07 Jakub Jelinek <jakub@redhat.com> + + Implement LWG2296 helper intrinsic + * parser.c (cp_parser_postfix_expression): Handle RID_ADDRESSOF. + * cp-objcp-common.c (cp_common_init_ts): Handle ADDRESSOF_EXPR. + * constexpr.c (potential_constant_expression_1): Likewise. + * error.c (dump_expr): Likewise. + * typeck.c (cp_build_addressof): New function. + * cp-tree.h (cp_build_addressof): Declare. + * cxx-pretty-print.h (pp_cxx_addressof_expression): Declare. + * cp-tree.def (ADDRESSOF_EXPR): New tree code. + * cxx-pretty-print.c (cxx_pretty_printer::primary_expression): Handle + ADDRESSOF_EXPR. Add __builtin_addressof and + __has_unique_object_representations into syntax in function comment. + (pp_cxx_addressof_expression): New function. + * pt.c (tsubst_copy_and_build): Handle ADDRESSOF_EXPR. + 2016-10-07 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/77700 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 4acbb26..f5235fc 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -5025,6 +5025,11 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, return (RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR)); } + case ADDRESSOF_EXPR: + /* This is like ADDR_EXPR, except it won't form pointer-to-member. */ + t = TREE_OPERAND (t, 0); + goto handle_addr_expr; + case ADDR_EXPR: /* -- a unary operator & that is applied to an lvalue that designates an object with thread or automatic storage @@ -5035,6 +5040,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, /* A pointer-to-member constant. */ return true; + handle_addr_expr: #if 0 /* FIXME adjust when issue 1197 is fully resolved. For now don't do any checking here, as we might dereference the pointer later. If diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 9cb9dd7..ac1bb63 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -315,6 +315,7 @@ cp_common_init_ts (void) MARK_TS_TYPED (STMT_EXPR); MARK_TS_TYPED (OFFSET_REF); MARK_TS_TYPED (OFFSETOF_EXPR); + MARK_TS_TYPED (ADDRESSOF_EXPR); MARK_TS_TYPED (PTRMEM_CST); MARK_TS_TYPED (EMPTY_CLASS_EXPR); MARK_TS_TYPED (VEC_INIT_EXPR); diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 6cb5a69..9e44076 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -334,6 +334,11 @@ DEFTREECODE (TAG_DEFN, "tag_defn", tcc_expression, 0) /* Represents an 'offsetof' expression during template expansion. */ DEFTREECODE (OFFSETOF_EXPR, "offsetof_expr", tcc_expression, 1) +/* Represents an '__builtin_addressof' expression during template + expansion. This is similar to ADDR_EXPR, but it doesn't invoke + overloaded & operators. */ +DEFTREECODE (ADDRESSOF_EXPR, "addressof_expr", tcc_expression, 1) + /* Represents the -> operator during template expansion. */ DEFTREECODE (ARROW_EXPR, "arrow_expr", tcc_expression, 1) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9282bbe..6a08627 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6658,6 +6658,8 @@ extern tree build_x_array_ref (location_t, tree, tree, extern tree build_x_unary_op (location_t, enum tree_code, cp_expr, tsubst_flags_t); +extern tree cp_build_addressof (location_t, tree, + tsubst_flags_t); extern tree cp_build_addr_expr (tree, tsubst_flags_t); extern tree cp_build_unary_op (enum tree_code, tree, bool, tsubst_flags_t); diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index 68dcf58..5157fab 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -380,6 +380,7 @@ pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t) GNU Extensions: __builtin_va_arg ( assignment-expression , type-id ) __builtin_offsetof ( type-id, offsetof-expression ) + __builtin_addressof ( expression ) __has_nothrow_assign ( type-id ) __has_nothrow_constructor ( type-id ) @@ -387,6 +388,7 @@ pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t) __has_trivial_assign ( type-id ) __has_trivial_constructor ( type-id ) __has_trivial_copy ( type-id ) + __has_unique_object_representations ( type-id ) __has_trivial_destructor ( type-id ) __has_virtual_destructor ( type-id ) __is_abstract ( type-id ) @@ -456,6 +458,10 @@ cxx_pretty_printer::primary_expression (tree t) pp_cxx_offsetof_expression (this, t); break; + case ADDRESSOF_EXPR: + pp_cxx_addressof_expression (this, t); + break; + case REQUIRES_EXPR: pp_cxx_requires_expr (this, t); break; @@ -2437,6 +2443,15 @@ pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t) pp_cxx_right_paren (pp); } +void +pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t) +{ + pp_cxx_ws_string (pp, "__builtin_addressof"); + pp_cxx_left_paren (pp); + pp->expression (TREE_OPERAND (t, 0)); + pp_cxx_right_paren (pp); +} + static char const* get_fold_operator (tree t) { diff --git a/gcc/cp/cxx-pretty-print.h b/gcc/cp/cxx-pretty-print.h index 2f0e35a..1eb55df 100644 --- a/gcc/cp/cxx-pretty-print.h +++ b/gcc/cp/cxx-pretty-print.h @@ -90,6 +90,7 @@ void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree); void pp_cxx_trait_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_addressof_expression (cxx_pretty_printer *, tree); void pp_cxx_userdef_literal (cxx_pretty_printer *, tree); void pp_cxx_requires_clause (cxx_pretty_printer *, tree); void pp_cxx_requires_expr (cxx_pretty_printer *, tree); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 20b20b4..4cf0041 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2678,6 +2678,10 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags) pp_cxx_offsetof_expression (pp, t); break; + case ADDRESSOF_EXPR: + pp_cxx_addressof_expression (pp, t); + break; + case SCOPE_REF: dump_decl (pp, t, flags); break; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8728991..643c1e7 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6602,6 +6602,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, break; } + case RID_ADDRESSOF: case RID_BUILTIN_SHUFFLE: { vec<tree, va_gc> *vec; @@ -6618,19 +6619,29 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, FOR_EACH_VEC_ELT (*vec, i, p) mark_exp_read (p); - if (vec->length () == 2) - return build_x_vec_perm_expr (loc, (*vec)[0], NULL_TREE, (*vec)[1], - tf_warning_or_error); - else if (vec->length () == 3) - return build_x_vec_perm_expr (loc, (*vec)[0], (*vec)[1], (*vec)[2], - tf_warning_or_error); - else - { - error_at (loc, "wrong number of arguments to " - "%<__builtin_shuffle%>"); - return error_mark_node; - } - break; + switch (keyword) + { + case RID_ADDRESSOF: + if (vec->length () == 1) + return cp_build_addressof (loc, (*vec)[0], tf_warning_or_error); + error_at (loc, "wrong number of arguments to " + "%<__builtin_addressof%>"); + return error_mark_node; + + case RID_BUILTIN_SHUFFLE: + if (vec->length () == 2) + return build_x_vec_perm_expr (loc, (*vec)[0], NULL_TREE, + (*vec)[1], tf_warning_or_error); + else if (vec->length () == 3) + return build_x_vec_perm_expr (loc, (*vec)[0], (*vec)[1], + (*vec)[2], tf_warning_or_error); + error_at (loc, "wrong number of arguments to " + "%<__builtin_shuffle%>"); + return error_mark_node; + + default: + gcc_unreachable (); + } } default: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e6bacdf..f6cd3ea 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17204,6 +17204,10 @@ tsubst_copy_and_build (tree t, RETURN (finish_offsetof (RECUR (TREE_OPERAND (t, 0)), EXPR_LOCATION (t))); + case ADDRESSOF_EXPR: + RETURN (cp_build_addressof (EXPR_LOCATION (t), + RECUR (TREE_OPERAND (t, 0)), complain)); + case TRAIT_EXPR: { tree type1 = tsubst (TRAIT_EXPR_TYPE1 (t), args, diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index f1abb40..6456269 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5456,6 +5456,29 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg, return exp; } +/* Construct and perhaps optimize a tree representation + for __builtin_addressof operation. ARG specifies the operand. */ + +tree +cp_build_addressof (location_t loc, tree arg, tsubst_flags_t complain) +{ + tree orig_expr = arg; + + if (processing_template_decl) + { + if (type_dependent_expression_p (arg)) + return build_min_nt_loc (loc, ADDRESSOF_EXPR, arg, NULL_TREE); + + arg = build_non_dependent_expr (arg); + } + + tree exp = cp_build_addr_expr_strict (arg, complain); + + if (processing_template_decl && exp != error_mark_node) + exp = build_min_non_dep (ADDRESSOF_EXPR, exp, orig_expr, NULL_TREE); + return exp; +} + /* Like c_common_truthvalue_conversion, but handle pointer-to-member constants, where a null value is represented by an INTEGER_CST of -1. */ |