aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-10-07 21:37:46 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-10-07 21:37:46 +0200
commitbe845b04a8e13e91e7ecd76b60254c7d0acfda2e (patch)
tree7b14e19adcc90c0ed591c2745b010b6ffcf52ade /gcc/cp
parent082139830afb428628657a7520659a01ae00b852 (diff)
downloadgcc-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/ChangeLog17
-rw-r--r--gcc/cp/constexpr.c6
-rw-r--r--gcc/cp/cp-objcp-common.c1
-rw-r--r--gcc/cp/cp-tree.def5
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/cxx-pretty-print.c15
-rw-r--r--gcc/cp/cxx-pretty-print.h1
-rw-r--r--gcc/cp/error.c4
-rw-r--r--gcc/cp/parser.c37
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/cp/typeck.c23
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. */