summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-15 11:22:33 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-15 11:22:33 +0000
commitc7b90083fc30ca513362af4146f2d74593e361b9 (patch)
tree2edd507fa9d839c9250de47fd7cb5ef53820ab03 /gcc/cp
parent71630517b50379f514fc7aa3e478adf7a800e153 (diff)
downloadgcc-c7b90083fc30ca513362af4146f2d74593e361b9.tar.gz
2016-04-15 Basile Starynkevitch <basile@starynkevitch.net>
{{merging with even more of GCC 6, using subversion 1.9 svn merge -r229783:229820 ^/trunk }} git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@235016 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog116
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/decl2.c5
-rw-r--r--gcc/cp/parser.c328
-rw-r--r--gcc/cp/pt.c76
-rw-r--r--gcc/cp/semantics.c344
-rw-r--r--gcc/cp/typeck2.c8
7 files changed, 661 insertions, 220 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 86c3653aff6..57de3e6b639 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,119 @@
+2015-11-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/67846
+ * parser.c (cp_parser_lambda_body): Check lambda_return_type
+ return value.
+ * typeck2.c (cxx_incomplete_type_diagnostic): Print member or
+ member function used invalidly.
+
+2015-11-05 Jakub Jelinek <jakub@redhat.com>
+ Ilya Verbin <ilya.verbin@intel.com>
+
+ * cp-tree.h (finish_omp_for): Add ORIG_INITS argument.
+ (omp_privatize_field): Add SHARED argument.
+ * parser.c: Include context.h.
+ (cp_parser_omp_clause_schedule): Parse schedule
+ modifiers, diagnose monotonic together with nonmonotonic.
+ (cp_parser_omp_clause_linear): Add DECLARE_SIMD argument. Parse
+ parameter name as linear step as id-expression rather than expression.
+ (cp_parser_omp_all_clauses): Adjust caller.
+ (cp_parser_omp_for_loop_init): Add ORIG_INIT argument,
+ initialize it. Adjust omp_privatize_field caller.
+ (cp_parser_omp_for_loop): Compute orig_inits, pass it's address
+ to finish_omp_for.
+ (OMP_DISTRIBUTE_CLAUSE_MASK): Add lastprivate clause.
+ (cp_parser_omp_target_data,
+ cp_parser_omp_target_enter_data,
+ cp_parser_omp_target_exit_data): Allow GOMP_MAP_ALWAYS_POINTER
+ and GOMP_MAP_FIRSTPRIVATE_REFERENCE.
+ (cp_parser_omp_target): Likewise. Evaluate num_teams and
+ thread_limit expressions on combined target teams before the target.
+ (cp_parser_omp_declare_target): If decl has "omp declare target" or
+ "omp declare target link" attribute, and cgraph or varpool node already
+ exists, then set corresponding flags. Call finish_omp_clauses
+ in the parenthesized extended-list syntax case. Call
+ cp_parser_require_pragma_eol instead of cp_parser_skip_to_pragma_eol.
+ (cp_parser_omp_end_declare_target): Call cp_parser_require_pragma_eol
+ instead of cp_parser_skip_to_pragma_eol.
+ * decl2.c (cplus_decl_attributes): Don't diagnose block scope vars
+ inside declare target.
+ * pt.c (tsubst_omp_clauses): If OMP_CLAUSE_LINEAR_VARIABLE_STRIDE,
+ use tsubst_omp_clause_decl instead of tsubst_expr on
+ OMP_CLAUSE_LINEAR_STEP. Handle non-static data members in shared
+ clauses.
+ (tsubst_omp_for_iterator): Adjust omp_privatize_field caller.
+ (tsubst_find_omp_teams): New function.
+ (tsubst_expr): Evaluate num_teams and thread_limit expressions on
+ combined target teams before the target. Use OMP_FOR_ORIG_DECLS for
+ all OpenMP/OpenACC/Cilk+ looping constructs. Adjust finish_omp_for
+ caller.
+ * semantics.c (omp_privatize_field): Add SHARED argument, if true,
+ always create artificial var and never put it into the hash table
+ or vector.
+ (handle_omp_array_sections_1): Adjust omp_privatize_field caller.
+ Allow non-zero low-bound on OMP_CLAUSE_REDUCTION array sections.
+ (handle_omp_array_sections): For structure element
+ based array sections use GOMP_MAP_ALWAYS_POINTER instead of
+ GOMP_MAP_FIRSTPRIVATE_POINTER. Encode low-bound into the MEM_REF,
+ either into the constant offset, or for variable low-bound using
+ POINTER_PLUS_EXPR.
+ (finish_omp_clauses): Adjust omp_privatize_field caller. Drop
+ generic_field_head, structure elements are now always mapped even
+ as array section bases, diagnose same var in data sharing and
+ mapping clauses. For references map what they refer to using
+ GOMP_MAP_ALWAYS_POINTER for structure elements and
+ GOMP_MAP_FIRSTPRIVATE_REFERENCE otherwise. Diagnose if linear step
+ on declare simd is neither a constant nor a uniform parameter.
+ Allow non-static data members on shared clauses. Look through
+ POINTER_PLUS_EXPR for array section reductions. Diagnose nonmonotonic
+ modifier on kinds other than dynamic or guided or nonmonotonic
+ modifier together with ordered clause. Diagnose the same var or
+ function appearing multiple times on the same directive. Fix up
+ wording for the to clause if t is neither a FUNCTION_DECL nor a
+ VAR_DECL, use special wording for OVERLOADs and TEMPLATE_ID_EXPR.
+ (handle_omp_for_class_iterator): Add ORIG_DECLS argument. Call
+ c_omp_check_loop_iv_exprs on cond.
+ (finish_omp_for): Add ORIG_INITS argument. Call
+ c_omp_check_loop_iv_exprs on ORIG_INITS elements. Adjust
+ handle_omp_for_class_iterator caller. Call c_omp_check_loop_iv.
+ Call add_stmt.
+ (finish_omp_atomic): Adjust c_finish_omp_atomic caller.
+
+2015-11-04 Cesar Philippidis <cesar@codesourcery.com>
+
+ * (cp_parser_oacc_single_int_clause): New function.
+ (cp_parser_oacc_clause_vector_length): Delete.
+ (cp_parser_omp_clause_num_gangs): Delete.
+ (cp_parser_omp_clause_num_workers): Delete.
+ (cp_parser_oacc_all_clauses): Use cp_parser_oacc_single_int_clause
+ for num_gangs, num_workers and vector_length.
+
+2015-11-04 Mikhail Maltsev <maltsevm@gmail.com>
+
+ * call.c (validate_conversion_obstack): Define unconditionally.
+ * constexpr.c (maybe_constant_value, fold_non_dependent_expr): Use
+ gcc_checking_assert.
+ * cp-tree.h: Use CHECKING_P instead of ENABLE_CHECKING.
+ * decl2.c (cxx_post_compilation_parsing_cleanups): Use flag_checking.
+ * mangle.c (add_substitution): Likewise.
+ * method.c (maybe_explain_implicit_delete): Likewise.
+ * parser.c (cp_parser_template_argument_list): Remove conditional
+ compilation.
+ * pt.c (check_unstripped_args): Rename to...
+ (verify_unstripped_args): ... this and remove conditional compilation.
+ (retrieve_specialization): Guard call of verify_unstripped_args with
+ flag_checking.
+ (template_parm_to_arg): Remove conditional compilation.
+ (template_parms_to_args, coerce_template_parameter_pack,
+ coerce_template_parms): Likewise.
+ (tsubst_copy): Use flag_checking.
+ (type_unification_real): Remove conditional compilation.
+ (build_non_dependent_expr): Use flag_checking.
+ * tree.c (build_target_expr): Remove conditional compilation, use
+ gcc_checking_assert.
+ * typeck.c (comptypes): Likewise.
+ * typeck2.c (digest_init_r): Likewise.
+
2015-11-03 Jason Merrill <jason@redhat.com>
* pt.c (struct find_parameter_pack_data): Add
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 17111884e2b..c578262677d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6327,7 +6327,7 @@ extern tree begin_omp_task (void);
extern tree finish_omp_task (tree, tree);
extern tree finish_omp_for (location_t, enum tree_code,
tree, tree, tree, tree, tree,
- tree, tree, tree);
+ tree, tree, vec<tree> *, tree);
extern void finish_omp_atomic (enum tree_code, enum tree_code,
tree, tree, tree, tree, tree,
bool);
@@ -6337,7 +6337,7 @@ extern void finish_omp_taskwait (void);
extern void finish_omp_taskyield (void);
extern void finish_omp_cancel (tree);
extern void finish_omp_cancellation_point (tree);
-extern tree omp_privatize_field (tree);
+extern tree omp_privatize_field (tree, bool);
extern tree begin_transaction_stmt (location_t, tree *, int);
extern void finish_transaction_stmt (tree, tree, int, tree);
extern tree build_transaction_expr (location_t, tree, int, tree);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 01d46070a80..846eca213bf 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1448,11 +1448,6 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
&& DECL_CLASS_SCOPE_P (*decl))
error ("%q+D static data member inside of declare target directive",
*decl);
- else if (VAR_P (*decl)
- && (DECL_FUNCTION_SCOPE_P (*decl)
- || (current_function_decl && !DECL_EXTERNAL (*decl))))
- error ("%q+D in block scope inside of declare target directive",
- *decl);
else if (!processing_template_decl
&& VAR_P (*decl)
&& !cp_omp_mappable_type (TREE_TYPE (*decl)))
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 313a8453c54..6eb68ebc42f 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "omp-low.h"
#include "gomp-constants.h"
#include "c-family/c-indentation.h"
+#include "context.h"
/* The lexer. */
@@ -9886,7 +9887,12 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
if (cp_parser_parse_definitely (parser))
{
if (!processing_template_decl)
- apply_deduced_return_type (fco, lambda_return_type (expr));
+ {
+ tree type = lambda_return_type (expr);
+ apply_deduced_return_type (fco, type);
+ if (type == error_mark_node)
+ expr = error_mark_node;
+ }
/* Will get error here if type not deduced yet. */
finish_return_stmt (expr);
@@ -29591,6 +29597,39 @@ cp_parser_oacc_simple_clause (cp_parser * /* parser */,
return c;
}
+ /* OpenACC:
+ num_gangs ( expression )
+ num_workers ( expression )
+ vector_length ( expression ) */
+
+static tree
+cp_parser_oacc_single_int_clause (cp_parser *parser, omp_clause_code code,
+ const char *str, tree list)
+{
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ tree t = cp_parser_assignment_expression (parser, NULL, false, false);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ {
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+ }
+
+ check_no_duplicate_clause (list, code, str, loc);
+
+ tree c = build_omp_clause (loc, code);
+ OMP_CLAUSE_OPERAND (c, 0) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
/* OpenACC:
gang [( gang-arg-list )]
@@ -29714,45 +29753,6 @@ cp_parser_oacc_shape_clause (cp_parser *parser, omp_clause_code kind,
return list;
}
-/* OpenACC:
- vector_length ( expression ) */
-
-static tree
-cp_parser_oacc_clause_vector_length (cp_parser *parser, tree list)
-{
- tree t, c;
- location_t location = cp_lexer_peek_token (parser->lexer)->location;
- bool error = false;
-
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
- return list;
-
- t = cp_parser_condition (parser);
- if (t == error_mark_node || !INTEGRAL_TYPE_P (TREE_TYPE (t)))
- {
- error_at (location, "expected positive integer expression");
- error = true;
- }
-
- if (error || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
- {
- cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
- /*or_comma=*/false,
- /*consume_paren=*/true);
- return list;
- }
-
- check_no_duplicate_clause (list, OMP_CLAUSE_VECTOR_LENGTH, "vector_length",
- location);
-
- c = build_omp_clause (location, OMP_CLAUSE_VECTOR_LENGTH);
- OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = t;
- OMP_CLAUSE_CHAIN (c) = list;
- list = c;
-
- return list;
-}
-
/* OpenACC 2.0
Parse wait clause or directive parameters. */
@@ -30131,42 +30131,6 @@ cp_parser_omp_clause_nowait (cp_parser * /*parser*/,
return c;
}
-/* OpenACC:
- num_gangs ( expression ) */
-
-static tree
-cp_parser_omp_clause_num_gangs (cp_parser *parser, tree list)
-{
- tree t, c;
- location_t location = cp_lexer_peek_token (parser->lexer)->location;
-
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
- return list;
-
- t = cp_parser_condition (parser);
-
- if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
- cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
- /*or_comma=*/false,
- /*consume_paren=*/true);
-
- if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
- {
- error_at (location, "expected positive integer expression");
- return list;
- }
-
- check_no_duplicate_clause (list, OMP_CLAUSE_NUM_GANGS, "num_gangs", location);
-
- c = build_omp_clause (location, OMP_CLAUSE_NUM_GANGS);
- OMP_CLAUSE_NUM_GANGS_EXPR (c) = t;
- OMP_CLAUSE_CHAIN (c) = list;
- list = c;
-
- return list;
-}
-
/* OpenMP 2.5:
num_threads ( expression ) */
@@ -30375,43 +30339,6 @@ cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list,
return list;
}
-/* OpenACC:
- num_workers ( expression ) */
-
-static tree
-cp_parser_omp_clause_num_workers (cp_parser *parser, tree list)
-{
- tree t, c;
- location_t location = cp_lexer_peek_token (parser->lexer)->location;
-
- if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
- return list;
-
- t = cp_parser_condition (parser);
-
- if (t == error_mark_node
- || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
- cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
- /*or_comma=*/false,
- /*consume_paren=*/true);
-
- if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
- {
- error_at (location, "expected positive integer expression");
- return list;
- }
-
- check_no_duplicate_clause (list, OMP_CLAUSE_NUM_WORKERS, "num_gangs",
- location);
-
- c = build_omp_clause (location, OMP_CLAUSE_NUM_WORKERS);
- OMP_CLAUSE_NUM_WORKERS_EXPR (c) = t;
- OMP_CLAUSE_CHAIN (c) = list;
- list = c;
-
- return list;
-}
-
/* OpenMP 2.5:
ordered
@@ -30578,31 +30505,44 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
OpenMP 4.5:
schedule ( schedule-modifier : schedule-kind )
- schedule ( schedule-modifier : schedule-kind , expression )
+ schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
schedule-modifier:
- simd */
+ simd
+ monotonic
+ nonmonotonic */
static tree
cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location)
{
tree c, t;
+ int modifiers = 0, nmodifiers = 0;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return list;
c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE);
- if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
- if (strcmp ("simd", p) == 0
- && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
+ if (strcmp ("simd", p) == 0)
+ OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
+ else if (strcmp ("monotonic", p) == 0)
+ modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
+ else if (strcmp ("nonmonotonic", p) == 0)
+ modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
+ else
+ break;
+ cp_lexer_consume_token (parser->lexer);
+ if (nmodifiers++ == 0
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else
{
- OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
- cp_lexer_consume_token (parser->lexer);
- cp_lexer_consume_token (parser->lexer);
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+ break;
}
}
@@ -30643,6 +30583,16 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
goto invalid_kind;
cp_lexer_consume_token (parser->lexer);
+ if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
+ | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
+ == (OMP_CLAUSE_SCHEDULE_MONOTONIC
+ | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
+ {
+ error_at (location, "both %<monotonic%> and %<nonmonotonic%> modifiers "
+ "specified");
+ modifiers = 0;
+ }
+
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
{
cp_token *token;
@@ -30668,6 +30618,10 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
goto resync_fail;
+ OMP_CLAUSE_SCHEDULE_KIND (c)
+ = (enum omp_clause_schedule_kind)
+ (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
+
check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location);
OMP_CLAUSE_CHAIN (c) = list;
return c;
@@ -30860,7 +30814,7 @@ cp_parser_omp_clause_aligned (cp_parser *parser, tree list)
static tree
cp_parser_omp_clause_linear (cp_parser *parser, tree list,
- bool is_cilk_simd_fn)
+ bool is_cilk_simd_fn, bool declare_simd)
{
tree nlist, c, step = integer_one_node;
bool colon;
@@ -30904,7 +30858,30 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
if (colon)
{
- step = cp_parser_expression (parser);
+ step = NULL_TREE;
+ if (declare_simd
+ && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN))
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ cp_parser_parse_tentatively (parser);
+ step = cp_parser_id_expression (parser, /*template_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ if (step != error_mark_node)
+ step = cp_parser_lookup_name_simple (parser, step, token->location);
+ if (step == error_mark_node)
+ {
+ step = NULL_TREE;
+ cp_parser_abort_tentative_parse (parser);
+ }
+ else if (!cp_parser_parse_definitely (parser))
+ step = NULL_TREE;
+ }
+ if (!step)
+ step = cp_parser_expression (parser);
if (is_cilk_simd_fn && TREE_CODE (step) == PARM_DECL)
{
@@ -31423,6 +31400,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
{
location_t here;
pragma_omp_clause c_kind;
+ omp_clause_code code;
const char *c_name;
tree prev = clauses;
@@ -31489,12 +31467,16 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
c_name = "if";
break;
case PRAGMA_OACC_CLAUSE_NUM_GANGS:
- clauses = cp_parser_omp_clause_num_gangs (parser, clauses);
+ code = OMP_CLAUSE_NUM_GANGS;
c_name = "num_gangs";
+ clauses = cp_parser_oacc_single_int_clause (parser, code, c_name,
+ clauses);
break;
case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
- clauses = cp_parser_omp_clause_num_workers (parser, clauses);
c_name = "num_workers";
+ code = OMP_CLAUSE_NUM_WORKERS;
+ clauses = cp_parser_oacc_single_int_clause (parser, code, c_name,
+ clauses);
break;
case PRAGMA_OACC_CLAUSE_PRESENT:
clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
@@ -31535,8 +31517,10 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
c_name, clauses);
break;
case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
- clauses = cp_parser_oacc_clause_vector_length (parser, clauses);
c_name = "vector_length";
+ code = OMP_CLAUSE_VECTOR_LENGTH;
+ clauses = cp_parser_oacc_single_int_clause (parser, code, c_name,
+ clauses);
break;
case PRAGMA_OACC_CLAUSE_WAIT:
clauses = cp_parser_oacc_clause_wait (parser, clauses);
@@ -31584,7 +31568,6 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
tree clauses = NULL;
bool first = true;
cp_token *token = NULL;
- bool cilk_simd_fn = false;
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
@@ -31798,9 +31781,15 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
c_name = "aligned";
break;
case PRAGMA_OMP_CLAUSE_LINEAR:
- if (((mask >> PRAGMA_CILK_CLAUSE_VECTORLENGTH) & 1) != 0)
- cilk_simd_fn = true;
- clauses = cp_parser_omp_clause_linear (parser, clauses, cilk_simd_fn);
+ {
+ bool cilk_simd_fn = false, declare_simd = false;
+ if (((mask >> PRAGMA_CILK_CLAUSE_VECTORLENGTH) & 1) != 0)
+ cilk_simd_fn = true;
+ else if (((mask >> PRAGMA_OMP_CLAUSE_UNIFORM) & 1) != 0)
+ declare_simd = true;
+ clauses = cp_parser_omp_clause_linear (parser, clauses,
+ cilk_simd_fn, declare_simd);
+ }
c_name = "linear";
break;
case PRAGMA_OMP_CLAUSE_DEPEND:
@@ -32583,6 +32572,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
tree &this_pre_body,
vec<tree, va_gc> *for_block,
tree &init,
+ tree &orig_init,
tree &decl,
tree &real_decl)
{
@@ -32680,6 +32670,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
cp_finish_decl (decl, init, !is_non_constant_init,
asm_specification,
LOOKUP_ONLYCONVERTING);
+ orig_init = init;
if (CLASS_TYPE_P (TREE_TYPE (decl)))
{
vec_safe_push (for_block, this_pre_body);
@@ -32740,7 +32731,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
decl = cp_parser_lookup_name_simple (parser, name,
token->location);
if (TREE_CODE (decl) == FIELD_DECL)
- add_private_clause = omp_privatize_field (decl);
+ add_private_clause = omp_privatize_field (decl, false);
}
cp_parser_abort_tentative_parse (parser);
cp_parser_parse_tentatively (parser);
@@ -32757,6 +32748,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
cp_parser_parse_definitely (parser);
cp_parser_require (parser, CPP_EQ, RT_EQ);
rhs = cp_parser_assignment_expression (parser);
+ orig_init = rhs;
finish_expr_stmt (build_x_modify_expr (EXPR_LOCATION (rhs),
decl, NOP_EXPR,
rhs,
@@ -32786,13 +32778,14 @@ static tree
cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
tree *cclauses)
{
- tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret;
+ tree init, orig_init, cond, incr, body, decl, pre_body = NULL_TREE, ret;
tree real_decl, initv, condv, incrv, declv;
tree this_pre_body, cl, ordered_cl = NULL_TREE;
location_t loc_first;
bool collapse_err = false;
int i, collapse = 1, ordered = 0, count, nbraces = 0;
vec<tree, va_gc> *for_block = make_tree_vector ();
+ auto_vec<tree, 4> orig_inits;
for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
@@ -32859,13 +32852,13 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return NULL;
- init = decl = real_decl = NULL;
+ init = orig_init = decl = real_decl = NULL;
this_pre_body = push_stmt_list ();
add_private_clause
= cp_parser_omp_for_loop_init (parser, code,
this_pre_body, for_block,
- init, decl, real_decl);
+ init, orig_init, decl, real_decl);
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
if (this_pre_body)
@@ -32997,6 +32990,11 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
TREE_VEC_ELT (initv, i) = init;
TREE_VEC_ELT (condv, i) = cond;
TREE_VEC_ELT (incrv, i) = incr;
+ if (orig_init)
+ {
+ orig_inits.safe_grow_cleared (i + 1);
+ orig_inits[i] = orig_init;
+ }
if (i == count - 1)
break;
@@ -33054,7 +33052,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
ret = NULL_TREE;
else
ret = finish_omp_for (loc_first, code, declv, NULL, initv, condv, incrv,
- body, pre_body, clauses);
+ body, pre_body, &orig_inits, clauses);
while (nbraces)
{
@@ -33699,6 +33697,7 @@ cp_parser_omp_cancellation_point (cp_parser *parser, cp_token *pragma_tok)
#define OMP_DISTRIBUTE_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
@@ -33894,6 +33893,8 @@ cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok)
map_seen = 3;
break;
case GOMP_MAP_FIRSTPRIVATE_POINTER:
+ case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
+ case GOMP_MAP_ALWAYS_POINTER:
break;
default:
map_seen |= 1;
@@ -33985,6 +33986,8 @@ cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok,
map_seen = 3;
break;
case GOMP_MAP_FIRSTPRIVATE_POINTER:
+ case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
+ case GOMP_MAP_ALWAYS_POINTER:
break;
default:
map_seen |= 1;
@@ -34072,6 +34075,8 @@ cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok,
map_seen = 3;
break;
case GOMP_MAP_FIRSTPRIVATE_POINTER:
+ case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
+ case GOMP_MAP_ALWAYS_POINTER:
break;
default:
map_seen |= 1;
@@ -34242,6 +34247,33 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
tree body = finish_omp_structured_block (sb);
if (ret == NULL_TREE)
return false;
+ if (ccode == OMP_TEAMS && !processing_template_decl)
+ {
+ /* For combined target teams, ensure the num_teams and
+ thread_limit clause expressions are evaluated on the host,
+ before entering the target construct. */
+ tree c;
+ for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+ c; c = OMP_CLAUSE_CHAIN (c))
+ if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
+ && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
+ {
+ tree expr = OMP_CLAUSE_OPERAND (c, 0);
+ expr = force_target_expr (TREE_TYPE (expr), expr, tf_none);
+ if (expr == error_mark_node)
+ continue;
+ tree tmp = TARGET_EXPR_SLOT (expr);
+ add_stmt (expr);
+ OMP_CLAUSE_OPERAND (c, 0) = expr;
+ tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+ OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (tc) = tmp;
+ OMP_CLAUSE_CHAIN (tc)
+ = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
+ cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
+ }
+ }
tree stmt = make_node (OMP_TARGET);
TREE_TYPE (stmt) = void_type_node;
OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
@@ -34308,6 +34340,8 @@ check_clauses:
case GOMP_MAP_ALWAYS_TOFROM:
case GOMP_MAP_ALLOC:
case GOMP_MAP_FIRSTPRIVATE_POINTER:
+ case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
+ case GOMP_MAP_ALWAYS_POINTER:
break;
default:
error_at (OMP_CLAUSE_LOCATION (*pc),
@@ -34839,11 +34873,12 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
{
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO_DECLARE,
clauses);
- cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ clauses = finish_omp_clauses (clauses, true);
+ cp_parser_require_pragma_eol (parser, pragma_tok);
}
else
{
- cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ cp_parser_require_pragma_eol (parser, pragma_tok);
scope_chain->omp_declare_target_attribute++;
return;
}
@@ -34873,7 +34908,22 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
continue;
}
if (!at1)
- DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ {
+ symtab_node *node = symtab_node::get (t);
+ DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ if (node != NULL)
+ {
+ node->offloadable = 1;
+#ifdef ENABLE_OFFLOADING
+ g->have_offload = true;
+ if (is_a <varpool_node *> (node))
+ {
+ vec_safe_push (offload_vars, t);
+ node->force_output = 1;
+ }
+#endif
+ }
+ }
}
}
@@ -34910,7 +34960,7 @@ cp_parser_omp_end_declare_target (cp_parser *parser, cp_token *pragma_tok)
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return;
}
- cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ cp_parser_require_pragma_eol (parser, pragma_tok);
if (!scope_chain->omp_declare_target_attribute)
error_at (pragma_tok->location,
"%<#pragma omp end declare target%> without corresponding "
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bc1ba2f38d8..554e081762e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14425,7 +14425,6 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
= tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
in_decl);
break;
- case OMP_CLAUSE_LINEAR:
case OMP_CLAUSE_ALIGNED:
OMP_CLAUSE_DECL (nc)
= tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
@@ -14433,12 +14432,25 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
OMP_CLAUSE_OPERAND (nc, 1)
= tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain,
in_decl, /*integral_constant_expression_p=*/false);
- if (OMP_CLAUSE_CODE (oc) == OMP_CLAUSE_LINEAR
- && OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE)
+ break;
+ case OMP_CLAUSE_LINEAR:
+ OMP_CLAUSE_DECL (nc)
+ = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
+ in_decl);
+ if (OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE)
{
gcc_assert (!linear_no_step);
linear_no_step = nc;
}
+ else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (oc))
+ OMP_CLAUSE_LINEAR_STEP (nc)
+ = tsubst_omp_clause_decl (OMP_CLAUSE_LINEAR_STEP (oc), args,
+ complain, in_decl);
+ else
+ OMP_CLAUSE_LINEAR_STEP (nc)
+ = tsubst_expr (OMP_CLAUSE_LINEAR_STEP (oc), args, complain,
+ in_decl,
+ /*integral_constant_expression_p=*/false);
break;
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_DEFAULT:
@@ -14462,6 +14474,7 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
if (allow_fields)
switch (OMP_CLAUSE_CODE (nc))
{
+ case OMP_CLAUSE_SHARED:
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_LASTPRIVATE:
@@ -14641,7 +14654,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
&& DECL_NAME (v) == this_identifier)
{
decl = TREE_OPERAND (decl, 1);
- decl = omp_privatize_field (decl);
+ decl = omp_privatize_field (decl, false);
}
/* FALLTHRU */
default:
@@ -14822,6 +14835,27 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
#undef RECUR
}
+/* Helper function of tsubst_expr, find OMP_TEAMS inside
+ of OMP_TARGET's body. */
+
+static tree
+tsubst_find_omp_teams (tree *tp, int *walk_subtrees, void *)
+{
+ *walk_subtrees = 0;
+ switch (TREE_CODE (*tp))
+ {
+ case OMP_TEAMS:
+ return *tp;
+ case BIND_EXPR:
+ case STATEMENT_LIST:
+ *walk_subtrees = 1;
+ break;
+ default:
+ break;
+ }
+ return NULL_TREE;
+}
+
/* Like tsubst_copy for expressions, etc. but also does semantic
processing. */
@@ -15246,7 +15280,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
if (OMP_FOR_INIT (t) != NULL_TREE)
{
declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
- if (TREE_CODE (t) == OMP_FOR && OMP_FOR_ORIG_DECLS (t))
+ if (OMP_FOR_ORIG_DECLS (t))
orig_declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
initv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
condv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
@@ -15273,7 +15307,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
if (OMP_FOR_INIT (t) != NULL_TREE)
t = finish_omp_for (EXPR_LOCATION (t), TREE_CODE (t), declv,
orig_declv, initv, condv, incrv, body, pre_body,
- clauses);
+ NULL, clauses);
else
{
t = make_node (TREE_CODE (t));
@@ -15324,6 +15358,36 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
t = copy_node (t);
OMP_BODY (t) = stmt;
OMP_CLAUSES (t) = tmp;
+ if (TREE_CODE (t) == OMP_TARGET && OMP_TARGET_COMBINED (t))
+ {
+ tree teams = cp_walk_tree (&stmt, tsubst_find_omp_teams, NULL, NULL);
+ if (teams)
+ {
+ /* For combined target teams, ensure the num_teams and
+ thread_limit clause expressions are evaluated on the host,
+ before entering the target construct. */
+ tree c;
+ for (c = OMP_TEAMS_CLAUSES (teams);
+ c; c = OMP_CLAUSE_CHAIN (c))
+ if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
+ && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
+ {
+ tree expr = OMP_CLAUSE_OPERAND (c, 0);
+ expr = force_target_expr (TREE_TYPE (expr), expr, tf_none);
+ if (expr == error_mark_node)
+ continue;
+ tmp = TARGET_EXPR_SLOT (expr);
+ add_stmt (expr);
+ OMP_CLAUSE_OPERAND (c, 0) = expr;
+ tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+ OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (tc) = tmp;
+ OMP_CLAUSE_CHAIN (tc) = OMP_TARGET_CLAUSES (t);
+ OMP_TARGET_CLAUSES (t) = tc;
+ }
+ }
+ }
add_stmt (t);
break;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index b9f8545a7bc..d9f4fc525ca 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4323,19 +4323,20 @@ omp_note_field_privatization (tree f, tree t)
dummy VAR_DECL. */
tree
-omp_privatize_field (tree t)
+omp_privatize_field (tree t, bool shared)
{
tree m = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
if (m == error_mark_node)
return error_mark_node;
- if (!omp_private_member_map)
+ if (!omp_private_member_map && !shared)
omp_private_member_map = new hash_map<tree, tree>;
if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
{
gcc_assert (TREE_CODE (m) == INDIRECT_REF);
m = TREE_OPERAND (m, 0);
}
- tree &v = omp_private_member_map->get_or_insert (t);
+ tree vb = NULL_TREE;
+ tree &v = shared ? vb : omp_private_member_map->get_or_insert (t);
if (v == NULL_TREE)
{
v = create_temporary_var (TREE_TYPE (m));
@@ -4344,7 +4345,8 @@ omp_privatize_field (tree t)
DECL_OMP_PRIVATIZED_MEMBER (v) = 1;
SET_DECL_VALUE_EXPR (v, m);
DECL_HAS_VALUE_EXPR_P (v) = 1;
- omp_private_member_vec.safe_push (t);
+ if (!shared)
+ omp_private_member_vec.safe_push (t);
}
return v;
}
@@ -4447,7 +4449,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
&& TREE_CODE (TREE_CHAIN (t)) == FIELD_DECL)
- TREE_CHAIN (t) = omp_privatize_field (TREE_CHAIN (t));
+ TREE_CHAIN (t) = omp_privatize_field (TREE_CHAIN (t), false);
ret = handle_omp_array_sections_1 (c, TREE_CHAIN (t), types,
maybe_zero_len, first_non_one, is_omp);
if (ret == error_mark_node || ret == NULL_TREE)
@@ -4516,13 +4518,6 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
&& (TREE_CODE (length) != INTEGER_CST || integer_onep (length)))
first_non_one++;
}
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
- && !integer_zerop (low_bound))
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "%<reduction%> array section has to be zero-based");
- return error_mark_node;
- }
if (TREE_CODE (type) == ARRAY_TYPE)
{
if (length == NULL_TREE
@@ -4863,7 +4858,24 @@ handle_omp_array_sections (tree c, bool is_omp)
t = convert_from_reference (t);
else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
t = build_fold_addr_expr (t);
- t = build2 (MEM_REF, type, t, build_int_cst (ptype, 0));
+ tree t2 = build_fold_addr_expr (first);
+ t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
+ ptrdiff_type_node, t2);
+ t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
+ ptrdiff_type_node, t2,
+ fold_convert_loc (OMP_CLAUSE_LOCATION (c),
+ ptrdiff_type_node, t));
+ if (tree_fits_shwi_p (t2))
+ t = build2 (MEM_REF, type, t,
+ build_int_cst (ptype, tree_to_shwi (t2)));
+ else
+ {
+ t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
+ sizetype, t2);
+ t = build2_loc (OMP_CLAUSE_LOCATION (c), POINTER_PLUS_EXPR,
+ TREE_TYPE (t), t, t2);
+ t = build2 (MEM_REF, type, t, build_int_cst (ptype, 0));
+ }
OMP_CLAUSE_DECL (c) = t;
return false;
}
@@ -4892,9 +4904,20 @@ handle_omp_array_sections (tree c, bool is_omp)
}
tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
OMP_CLAUSE_MAP);
- OMP_CLAUSE_SET_MAP_KIND (c2, is_omp ? GOMP_MAP_FIRSTPRIVATE_POINTER
- : GOMP_MAP_POINTER);
- if (!is_omp && !cxx_mark_addressable (t))
+ if (!is_omp)
+ OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_POINTER);
+ else if (TREE_CODE (t) == COMPONENT_REF)
+ OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER);
+ else if (REFERENCE_REF_P (t)
+ && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF)
+ {
+ t = TREE_OPERAND (t, 0);
+ OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER);
+ }
+ else
+ OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER);
+ if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER
+ && !cxx_mark_addressable (t))
return false;
OMP_CLAUSE_DECL (c2) = t;
t = build_fold_addr_expr (first);
@@ -4912,15 +4935,18 @@ handle_omp_array_sections (tree c, bool is_omp)
OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
OMP_CLAUSE_CHAIN (c) = c2;
ptr = OMP_CLAUSE_DECL (c2);
- if (!is_omp
+ if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER
&& TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
&& POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
{
tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
OMP_CLAUSE_MAP);
- OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER);
+ OMP_CLAUSE_SET_MAP_KIND (c3, OMP_CLAUSE_MAP_KIND (c2));
OMP_CLAUSE_DECL (c3) = ptr;
- OMP_CLAUSE_DECL (c2) = convert_from_reference (ptr);
+ if (OMP_CLAUSE_MAP_KIND (c2) == GOMP_MAP_ALWAYS_POINTER)
+ OMP_CLAUSE_DECL (c2) = build_simple_mem_ref (ptr);
+ else
+ OMP_CLAUSE_DECL (c2) = convert_from_reference (ptr);
OMP_CLAUSE_SIZE (c3) = size_zero_node;
OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (c2);
OMP_CLAUSE_CHAIN (c2) = c3;
@@ -5645,11 +5671,12 @@ tree
finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
{
bitmap_head generic_head, firstprivate_head, lastprivate_head;
- bitmap_head aligned_head, map_head, map_field_head, generic_field_head;
+ bitmap_head aligned_head, map_head, map_field_head;
tree c, t, *pc;
tree safelen = NULL_TREE;
bool branch_seen = false;
bool copyprivate_seen = false;
+ bool ordered_seen = false;
bitmap_obstack_initialize (NULL);
bitmap_initialize (&generic_head, &bitmap_default_obstack);
@@ -5658,7 +5685,6 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
bitmap_initialize (&aligned_head, &bitmap_default_obstack);
bitmap_initialize (&map_head, &bitmap_default_obstack);
bitmap_initialize (&map_field_head, &bitmap_default_obstack);
- bitmap_initialize (&generic_field_head, &bitmap_default_obstack);
for (pc = &clauses, c = clauses; c ; c = *pc)
{
@@ -5668,6 +5694,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
switch (OMP_CLAUSE_CODE (c))
{
case OMP_CLAUSE_SHARED:
+ field_ok = allow_fields;
goto check_dup_generic;
case OMP_CLAUSE_PRIVATE:
field_ok = allow_fields;
@@ -5691,6 +5718,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
{
gcc_assert (TREE_CODE (t) == MEM_REF);
t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == POINTER_PLUS_EXPR)
+ t = TREE_OPERAND (t, 0);
if (TREE_CODE (t) == ADDR_EXPR
|| TREE_CODE (t) == INDIRECT_REF)
t = TREE_OPERAND (t, 0);
@@ -5753,7 +5782,11 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
break;
}
else if (!type_dependent_expression_p (t)
- && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t))
+ && (!declare_simd
+ || TREE_CODE (t) != PARM_DECL
+ || TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
+ || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t)))))
{
error ("linear step expression must be integral");
remove = true;
@@ -5762,12 +5795,27 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
else
{
t = mark_rvalue_use (t);
+ if (declare_simd && TREE_CODE (t) == PARM_DECL)
+ {
+ OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1;
+ goto check_dup_generic;
+ }
if (!processing_template_decl
&& (VAR_P (OMP_CLAUSE_DECL (c))
|| TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL))
{
- if (TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL)
- t = maybe_constant_value (t);
+ if (declare_simd)
+ {
+ t = maybe_constant_value (t);
+ if (TREE_CODE (t) != INTEGER_CST)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<linear%> clause step %qE is neither "
+ "constant nor a parameter", t);
+ remove = true;
+ break;
+ }
+ }
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
tree type = TREE_TYPE (OMP_CLAUSE_DECL (c));
if (TREE_CODE (type) == REFERENCE_TYPE)
@@ -5821,7 +5869,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
if (t)
{
- if (!remove)
+ if (!remove && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED)
omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
}
else
@@ -5857,6 +5905,12 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
error ("%qD appears more than once in data clauses", t);
remove = true;
}
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
+ && bitmap_bit_p (&map_head, DECL_UID (t)))
+ {
+ error ("%qD appears both in data and map clauses", t);
+ remove = true;
+ }
else
bitmap_set_bit (&generic_head, DECL_UID (t));
if (!field_ok)
@@ -5866,7 +5920,9 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
&& TREE_CODE (t) == FIELD_DECL
&& t == OMP_CLAUSE_DECL (c))
{
- OMP_CLAUSE_DECL (c) = omp_privatize_field (t);
+ OMP_CLAUSE_DECL (c)
+ = omp_privatize_field (t, (OMP_CLAUSE_CODE (c)
+ == OMP_CLAUSE_SHARED));
if (OMP_CLAUSE_DECL (c) == error_mark_node)
remove = true;
}
@@ -5902,6 +5958,11 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
error ("%qD appears more than once in data clauses", t);
remove = true;
}
+ else if (bitmap_bit_p (&map_head, DECL_UID (t)))
+ {
+ error ("%qD appears both in data and map clauses", t);
+ remove = true;
+ }
else
bitmap_set_bit (&firstprivate_head, DECL_UID (t));
goto handle_field_decl;
@@ -6072,6 +6133,30 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
break;
case OMP_CLAUSE_SCHEDULE:
+ if (OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_NONMONOTONIC)
+ {
+ const char *p = NULL;
+ switch (OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_MASK)
+ {
+ case OMP_CLAUSE_SCHEDULE_STATIC: p = "static"; break;
+ case OMP_CLAUSE_SCHEDULE_DYNAMIC: break;
+ case OMP_CLAUSE_SCHEDULE_GUIDED: break;
+ case OMP_CLAUSE_SCHEDULE_AUTO: p = "auto"; break;
+ case OMP_CLAUSE_SCHEDULE_RUNTIME: p = "runtime"; break;
+ default: gcc_unreachable ();
+ }
+ if (p)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<nonmonotonic%> modifier specified for %qs "
+ "schedule kind", p);
+ OMP_CLAUSE_SCHEDULE_KIND (c)
+ = (enum omp_clause_schedule_kind)
+ (OMP_CLAUSE_SCHEDULE_KIND (c)
+ & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
+ }
+ }
+
t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c);
if (t == NULL)
;
@@ -6406,7 +6491,10 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
}
if (REFERENCE_REF_P (t)
&& TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF)
- t = TREE_OPERAND (t, 0);
+ {
+ t = TREE_OPERAND (t, 0);
+ OMP_CLAUSE_DECL (c) = t;
+ }
if (TREE_CODE (t) == COMPONENT_REF
&& allow_fields
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_)
@@ -6443,15 +6531,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
break;
if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
{
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
- && (OMP_CLAUSE_MAP_KIND (c)
- == GOMP_MAP_FIRSTPRIVATE_POINTER))
- {
- if (bitmap_bit_p (&generic_field_head, DECL_UID (t)))
- break;
- }
- else if (bitmap_bit_p (&map_field_head, DECL_UID (t)))
- break;
+ if (bitmap_bit_p (&map_field_head, DECL_UID (t)))
+ goto handle_map_references;
}
}
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
@@ -6459,7 +6540,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
if (processing_template_decl)
break;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
- && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
+ && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
+ || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER))
break;
if (DECL_P (t))
error ("%qD is not a variable in %qs clause", t,
@@ -6511,17 +6593,13 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
error ("%qD appears more than once in data clauses", t);
remove = true;
}
- else
+ else if (bitmap_bit_p (&map_head, DECL_UID (t)))
{
- bitmap_set_bit (&generic_head, DECL_UID (t));
- if (t != OMP_CLAUSE_DECL (c)
- && (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF
- || (REFERENCE_REF_P (OMP_CLAUSE_DECL (c))
- && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c),
- 0))
- == COMPONENT_REF))))
- bitmap_set_bit (&generic_field_head, DECL_UID (t));
+ error ("%qD appears both in data and map clauses", t);
+ remove = true;
}
+ else
+ bitmap_set_bit (&generic_head, DECL_UID (t));
}
else if (bitmap_bit_p (&map_head, DECL_UID (t)))
{
@@ -6531,6 +6609,12 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
error ("%qD appears more than once in map clauses", t);
remove = true;
}
+ else if (bitmap_bit_p (&generic_head, DECL_UID (t))
+ || bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
+ {
+ error ("%qD appears both in data and map clauses", t);
+ remove = true;
+ }
else
{
bitmap_set_bit (&map_head, DECL_UID (t));
@@ -6538,20 +6622,75 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
&& TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF)
bitmap_set_bit (&map_field_head, DECL_UID (t));
}
+ handle_map_references:
+ if (!remove
+ && !processing_template_decl
+ && allow_fields
+ && TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) == REFERENCE_TYPE)
+ {
+ t = OMP_CLAUSE_DECL (c);
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
+ {
+ OMP_CLAUSE_DECL (c) = build_simple_mem_ref (t);
+ if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
+ OMP_CLAUSE_SIZE (c)
+ = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t)));
+ }
+ else if (OMP_CLAUSE_MAP_KIND (c)
+ != GOMP_MAP_FIRSTPRIVATE_POINTER
+ && (OMP_CLAUSE_MAP_KIND (c)
+ != GOMP_MAP_FIRSTPRIVATE_REFERENCE)
+ && (OMP_CLAUSE_MAP_KIND (c)
+ != GOMP_MAP_ALWAYS_POINTER))
+ {
+ tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+ OMP_CLAUSE_MAP);
+ if (TREE_CODE (t) == COMPONENT_REF)
+ OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER);
+ else
+ OMP_CLAUSE_SET_MAP_KIND (c2,
+ GOMP_MAP_FIRSTPRIVATE_REFERENCE);
+ OMP_CLAUSE_DECL (c2) = t;
+ OMP_CLAUSE_SIZE (c2) = size_zero_node;
+ OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
+ OMP_CLAUSE_CHAIN (c) = c2;
+ OMP_CLAUSE_DECL (c) = build_simple_mem_ref (t);
+ if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
+ OMP_CLAUSE_SIZE (c)
+ = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t)));
+ c = c2;
+ }
+ }
break;
case OMP_CLAUSE_TO_DECLARE:
- t = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (t) == FUNCTION_DECL)
- break;
- /* FALLTHRU */
case OMP_CLAUSE_LINK:
t = OMP_CLAUSE_DECL (c);
- if (!VAR_P (t))
+ if (TREE_CODE (t) == FUNCTION_DECL
+ && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE)
+ ;
+ else if (!VAR_P (t))
{
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qE is not a variable in clause %qs", t,
- omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE)
+ {
+ if (TREE_CODE (t) == OVERLOAD && OVL_CHAIN (t))
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "overloaded function name %qE in clause %qs", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ else if (TREE_CODE (t) == TEMPLATE_ID_EXPR)
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "template %qE in clause %qs", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ else
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE is neither a variable nor a function name "
+ "in clause %qs", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ }
+ else
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE is not a variable in clause %qs", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
remove = true;
}
else if (DECL_THREAD_LOCAL_P (t))
@@ -6568,6 +6707,17 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
remove = true;
}
+ if (remove)
+ break;
+ if (bitmap_bit_p (&generic_head, DECL_UID (t)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE appears more than once on the same "
+ "%<declare target%> directive", t);
+ remove = true;
+ }
+ else
+ bitmap_set_bit (&generic_head, DECL_UID (t));
break;
case OMP_CLAUSE_UNIFORM:
@@ -6583,6 +6733,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
remove = true;
break;
}
+ /* map_head bitmap is used as uniform_head if declare_simd. */
+ bitmap_set_bit (&map_head, DECL_UID (t));
goto check_dup_generic;
case OMP_CLAUSE_GRAINSIZE:
@@ -6688,7 +6840,6 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
goto check_dup_generic;
case OMP_CLAUSE_NOWAIT:
- case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_DEFAULT:
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_COLLAPSE:
@@ -6707,6 +6858,10 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
case OMP_CLAUSE_SEQ:
break;
+ case OMP_CLAUSE_ORDERED:
+ ordered_seen = true;
+ break;
+
case OMP_CLAUSE_INBRANCH:
case OMP_CLAUSE_NOTINBRANCH:
if (branch_seen)
@@ -6768,6 +6923,17 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
case OMP_CLAUSE_LINEAR:
if (!declare_simd)
need_implicitly_determined = true;
+ else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c)
+ && !bitmap_bit_p (&map_head,
+ DECL_UID (OMP_CLAUSE_LINEAR_STEP (c))))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<linear%> clause step is a parameter %qD not "
+ "specified in %<uniform%> clause",
+ OMP_CLAUSE_LINEAR_STEP (c));
+ *pc = OMP_CLAUSE_CHAIN (c);
+ continue;
+ }
break;
case OMP_CLAUSE_COPYPRIVATE:
need_copy_assignment = true;
@@ -6789,6 +6955,21 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
}
pc = &OMP_CLAUSE_CHAIN (c);
continue;
+ case OMP_CLAUSE_SCHEDULE:
+ if (ordered_seen
+ && (OMP_CLAUSE_SCHEDULE_KIND (c)
+ & OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<nonmonotonic%> schedule modifier specified "
+ "together with %<ordered%> clause");
+ OMP_CLAUSE_SCHEDULE_KIND (c)
+ = (enum omp_clause_schedule_kind)
+ (OMP_CLAUSE_SCHEDULE_KIND (c)
+ & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
+ }
+ pc = &OMP_CLAUSE_CHAIN (c);
+ continue;
case OMP_CLAUSE_NOWAIT:
if (copyprivate_seen)
{
@@ -6906,6 +7087,15 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
need_dtor))
remove = true;
+ if (!remove
+ && c_kind == OMP_CLAUSE_SHARED
+ && processing_template_decl)
+ {
+ t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
+ if (t)
+ OMP_CLAUSE_DECL (c) = t;
+ }
+
if (remove)
*pc = OMP_CLAUSE_CHAIN (c);
else
@@ -7202,9 +7392,10 @@ finish_omp_task (tree clauses, tree body)
static bool
handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
- tree declv, tree initv, tree condv, tree incrv,
- tree *body, tree *pre_body, tree &clauses,
- tree *lastp, int collapse, int ordered)
+ tree declv, tree orig_declv, tree initv,
+ tree condv, tree incrv, tree *body,
+ tree *pre_body, tree &clauses, tree *lastp,
+ int collapse, int ordered)
{
tree diff, iter_init, iter_incr = NULL, last;
tree incr_var = NULL, orig_pre_body, orig_body, c;
@@ -7261,6 +7452,10 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
TREE_OPERAND (cond, 1), iter);
return true;
}
+ if (!c_omp_check_loop_iv_exprs (locus, orig_declv,
+ TREE_VEC_ELT (declv, i), NULL_TREE,
+ cond, cp_walk_subtrees))
+ return true;
switch (TREE_CODE (incr))
{
@@ -7516,7 +7711,7 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
tree
finish_omp_for (location_t locus, enum tree_code code, tree declv,
tree orig_declv, tree initv, tree condv, tree incrv,
- tree body, tree pre_body, tree clauses)
+ tree body, tree pre_body, vec<tree> *orig_inits, tree clauses)
{
tree omp_for = NULL, orig_incr = NULL;
tree decl = NULL, init, cond, incr, orig_decl = NULL_TREE, block = NULL_TREE;
@@ -7592,6 +7787,20 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
TREE_VEC_ELT (initv, i) = init;
}
+ if (orig_inits)
+ {
+ bool fail = false;
+ tree orig_init;
+ FOR_EACH_VEC_ELT (*orig_inits, i, orig_init)
+ if (orig_init
+ && !c_omp_check_loop_iv_exprs (locus, declv,
+ TREE_VEC_ELT (declv, i), orig_init,
+ NULL_TREE, cp_walk_subtrees))
+ fail = true;
+ if (fail)
+ return NULL;
+ }
+
if (dependent_omp_for_p (declv, initv, condv, incrv))
{
tree stmt;
@@ -7665,10 +7874,10 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
}
if (code == CILK_FOR && i == 0)
orig_decl = decl;
- if (handle_omp_for_class_iterator (i, locus, code, declv, initv,
- condv, incrv, &body, &pre_body,
- clauses, &last, collapse,
- ordered))
+ if (handle_omp_for_class_iterator (i, locus, code, declv, orig_declv,
+ initv, condv, incrv, &body,
+ &pre_body, clauses, &last,
+ collapse, ordered))
return NULL;
continue;
}
@@ -7727,6 +7936,10 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv,
incrv, body, pre_body);
+ /* Check for iterators appearing in lb, b or incr expressions. */
+ if (omp_for && !c_omp_check_loop_iv (omp_for, orig_declv, cp_walk_subtrees))
+ omp_for = NULL_TREE;
+
if (omp_for == NULL)
{
if (block)
@@ -7734,6 +7947,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
return NULL;
}
+ add_stmt (omp_for);
+
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
{
decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i), 0);
@@ -8013,7 +8228,8 @@ finish_omp_atomic (enum tree_code code, enum tree_code opcode, tree lhs,
return;
}
stmt = c_finish_omp_atomic (input_location, code, opcode, lhs, rhs,
- v, lhs1, rhs1, swapped, seq_cst);
+ v, lhs1, rhs1, swapped, seq_cst,
+ processing_template_decl != 0);
if (stmt == error_mark_node)
return;
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index bdd8946890d..086724c6408 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -516,12 +516,12 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
if (DECL_FUNCTION_MEMBER_P (member)
&& ! flag_ms_extensions)
emit_diagnostic (diag_kind, input_location, 0,
- "invalid use of member function "
- "(did you forget the %<()%> ?)");
+ "invalid use of member function %qD "
+ "(did you forget the %<()%> ?)", member);
else
emit_diagnostic (diag_kind, input_location, 0,
- "invalid use of member "
- "(did you forget the %<&%> ?)");
+ "invalid use of member %qD "
+ "(did you forget the %<&%> ?)", member);
}
break;