===================================================================
@@ -27872,19 +27872,27 @@ cp_parser_omp_var_list_no_open (cp_parser *parser,
tree name, decl;
token = cp_lexer_peek_token (parser->lexer);
- name = cp_parser_id_expression (parser, /*template_p=*/false,
- /*check_dependency_p=*/true,
- /*template_p=*/NULL,
- /*declarator_p=*/false,
- /*optional_p=*/false);
- if (name == error_mark_node)
- goto skip_comma;
+ if (current_class_ptr && cp_parser_is_keyword (token, RID_THIS))
+ {
+ decl = current_class_ptr;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ {
+ name = cp_parser_id_expression (parser, /*template_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ if (name == error_mark_node)
+ goto skip_comma;
- decl = cp_parser_lookup_name_simple (parser, name, token->location);
- if (decl == error_mark_node)
- cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
- token->location);
- else if (kind != 0)
+ decl = cp_parser_lookup_name_simple (parser, name, token->location);
+ if (decl == error_mark_node)
+ cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
+ token->location);
+ }
+ if (decl != error_mark_node && kind != 0)
{
switch (kind)
{
@@ -27958,7 +27966,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser,
OMP_CLAUSE_CHAIN (u) = list;
list = u;
}
- else
+ else if (decl != error_mark_node)
list = tree_cons (decl, NULL_TREE, list);
get_comma:
===================================================================
@@ -6019,10 +6019,11 @@ unary_complex_lvalue (enum tree_code code, tree ar
address of it; it should not be allocated in a register.
Value is true if successful.
- C++: we do not allow `current_class_ptr' to be addressable. */
+ C++: we do not allow `current_class_ptr' to be addressable unless
+ ALLOW_THIS is true. */
bool
-cxx_mark_addressable (tree exp)
+cxx_mark_addressable (tree exp, bool allow_this)
{
tree x = exp;
@@ -6040,7 +6041,8 @@ bool
case PARM_DECL:
if (x == current_class_ptr)
{
- error ("cannot take the address of %<this%>, which is an rvalue expression");
+ if (!allow_this)
+ error ("cannot take the address of %<this%>, which is an rvalue expression");
TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later. */
return true;
}
@@ -6083,7 +6085,7 @@ bool
case TARGET_EXPR:
TREE_ADDRESSABLE (x) = 1;
- cxx_mark_addressable (TREE_OPERAND (x, 0));
+ cxx_mark_addressable (TREE_OPERAND (x, 0), allow_this);
return true;
default:
===================================================================
@@ -6168,7 +6168,7 @@ extern void cxx_print_error_function (diagnostic_
struct diagnostic_info *);
/* in typeck.c */
-extern bool cxx_mark_addressable (tree);
+extern bool cxx_mark_addressable (tree, bool = false);
extern int string_conv_p (const_tree, const_tree, int);
extern tree cp_truthvalue_conversion (tree);
extern tree condition_conversion (tree);
===================================================================
@@ -4673,7 +4673,7 @@ handle_omp_array_sections (tree c)
tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
OMP_CLAUSE_MAP);
OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_POINTER);
- if (!cxx_mark_addressable (t))
+ if (!cxx_mark_addressable (t, true))
return false;
OMP_CLAUSE_DECL (c2) = t;
t = build_fold_addr_expr (first);
@@ -5204,7 +5204,7 @@ finish_omp_reduction_clause (tree c, bool *need_de
if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[1]))
&& TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
!= REFERENCE_TYPE)
- cxx_mark_addressable (OMP_CLAUSE_DECL (c));
+ cxx_mark_addressable (OMP_CLAUSE_DECL (c), true);
tree omp_out = placeholder;
tree omp_in = convert_from_reference (OMP_CLAUSE_DECL (c));
if (need_static_cast)
@@ -5228,7 +5228,7 @@ finish_omp_reduction_clause (tree c, bool *need_de
gcc_assert (TREE_CODE (stmts[3]) == DECL_EXPR
&& TREE_CODE (stmts[4]) == DECL_EXPR);
if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[3])))
- cxx_mark_addressable (OMP_CLAUSE_DECL (c));
+ cxx_mark_addressable (OMP_CLAUSE_DECL (c), true);
if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[4])))
cxx_mark_addressable (placeholder);
tree omp_priv = convert_from_reference (OMP_CLAUSE_DECL (c));
@@ -5844,7 +5844,7 @@ finish_omp_clauses (tree clauses, bool oacc)
remove = true;
}
else if (!processing_template_decl
- && !cxx_mark_addressable (t))
+ && !cxx_mark_addressable (t, true))
remove = true;
break;
@@ -5907,7 +5907,7 @@ finish_omp_clauses (tree clauses, bool oacc)
}
else if (!processing_template_decl
&& TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
- && !cxx_mark_addressable (t))
+ && !cxx_mark_addressable (t, true))
remove = true;
else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
===================================================================
@@ -0,0 +1,43 @@
+#include <cstdlib>
+#include <iostream>
+using namespace std;
+
+class test {
+ public:
+ int a;
+
+ test ()
+ {
+ a = -1;
+#pragma acc enter data copyin (this[0:1])
+ }
+
+ ~test ()
+ {
+#pragma acc exit data delete (this[0:1])
+ }
+
+ void set (int i)
+ {
+ a = i;
+#pragma acc update device (this[0:1])
+ }
+
+ int get ()
+ {
+#pragma acc update host (this[0:1])
+ return a;
+ }
+};
+
+int
+main ()
+{
+ test t;
+
+ t.set (4);
+ if (t.get () != 4)
+ abort ();
+
+ return 0;
+}