diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-16 17:02:56 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-16 17:02:56 +0000 |
commit | c8aed844acdc89884d630c7e3266ecd8d4101847 (patch) | |
tree | 0d046a9255339220c1bbd6ba14e84e5304acbe10 /gcc/c | |
parent | 74f8420a5b204c5e021ce05b3d0d79ba9718360a (diff) | |
download | gcc-c8aed844acdc89884d630c7e3266ecd8d4101847.tar.gz |
2016-04-16 Basile Starynkevitch <basile@starynkevitch.net>
{{merging with even more of GCC 6, using subversion 1.9
svn merge -r231651:232605 ^/trunk
}}
[gcc/]
2016-04-16 Basile Starynkevitch <basile@starynkevitch.net>
* melt/libmelt-ana-gimple.melt:
(melt_build_transaction_with_label_norm): New inlined function,
for gimple_transaction operator implementation...
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@235064 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 99 | ||||
-rw-r--r-- | gcc/c/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc/c/c-array-notation.c | 2 | ||||
-rw-r--r-- | gcc/c/c-aux-info.c | 2 | ||||
-rw-r--r-- | gcc/c/c-convert.c | 14 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 14 | ||||
-rw-r--r-- | gcc/c/c-errors.c | 2 | ||||
-rw-r--r-- | gcc/c/c-fold.c | 2 | ||||
-rw-r--r-- | gcc/c/c-lang.c | 2 | ||||
-rw-r--r-- | gcc/c/c-lang.h | 2 | ||||
-rw-r--r-- | gcc/c/c-objc-common.c | 2 | ||||
-rw-r--r-- | gcc/c/c-objc-common.h | 2 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 132 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 2 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 175 | ||||
-rw-r--r-- | gcc/c/config-lang.in | 2 | ||||
-rw-r--r-- | gcc/c/gccspec.c | 2 |
17 files changed, 373 insertions, 85 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 2ba94646e64..d11a822b217 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,100 @@ +2016-01-14 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/68773 + * c-parser.c (c_parser_oacc_declare, c_parser_omp_declare_target): Don't + set force_output. + +2016-01-14 Marek Polacek <polacek@redhat.com> + + PR c/69262 + * c-decl.c (grokdeclarator): Provide more information for invalid + array declarations. + +2016-01-06 David Malcolm <dmalcolm@redhat.com> + + * c-parser.c (c_parser_unary_expression): For dereferences, build + a combined location before calling build_indirect_ref, so that + error reports cover the full range, manually updating the c_expr + src_range. + +2016-01-06 Marek Polacek <polacek@redhat.com> + + PR sanitizer/69099 + * c-convert.c (convert) [INTEGER_TYPE]: Drop ARG. Don't pass ARG to + ubsan_instrument_float_cast. Fold EXPR. Use NULL_TREE instead of + NULL. + +2016-01-04 Jakub Jelinek <jakub@redhat.com> + + Update copyright years. + +2016-01-04 Marek Polacek <polacek@redhat.com> + + PR c/68908 + * c-typeck.c (build_atomic_assign): Improve commentary. Add + optimization to use __atomic_fetch_* built-in if possible. + +2015-12-23 Thomas Schwinge <thomas@codesourcery.com> + + * c-parser.c (c_parser_oacc_clause_use_device): Merge function + into... + (c_parser_omp_clause_use_device_ptr): ... this function. Adjust + all users. + +2015-12-22 Marek Polacek <polacek@redhat.com> + + PR c/69002 + * c-typeck.c (build_component_ref): Warn when acessing elements of + atomic structures or unions. + +2015-12-21 David Malcolm <dmalcolm@redhat.com> + + * c-typeck.c: Include "gcc-rich-location.h". + (build_binary_op): In the two places that call binary_op_error, + create a gcc_rich_location and populate it with the location of + the binary op and its two operands. + +2015-12-16 David Malcolm <dmalcolm@redhat.com> + + * c-parser.c (c_parser_statement_after_labels): When calling + c_finish_return, Use the return expression's location if it has + one, falling back to the location of the first token within it. + * c-typeck.c (c_finish_return): When issuing warnings about + the incorrect presence/absence of a return value, issue a note + showing the declaration of the function. + +2015-12-16 David Malcolm <dmalcolm@redhat.com> + + * c-parser.c (struct c_parser): Expand array "tokens_buf" from 2 + to 4. + (c_parser_peek_nth_token): New function. + (c_parser_peek_conflict_marker): New function. + (c_parser_error): Detect conflict markers and report them as such. + +2015-12-16 David Malcolm <dmalcolm@redhat.com> + + * c-parser.c (c_parser_postfix_expression): Use EXPR_LOC_OR_LOC + to preserve range information for the primary expression + in the call to c_parser_postfix_expression_after_primary. + +2015-12-16 David Malcolm <dmalcolm@redhat.com> + + * c-parser.c (c_parser_static_assert_declaration_no_semi): Use the + expression location, falling back on the first token location, + rather than always using the latter. + +2015-12-16 Marek Polacek <polacek@redhat.com> + + PR c/64637 + * c-typeck.c (c_process_expr_stmt): Use location of the expression if + available. + +2015-12-15 Marek Polacek <polacek@redhat.com> + + PR c/68907 + * c-typeck.c (build_atomic_assign): Set TREE_NO_WARNING on an + artificial decl. + 2015-12-08 David Malcolm <dmalcolm@redhat.com> * c-parser.c (c_parser_alignof_expression): Capture location of @@ -3093,7 +3190,7 @@ * c-decl.c: Likewise. Include gt-c-c-decl.h, not gt-c-decl.h. * c-parser.c: Likewise. Include gt-c-c-parser.h, not gt-c-parser.h. -Copyright (C) 2012-2015 Free Software Foundation, Inc. +Copyright (C) 2012-2016 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in index b1d0e91b0ad..8525707f996 100644 --- a/gcc/c/Make-lang.in +++ b/gcc/c/Make-lang.in @@ -1,5 +1,5 @@ # Top level -*- makefile -*- fragment for GNU C - C language. -# Copyright (C) 1994-2015 Free Software Foundation, Inc. +# Copyright (C) 1994-2016 Free Software Foundation, Inc. #This file is part of GCC. diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c index 8d5876a4b32..716bd119ffc 100644 --- a/gcc/c/c-array-notation.c +++ b/gcc/c/c-array-notation.c @@ -1,7 +1,7 @@ /* This file is part of the Intel(R) Cilk(TM) Plus support This file contains routines to handle Array Notation expression handling routines in the C Compiler. - Copyright (C) 2013-2015 Free Software Foundation, Inc. + Copyright (C) 2013-2016 Free Software Foundation, Inc. Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>, Intel Corporation. diff --git a/gcc/c/c-aux-info.c b/gcc/c/c-aux-info.c index 79d98518561..f69c04369cf 100644 --- a/gcc/c/c-aux-info.c +++ b/gcc/c/c-aux-info.c @@ -1,7 +1,7 @@ /* Generate information regarding function declarations and definitions based on information stored in GCC's tree structure. This code implements the -aux-info option. - Copyright (C) 1989-2015 Free Software Foundation, Inc. + Copyright (C) 1989-2016 Free Software Foundation, Inc. Contributed by Ron Guilmette (rfg@segfault.us.com). This file is part of GCC. diff --git a/gcc/c/c-convert.c b/gcc/c/c-convert.c index 6476a8b01dd..4167c3461f3 100644 --- a/gcc/c/c-convert.c +++ b/gcc/c/c-convert.c @@ -1,5 +1,5 @@ /* Language-level data type conversion for GNU C. - Copyright (C) 1987-2015 Free Software Foundation, Inc. + Copyright (C) 1987-2016 Free Software Foundation, Inc. This file is part of GCC. @@ -111,20 +111,16 @@ convert (tree type, tree expr) && COMPLETE_TYPE_P (type) && do_ubsan_in_current_function ()) { - tree arg; if (in_late_binary_op) - { - expr = save_expr (expr); - arg = expr; - } + expr = save_expr (expr); else { expr = c_save_expr (expr); - arg = c_fully_fold (expr, false, NULL); + expr = c_fully_fold (expr, false, NULL); } - tree check = ubsan_instrument_float_cast (loc, type, expr, arg); + tree check = ubsan_instrument_float_cast (loc, type, expr); expr = fold_build1 (FIX_TRUNC_EXPR, type, expr); - if (check == NULL) + if (check == NULL_TREE) return expr; return fold_build2 (COMPOUND_EXPR, TREE_TYPE (expr), check, expr); } diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 2da84f26463..5830e22a7fc 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -1,5 +1,5 @@ /* Process declarations and variables for C compiler. - Copyright (C) 1988-2015 Free Software Foundation, Inc. + Copyright (C) 1988-2016 Free Software Foundation, Inc. This file is part of GCC. @@ -5951,6 +5951,18 @@ grokdeclarator (const struct c_declarator *declarator, { error_at (loc, "array type has incomplete element type %qT", type); + /* See if we can be more helpful. */ + if (TREE_CODE (type) == ARRAY_TYPE) + { + if (name) + inform (loc, "declaration of %qE as multidimensional " + "array must have bounds for all dimensions " + "except the first", name); + else + inform (loc, "declaration of multidimensional array " + "must have bounds for all dimensions except " + "the first"); + } type = error_mark_node; } else diff --git a/gcc/c/c-errors.c b/gcc/c/c-errors.c index ee9c2b5858d..d5e78b875ee 100644 --- a/gcc/c/c-errors.c +++ b/gcc/c/c-errors.c @@ -1,5 +1,5 @@ /* Various diagnostic subroutines for the GNU C language. - Copyright (C) 2000-2015 Free Software Foundation, Inc. + Copyright (C) 2000-2016 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis <gdr@codesourcery.com> This file is part of GCC. diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c index c554e179d55..f07917f17e7 100644 --- a/gcc/c/c-fold.c +++ b/gcc/c/c-fold.c @@ -1,5 +1,5 @@ /* Support for fully folding sub-trees of an expression for C compiler. - Copyright (C) 1992-2015 Free Software Foundation, Inc. + Copyright (C) 1992-2016 Free Software Foundation, Inc. This file is part of GCC. diff --git a/gcc/c/c-lang.c b/gcc/c/c-lang.c index 2ee7f91cc82..89954b749cf 100644 --- a/gcc/c/c-lang.c +++ b/gcc/c/c-lang.c @@ -1,5 +1,5 @@ /* Language-specific hook definitions for C front end. - Copyright (C) 1991-2015 Free Software Foundation, Inc. + Copyright (C) 1991-2016 Free Software Foundation, Inc. This file is part of GCC. diff --git a/gcc/c/c-lang.h b/gcc/c/c-lang.h index 9b45c87a6c2..ac7c1bb0541 100644 --- a/gcc/c/c-lang.h +++ b/gcc/c/c-lang.h @@ -1,5 +1,5 @@ /* Definitions for C language specific types. - Copyright (C) 2009-2015 Free Software Foundation, Inc. + Copyright (C) 2009-2016 Free Software Foundation, Inc. This file is part of GCC. diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c index 77a883b49b4..18247af2b54 100644 --- a/gcc/c/c-objc-common.c +++ b/gcc/c/c-objc-common.c @@ -1,5 +1,5 @@ /* Some code common to C and ObjC front ends. - Copyright (C) 2001-2015 Free Software Foundation, Inc. + Copyright (C) 2001-2016 Free Software Foundation, Inc. This file is part of GCC. diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h index 50c9f54998c..ccb4903ee42 100644 --- a/gcc/c/c-objc-common.h +++ b/gcc/c/c-objc-common.h @@ -1,5 +1,5 @@ /* Language hooks common to C and ObjC front ends. - Copyright (C) 2004-2015 Free Software Foundation, Inc. + Copyright (C) 2004-2016 Free Software Foundation, Inc. Contributed by Ziemowit Laski <zlaski@apple.com> This file is part of GCC. diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 124c30b9939..919680aab47 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1,5 +1,5 @@ /* Parser for C and Objective-C. - Copyright (C) 1987-2015 Free Software Foundation, Inc. + Copyright (C) 1987-2016 Free Software Foundation, Inc. Parser actions based on the old Bison parser; structure somewhat influenced by and fragments based on the C++ parser. @@ -202,8 +202,8 @@ struct GTY(()) c_parser { /* The look-ahead tokens. */ c_token * GTY((skip)) tokens; /* Buffer for look-ahead tokens. */ - c_token tokens_buf[2]; - /* How many look-ahead tokens are available (0, 1 or 2, or + c_token tokens_buf[4]; + /* How many look-ahead tokens are available (0 - 4, or more if parsing from pre-lexed tokens). */ unsigned int tokens_avail; /* True if a syntax error is being recovered from; false otherwise. @@ -492,6 +492,23 @@ c_parser_peek_2nd_token (c_parser *parser) return &parser->tokens[1]; } +/* Return a pointer to the Nth token from PARSER, reading it + in if necessary. The N-1th token is already read in. */ + +static c_token * +c_parser_peek_nth_token (c_parser *parser, unsigned int n) +{ + /* N is 1-based, not zero-based. */ + gcc_assert (n > 0); + + if (parser->tokens_avail >= n) + return &parser->tokens[n - 1]; + gcc_assert (parser->tokens_avail == n - 1); + c_lex_one_token (parser, &parser->tokens[n - 1]); + parser->tokens_avail = n; + return &parser->tokens[n - 1]; +} + /* Return true if TOKEN can start a type name, false otherwise. */ static bool @@ -829,6 +846,46 @@ c_parser_set_source_position_from_token (c_token *token) } } +/* Helper function for c_parser_error. + Having peeked a token of kind TOK1_KIND that might signify + a conflict marker, peek successor tokens to determine + if we actually do have a conflict marker. + Specifically, we consider a run of 7 '<', '=' or '>' characters + at the start of a line as a conflict marker. + These come through the lexer as three pairs and a single, + e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<'). + If it returns true, *OUT_LOC is written to with the location/range + of the marker. */ + +static bool +c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind, + location_t *out_loc) +{ + c_token *token2 = c_parser_peek_2nd_token (parser); + if (token2->type != tok1_kind) + return false; + c_token *token3 = c_parser_peek_nth_token (parser, 3); + if (token3->type != tok1_kind) + return false; + c_token *token4 = c_parser_peek_nth_token (parser, 4); + if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind)) + return false; + + /* It must be at the start of the line. */ + location_t start_loc = c_parser_peek_token (parser)->location; + if (LOCATION_COLUMN (start_loc) != 1) + return false; + + /* We have a conflict marker. Construct a location of the form: + <<<<<<< + ^~~~~~~ + with start == caret, finishing at the end of the marker. */ + location_t finish_loc = get_finish (token4->location); + *out_loc = make_location (start_loc, start_loc, finish_loc); + + return true; +} + /* Issue a diagnostic of the form FILE:LINE: MESSAGE before TOKEN where TOKEN is the next token in the input stream of PARSER. @@ -850,6 +907,20 @@ c_parser_error (c_parser *parser, const char *gmsgid) parser->error = true; if (!gmsgid) return; + + /* If this is actually a conflict marker, report it as such. */ + if (token->type == CPP_LSHIFT + || token->type == CPP_RSHIFT + || token->type == CPP_EQ_EQ) + { + location_t loc; + if (c_parser_peek_conflict_marker (parser, token->type, &loc)) + { + error_at (loc, "version control conflict marker in file"); + return; + } + } + /* This diagnostic makes more sense if it is tagged to the line of the token we just peeked at. */ c_parser_set_source_position_from_token (token); @@ -2097,8 +2168,9 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser) c_parser_consume_token (parser); if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) return; - value_loc = c_parser_peek_token (parser)->location; + location_t value_tok_loc = c_parser_peek_token (parser)->location; value = c_parser_expr_no_commas (parser, NULL).value; + value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc); parser->lex_untranslated_string = true; if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) { @@ -5107,7 +5179,8 @@ c_parser_statement_after_labels (c_parser *parser, vec<tree> *chain) location_t xloc = c_parser_peek_token (parser)->location; struct c_expr expr = c_parser_expression_conv (parser); mark_exp_read (expr.value); - stmt = c_finish_return (xloc, expr.value, expr.original_type); + stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc), + expr.value, expr.original_type); goto expect_semicolon; } break; @@ -6686,14 +6759,18 @@ c_parser_unary_expression (c_parser *parser) mark_exp_read (op.value); return parser_build_unary_op (op_loc, ADDR_EXPR, op); case CPP_MULT: - c_parser_consume_token (parser); - exp_loc = c_parser_peek_token (parser)->location; - op = c_parser_cast_expression (parser, NULL); - finish = op.get_finish (); - op = convert_lvalue_to_rvalue (exp_loc, op, true, true); - ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR); - set_c_expr_source_range (&ret, op_loc, finish); - return ret; + { + c_parser_consume_token (parser); + exp_loc = c_parser_peek_token (parser)->location; + op = c_parser_cast_expression (parser, NULL); + finish = op.get_finish (); + op = convert_lvalue_to_rvalue (exp_loc, op, true, true); + location_t combined_loc = make_location (op_loc, op_loc, finish); + ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR); + ret.src_range.m_start = op_loc; + ret.src_range.m_finish = finish; + return ret; + } case CPP_PLUS: if (!c_dialect_objc () && !in_system_header_at (input_location)) warning_at (op_loc, @@ -7953,7 +8030,8 @@ c_parser_postfix_expression (c_parser *parser) expr.value = error_mark_node; break; } - return c_parser_postfix_expression_after_primary (parser, loc, expr); + return c_parser_postfix_expression_after_primary + (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr); } /* Parse a postfix expression after a parenthesized type name: the @@ -11321,7 +11399,10 @@ c_parser_omp_clause_defaultmap (c_parser *parser, tree list) return list; } -/* OpenMP 4.5: +/* OpenACC 2.0: + use_device ( variable-list ) + + OpenMP 4.5: use_device_ptr ( variable-list ) */ static tree @@ -11656,15 +11737,6 @@ c_parser_oacc_clause_tile (c_parser *parser, tree list) return c; } -/* OpenACC 2.0: - use_device ( variable-list ) */ - -static tree -c_parser_oacc_clause_use_device (c_parser *parser, tree list) -{ - return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE, list); -} - /* OpenACC: wait ( int-expr-list ) */ @@ -12984,7 +13056,7 @@ c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask, c_name = "tile"; break; case PRAGMA_OACC_CLAUSE_USE_DEVICE: - clauses = c_parser_oacc_clause_use_device (parser, clauses); + clauses = c_parser_omp_clause_use_device_ptr (parser, clauses); c_name = "use_device"; break; case PRAGMA_OACC_CLAUSE_VECTOR: @@ -13527,10 +13599,7 @@ c_parser_oacc_declare (c_parser *parser) { g->have_offload = true; if (is_a <varpool_node *> (node)) - { - vec_safe_push (offload_vars, decl); - node->force_output = 1; - } + vec_safe_push (offload_vars, decl); } } } @@ -16412,10 +16481,7 @@ c_parser_omp_declare_target (c_parser *parser) { g->have_offload = true; if (is_a <varpool_node *> (node)) - { - vec_safe_push (offload_vars, t); - node->force_output = 1; - } + vec_safe_push (offload_vars, t); } } } diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 00e72b115ca..81a3d581ad8 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -1,5 +1,5 @@ /* Definitions for C parsing and type checking. - Copyright (C) 1987-2015 Free Software Foundation, Inc. + Copyright (C) 1987-2016 Free Software Foundation, Inc. This file is part of GCC. diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index b691072caa9..d602e3383e9 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -1,5 +1,5 @@ /* Build expressions with type checking for C compiler. - Copyright (C) 1987-2015 Free Software Foundation, Inc. + Copyright (C) 1987-2016 Free Software Foundation, Inc. This file is part of GCC. @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "cilk.h" #include "gomp-constants.h" #include "spellcheck.h" +#include "gcc-rich-location.h" /* Possible cases of implicit bad conversions. Used to select diagnostic messages in convert_for_assignment. */ @@ -2348,6 +2349,18 @@ build_component_ref (location_t loc, tree datum, tree component) return error_mark_node; } + /* Accessing elements of atomic structures or unions is undefined + behavior (C11 6.5.2.3#5). */ + if (TYPE_ATOMIC (type) && c_inhibit_evaluation_warnings == 0) + { + if (code == RECORD_TYPE) + warning_at (loc, 0, "accessing a member %qE of an atomic " + "structure %qE", component, datum); + else + warning_at (loc, 0, "accessing a member %qE of an atomic " + "union %qE", component, datum); + } + /* Chain the COMPONENT_REFs if necessary down to the FIELD. This might be better solved in future the way the C++ front end does it - by giving the anonymous entities each a @@ -3035,7 +3048,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc, return error_mark_node; /* Check that the arguments to the function are valid. */ - check_function_arguments (fntype, nargs, argarray); + check_function_arguments (loc, fntype, nargs, argarray); if (name != NULL_TREE && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10)) @@ -3685,9 +3698,9 @@ pointer_diff (location_t loc, tree op0, tree op1) return convert (restype, result); } -/* Expand atomic compound assignments into an approriate sequence as - specified by the C11 standard section 6.5.16.2. - given +/* Expand atomic compound assignments into an appropriate sequence as + specified by the C11 standard section 6.5.16.2. + _Atomic T1 E1 T2 E2 E1 op= E2 @@ -3719,26 +3732,25 @@ loop: done: feupdateenv (&fenv); - Also note that the compiler is simply issuing the generic form of - the atomic operations. This requires temp(s) and has their address - taken. The atomic processing is smart enough to figure out when the - size of an object can utilize a lock-free version, and convert the - built-in call to the appropriate lock-free routine. The optimizers - will then dispose of any temps that are no longer required, and - lock-free implementations are utilized as long as there is target - support for the required size. + The compiler will issue the __atomic_fetch_* built-in when possible, + otherwise it will generate the generic form of the atomic operations. + This requires temp(s) and has their address taken. The atomic processing + is smart enough to figure out when the size of an object can utilize + a lock-free version, and convert the built-in call to the appropriate + lock-free routine. The optimizers will then dispose of any temps that + are no longer required, and lock-free implementations are utilized as + long as there is target support for the required size. If the operator is NOP_EXPR, then this is a simple assignment, and an __atomic_store is issued to perform the assignment rather than - the above loop. - -*/ + the above loop. */ /* Build an atomic assignment at LOC, expanding into the proper sequence to store LHS MODIFYCODE= RHS. Return a value representing - the result of the operation, unless RETURN_OLD_P in which case + the result of the operation, unless RETURN_OLD_P, in which case return the old value of LHS (this is only for postincrement and postdecrement). */ + static tree build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode, tree rhs, bool return_old_p) @@ -3805,6 +3817,93 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode, return build2 (COMPOUND_EXPR, nonatomic_lhs_type, compound_stmt, val); } + /* Attempt to implement the atomic operation as an __atomic_fetch_* or + __atomic_*_fetch built-in rather than a CAS loop. atomic_bool type + isn't applicable for such builtins. ??? Do we want to handle enums? */ + if ((TREE_CODE (lhs_type) == INTEGER_TYPE || POINTER_TYPE_P (lhs_type)) + && TREE_CODE (rhs_type) == INTEGER_TYPE) + { + built_in_function fncode; + switch (modifycode) + { + case PLUS_EXPR: + case POINTER_PLUS_EXPR: + fncode = (return_old_p + ? BUILT_IN_ATOMIC_FETCH_ADD_N + : BUILT_IN_ATOMIC_ADD_FETCH_N); + break; + case MINUS_EXPR: + fncode = (return_old_p + ? BUILT_IN_ATOMIC_FETCH_SUB_N + : BUILT_IN_ATOMIC_SUB_FETCH_N); + break; + case BIT_AND_EXPR: + fncode = (return_old_p + ? BUILT_IN_ATOMIC_FETCH_AND_N + : BUILT_IN_ATOMIC_AND_FETCH_N); + break; + case BIT_IOR_EXPR: + fncode = (return_old_p + ? BUILT_IN_ATOMIC_FETCH_OR_N + : BUILT_IN_ATOMIC_OR_FETCH_N); + break; + case BIT_XOR_EXPR: + fncode = (return_old_p + ? BUILT_IN_ATOMIC_FETCH_XOR_N + : BUILT_IN_ATOMIC_XOR_FETCH_N); + break; + default: + goto cas_loop; + } + + /* We can only use "_1" through "_16" variants of the atomic fetch + built-ins. */ + unsigned HOST_WIDE_INT size = tree_to_uhwi (TYPE_SIZE_UNIT (lhs_type)); + if (size != 1 && size != 2 && size != 4 && size != 8 && size != 16) + goto cas_loop; + + /* If this is a pointer type, we need to multiply by the size of + the pointer target type. */ + if (POINTER_TYPE_P (lhs_type)) + { + if (!COMPLETE_TYPE_P (TREE_TYPE (lhs_type)) + /* ??? This would introduce -Wdiscarded-qualifiers + warning: __atomic_fetch_* expect volatile void * + type as the first argument. (Assignments between + atomic and non-atomic objects are OK.) */ + || TYPE_RESTRICT (lhs_type)) + goto cas_loop; + tree sz = TYPE_SIZE_UNIT (TREE_TYPE (lhs_type)); + rhs = fold_build2_loc (loc, MULT_EXPR, ptrdiff_type_node, + convert (ptrdiff_type_node, rhs), + convert (ptrdiff_type_node, sz)); + } + + /* Build __atomic_fetch_* (&lhs, &val, SEQ_CST), or + __atomic_*_fetch (&lhs, &val, SEQ_CST). */ + fndecl = builtin_decl_explicit (fncode); + params->quick_push (lhs_addr); + params->quick_push (rhs); + params->quick_push (seq_cst); + func_call = c_build_function_call_vec (loc, vNULL, fndecl, params, NULL); + + newval = create_tmp_var_raw (nonatomic_lhs_type); + TREE_ADDRESSABLE (newval) = 1; + TREE_NO_WARNING (newval) = 1; + rhs = build4 (TARGET_EXPR, nonatomic_lhs_type, newval, func_call, + NULL_TREE, NULL_TREE); + SET_EXPR_LOCATION (rhs, loc); + add_stmt (rhs); + + /* Finish the compound statement. */ + compound_stmt = c_end_compound_stmt (loc, compound_stmt, false); + + /* NEWVAL is the value which was stored, return a COMPOUND_STMT of + the statement and that value. */ + return build2 (COMPOUND_EXPR, nonatomic_lhs_type, compound_stmt, newval); + } + +cas_loop: /* Create the variables and labels required for the op= form. */ old = create_tmp_var_raw (nonatomic_lhs_type); old_addr = build_unary_op (loc, ADDR_EXPR, old, 0); @@ -3814,6 +3913,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode, newval = create_tmp_var_raw (nonatomic_lhs_type); newval_addr = build_unary_op (loc, ADDR_EXPR, newval, 0); TREE_ADDRESSABLE (newval) = 1; + TREE_NO_WARNING (newval) = 1; loop_decl = create_artificial_label (loc); loop_label = build1 (LABEL_EXPR, void_type_node, loop_decl); @@ -9544,24 +9644,36 @@ c_finish_return (location_t loc, tree retval, tree origtype) if ((warn_return_type || flag_isoc99) && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE) { + bool warned_here; if (flag_isoc99) - pedwarn (loc, 0, "%<return%> with no value, in " - "function returning non-void"); + warned_here = pedwarn + (loc, 0, + "%<return%> with no value, in function returning non-void"); else - warning_at (loc, OPT_Wreturn_type, "%<return%> with no value, " - "in function returning non-void"); + warned_here = warning_at + (loc, OPT_Wreturn_type, + "%<return%> with no value, in function returning non-void"); no_warning = true; + if (warned_here) + inform (DECL_SOURCE_LOCATION (current_function_decl), + "declared here"); } } else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE) { current_function_returns_null = 1; + bool warned_here; if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) - pedwarn (xloc, 0, - "%<return%> with a value, in function returning void"); + warned_here = pedwarn + (xloc, 0, + "%<return%> with a value, in function returning void"); else - pedwarn (xloc, OPT_Wpedantic, "ISO C forbids " - "%<return%> with expression, in function returning void"); + warned_here = pedwarn + (xloc, OPT_Wpedantic, "ISO C forbids " + "%<return%> with expression, in function returning void"); + if (warned_here) + inform (DECL_SOURCE_LOCATION (current_function_decl), + "declared here"); } else { @@ -10130,7 +10242,7 @@ c_process_expr_stmt (location_t loc, tree expr) out which is the result. */ if (!STATEMENT_LIST_STMT_EXPR (cur_stmt_list) && warn_unused_value) - emit_side_effect_warnings (loc, expr); + emit_side_effect_warnings (EXPR_LOC_OR_LOC (expr, loc), expr); exprv = expr; while (TREE_CODE (exprv) == COMPOUND_EXPR) @@ -11189,7 +11301,10 @@ build_binary_op (location_t location, enum tree_code code, && (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1)) || !vector_types_compatible_elements_p (type0, type1))) { - binary_op_error (location, code, type0, type1); + gcc_rich_location richloc (location); + richloc.maybe_add_expr (orig_op0); + richloc.maybe_add_expr (orig_op1); + binary_op_error (&richloc, code, type0, type1); return error_mark_node; } @@ -11428,7 +11543,10 @@ build_binary_op (location_t location, enum tree_code code, if (!result_type) { - binary_op_error (location, code, TREE_TYPE (op0), TREE_TYPE (op1)); + gcc_rich_location richloc (location); + richloc.maybe_add_expr (orig_op0); + richloc.maybe_add_expr (orig_op1); + binary_op_error (&richloc, code, TREE_TYPE (op0), TREE_TYPE (op1)); return error_mark_node; } @@ -13093,7 +13211,6 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd) bitmap_set_bit (&map_head, DECL_UID (t)); goto check_dup_generic; - case OMP_CLAUSE_USE_DEVICE: case OMP_CLAUSE_IS_DEVICE_PTR: case OMP_CLAUSE_USE_DEVICE_PTR: t = OMP_CLAUSE_DECL (c); diff --git a/gcc/c/config-lang.in b/gcc/c/config-lang.in index 786c58eabd2..b9cdc8e66ce 100644 --- a/gcc/c/config-lang.in +++ b/gcc/c/config-lang.in @@ -1,5 +1,5 @@ # Top level configure fragment for GNU C - C language. -# Copyright (C) 1994-2015 Free Software Foundation, Inc. +# Copyright (C) 1994-2016 Free Software Foundation, Inc. #This file is part of GCC. diff --git a/gcc/c/gccspec.c b/gcc/c/gccspec.c index 84be44674b9..cfb0aa0450a 100644 --- a/gcc/c/gccspec.c +++ b/gcc/c/gccspec.c @@ -1,5 +1,5 @@ /* Specific flags and argument handling of the C front-end. - Copyright (C) 1999-2015 Free Software Foundation, Inc. + Copyright (C) 1999-2016 Free Software Foundation, Inc. This file is part of GCC. |