aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/cp
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2013-08-05 15:18:29 -0700
committerBen Cheng <bccheng@google.com>2013-08-05 16:03:48 -0700
commit32fce3edda831e36ee484406c39dffbe0230f257 (patch)
tree733b1b5398304b260a4ee3d5d9b17da5038c5486 /gcc-4.8/gcc/cp
parente85b9ca2afe8edbb9fa99c6ce2cc4e52dce18c21 (diff)
downloadtoolchain_gcc-32fce3edda831e36ee484406c39dffbe0230f257.tar.gz
toolchain_gcc-32fce3edda831e36ee484406c39dffbe0230f257.tar.bz2
toolchain_gcc-32fce3edda831e36ee484406c39dffbe0230f257.zip
[4.8] Merge GCC 4.8.1
Change-Id: Ic8a60b7563f5172440fd40788605163a0cca6e30
Diffstat (limited to 'gcc-4.8/gcc/cp')
-rw-r--r--gcc-4.8/gcc/cp/ChangeLog397
-rw-r--r--gcc-4.8/gcc/cp/call.c47
-rw-r--r--gcc-4.8/gcc/cp/class.c20
-rw-r--r--gcc-4.8/gcc/cp/cp-tree.h55
-rw-r--r--gcc-4.8/gcc/cp/decl.c156
-rw-r--r--gcc-4.8/gcc/cp/decl2.c41
-rw-r--r--gcc-4.8/gcc/cp/error.c25
-rw-r--r--gcc-4.8/gcc/cp/init.c33
-rw-r--r--gcc-4.8/gcc/cp/mangle.c37
-rw-r--r--gcc-4.8/gcc/cp/name-lookup.h3
-rw-r--r--gcc-4.8/gcc/cp/parser.c244
-rw-r--r--gcc-4.8/gcc/cp/pt.c161
-rw-r--r--gcc-4.8/gcc/cp/search.c8
-rw-r--r--gcc-4.8/gcc/cp/semantics.c87
-rw-r--r--gcc-4.8/gcc/cp/tree.c115
-rw-r--r--gcc-4.8/gcc/cp/typeck.c98
-rw-r--r--gcc-4.8/gcc/cp/typeck2.c33
17 files changed, 1302 insertions, 258 deletions
diff --git a/gcc-4.8/gcc/cp/ChangeLog b/gcc-4.8/gcc/cp/ChangeLog
index a22f2c352..ffc0ccd8b 100644
--- a/gcc-4.8/gcc/cp/ChangeLog
+++ b/gcc-4.8/gcc/cp/ChangeLog
@@ -1,3 +1,400 @@
+2013-05-31 Release Manager
+
+ * GCC 4.8.1 released.
+
+2013-05-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/57388
+ * tree.c (build_ref_qualified_type): Clear
+ FUNCTION_RVALUE_QUALIFIED for lvalue ref-qualifier.
+
+ PR c++/57016
+ * pt.c (instantiation_dependent_r) [TRAIT_EXPR]: Only check type2
+ if there is one.
+
+2013-05-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/57325
+ * tree.c (build_cplus_array_type): Copy layout info if element
+ type is complete.
+
+ PR c++/57317
+ * decl2.c (determine_visibility): Use PRIMARY_TEMPLATE_P to decide
+ whether a template has its own args.
+
+2013-05-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/57279
+ * decl.c (grokdeclarator): Allow member function qualifiers in
+ TYPENAME context in C++11 mode.
+
+2013-05-16 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/56782 - Regression with empty pack expansions
+ * pt.c (use_pack_expansion_extra_args_p): When at least a
+ parameter pack has an empty argument pack, and another parameter
+ pack has no argument pack at all, use the PACK_EXPANSION_EXTRA
+ mechanism.
+
+2013-05-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/57243
+ * parser.c (cp_parser_range_for): Call complete_type.
+
+ PR c++/57041
+ * pt.c (tsubst_copy_and_build): Don't recur into a designator.
+
+2013-05-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/56998
+ * semantics.c (potential_constant_expression_1): Make sure the
+ called function is potentially constant.
+
+ PR c++/57041
+ * decl.c (reshape_init_class): Handle error_mark_node.
+
+ PR c++/57254
+ * typeck.c (merge_types): Propagate ref-qualifier
+ in METHOD_TYPE case.
+
+ PR c++/57253
+ * decl.c (grokdeclarator): Apply ref-qualifier
+ in the TYPENAME case.
+
+ PR c++/57252
+ * decl.c (decls_match): Compare ref-qualifiers.
+
+ PR c++/57196
+ * pt.c (convert_template_argument): Use dependent_template_arg_p,
+ not uses_template_parms.
+
+2013-05-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/57047
+ * semantics.c (cxx_fold_indirect_ref): Fix thinko.
+
+2013-05-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/57222
+ * pt.c (lookup_template_class_1): Handle getting a template
+ template parameter as D1.
+
+2013-05-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/57068
+ * decl.c (grokdeclarator): Warn about ref-qualifiers here.
+ * parser.c (cp_parser_ref_qualifier_seq_opt): Not here.
+ * error.c (maybe_warn_cpp0x): s/0x/11/.
+
+2013-05-08 Marc Glisse <marc.glisse@inria.fr>
+
+ * typeck.c (cp_build_binary_op): Call save_expr before
+ build_vector_from_val.
+
+2013-05-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57183
+ * decl.c (cp_finish_decl): After do_auto_deduction copy the
+ qualifers with cp_apply_type_quals_to_decl.
+
+2013-05-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57092
+ * semantics.c (finish_decltype_type): Handle instantiated template
+ non-type arguments.
+
+2013-04-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56450
+ * semantics.c (finish_decltype_type): Handle COMPOUND_EXPR.
+
+2013-04-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/57064
+ * call.c (add_function_candidate): Strip ref-to-ptr conversion.
+
+ PR c++/56859
+ * typeck.c (cxx_alignas_expr): Handle value-dependence properly.
+
+ PR c++/50261
+ * init.c (perform_member_init): Call reshape_init.
+
+2013-04-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56970
+ * init.c (build_offset_ref): Add tsubst_flags_t parameter.
+ * semantics.c (finish_qualified_id_expr): Likewise.
+ (finish_id_expression): Update.
+ * typeck.c (cp_build_addr_expr_1): Likewise.
+ * pt.c (tsubst_qualified_id, resolve_nondeduced_context): Likewise.
+ * cp-tree.h: Update declarations.
+
+2013-04-17 Jason Merrill <jason@redhat.com>
+
+ DR 941
+ * decl.c (duplicate_decls): Don't propagate DECL_DELETED_FN to
+ template specializations.
+
+2013-04-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/52748
+ * pt.c (tsubst) [DECLTYPE_TYPE]: If ~id is an expression
+ rather than a destructor name, it isn't an unqualified-name.
+ (tsubst_copy_and_build): Pass down decltype_flag to operator
+ handling code, too.
+
+ PR c++/56388
+ * semantics.c (insert_capture_proxy): Just use index 1 in the
+ stmt_list_stack.
+
+2013-04-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/52748
+ * parser.c (complain_flags): New.
+ (cp_parser_postfix_expression): Use it.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_binary_expression): Likewise.
+ (cp_parser_assignment_expression): Likewise.
+ (cp_parser_expression): Likewise.
+ (cp_parser_postfix_open_square_expression): Take decltype_p.
+ (cp_parser_builtin_offsetof): Adjust.
+ (cp_convert_range_for): Pass complain to finish_unary_op_expr.
+ * decl2.c (grok_array_decl): Add decltype_p parm.
+ * cp-tree.h: Adjust prototype.
+ * semantics.c (finish_unary_op_expr): Add complain parm.
+
+2013-04-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/56895
+ * call.c (null_ptr_cst_p): Call fold_non_dependent_expr_sfinae before
+ calling maybe_constant_value for C++98.
+
+2013-04-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56913
+ * typeck2.c (build_m_component_ref): Protect error calls with
+ (complain & tf_error).
+
+2013-04-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/56895
+ * typeck.c (cp_build_binary_op): Call fold_non_dependent_expr_sfinae
+ first before calling maybe_constant_value for warn_for_div_by_zero
+ or invalid shift count warning purposes.
+
+2013-04-06 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_std_attribute): Treat [[noreturn]] like GNU
+ noreturn attribute.
+
+2013-04-03 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (FUNCTION_OR_METHOD_TYPE_CHECK): Remove.
+ (FUNCTION_REF_QUALIFIED): Use FUNC_OR_METHOD_CHECK instead.
+ (FUNCTION_RVALUE_QUALIFIED): Likewise.
+
+2013-04-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/56819
+ * tree.c (strip_typedefs): Copy NON_DEFAULT_TEMPLATE_ARGS_COUNT
+ from args to new_args.
+ (strip_typedefs_expr): Copy NON_DEFAULT_TEMPLATE_ARGS_COUNT from t to
+ r instead of doing {S,G}ET_NON_DEFAULT_TEMPLATE_ARGS_COUNT.
+
+2013-04-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/56821
+ * mangle.c (write_function_type): Mangle ref-qualifier.
+ (write_nested_name): Likewise.
+ (canonicalize_for_substitution): Preserve ref-qualifier.
+ (write_type): Likewise.
+
+2013-04-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/55951
+ * decl.c (check_array_designated_initializer): Handle CONST_DECL
+ as ce->index.
+
+2013-04-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/56772
+ * init.c (build_new): Don't try to process an array initializer
+ at template definition time.
+
+2013-04-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/56793
+ * typeck.c (finish_class_member_access_expr): Handle enum scope.
+
+2013-04-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/56794
+ * parser.c (cp_parser_range_for): Don't try to do auto deduction
+ in a template if the type of the range is incomplete.
+
+2013-04-01 Bronek Kozicki <b.kozicki@gmail.com>
+ Jason Merrill <jason@redhat.com>
+
+ Implement N2439 (ref-qualifiers for 'this')
+ * cp-tree.h (FUNCTION_REF_QUALIFIED): New.
+ (FUNCTION_RVALUE_QUALIFIED): New.
+ (FUNCTION_OR_METHOD_TYPE_CHECK): New.
+ (cpp0x_warn_str): Add CPP0X_REF_QUALIFIER.
+ (cp_ref_qualifier): New enum.
+ (cp_declarator): Add ref_qualifier.
+ * parser.c (cp_parser_ref_qualifier_seq_opt): New.
+ (cp_parser_direct_declarator): Use it.
+ (make_call_declarator): Adjust.
+ (cp_parser_lambda_declarator_opt): Adjust.
+ * call.c (add_function_candidate): Handle ref-qualifier overload
+ resolution semantics.
+ (standard_conversion): Adjust.
+ * class.c (add_method, same_signature_p): Compare ref-qualifiers.
+ * decl.c (grokdeclarator): Handle ref-qualifiers.
+ (grokfndecl): Check for invalid ref-qualifiers.
+ (static_fn_type, revert_static_member_fn): Adjust.
+ * decl2.c (build_memfn_type): Handle ref-qualifiers.
+ (check_classfn): Check them.
+ (cp_reconstruct_complex_type): Retain them.
+ * error.c (dump_ref_qualifier): New.
+ (dump_type_suffix, dump_function_decl): Use it.
+ (maybe_warn_cpp0x): Handle CPP0X_REF_QUALIFIER.
+ * pt.c (tsubst, tsubst_function_type): Instantiate ref-quals.
+ (unify): Retain them.
+ * tree.c (cp_check_qualified_type): New.
+ (cp_build_qualified_type_real): Keep exception spec and ref-qual.
+ (build_ref_qualified_type): New.
+ (strip_typedefs, build_exception_variant): Keep ref-qualifier.
+ (cp_build_type_attribute_variant): Keep ref-qualifier.
+ * typeck.c (merge_types): Keep ref-qualifier.
+ (structural_comptypes): Compare ref-qualifier.
+ (type_memfn_rqual): New.
+ (apply_memfn_quals): Take ref-qual argument.
+ * typeck2.c (build_m_component_ref): Check ref-qualifier.
+
+2013-03-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/56774
+ PR c++/35722
+ * pt.c (unify_pack_expansion): Fix indexing.
+
+2013-03-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/56728
+ * semantics.c (cxx_eval_indirect_ref): Use the folded operand if
+ we still think this might be constant.
+
+2013-03-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/56749
+ * semantics.c (finish_qualified_id_expr): Return early
+ for enum scope.
+
+2013-03-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/45282
+ * typeck2.c (build_m_component_ref): Handle prvalue object.
+
+2013-03-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/56699
+ * semantics.c (maybe_resolve_dummy): Make sure that the enclosing
+ class is derived from the type of the object.
+
+ PR c++/56692
+ * search.c (lookup_base): Handle NULL_TREE.
+
+2013-03-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56722
+ * decl.c (cp_finish_decl): Check DECL_LANG_SPECIFIC before
+ DECL_TEMPLATE_INSTANTIATION.
+
+2013-03-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/52014
+ * semantics.c (lambda_expr_this_capture): Don't capture 'this' in
+ unevaluated context.
+
+2013-03-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/54359
+ * parser.c (cp_parser_direct_declarator): Fix late return
+ for out-of-class defn of member function.
+
+2013-03-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56582
+ * semantics.c (cxx_eval_array_reference): Check for negative index.
+
+2013-03-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/56646
+ * parser.c (cp_parser_late_return_type_opt): Save and restore
+ current_class_ptr/ref.
+
+ N3276
+ PR c++/52748
+ * cp-tree.h (tsubst_flags): Add tf_decltype.
+ * call.c (build_cxx_call): Don't build a temporary if it's set.
+ (build_over_call): Make sure it's only passed to build_cxx_call.
+ * parser.c (cp_parser_primary_expression): Add decltype_p parm.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_binary_expression): Likewise.
+ (cp_parser_assignment_expression): Likewise.
+ (cp_parser_postfix_expression): Likewise. Pass tf_decltype.
+ (cp_parser_explicit_instantiation): Add decltype_p. Force a
+ temporary for a call on the LHS of a comma.
+ (cp_parser_decltype): Pass true to decltype_p parms.
+ * pt.c (tsubst) [DECLTYPE_TYPE]: Pass tf_decltype.
+ (tsubst_copy_and_build): Pass tf_decltype down only for
+ CALL_EXPR and the RHS of COMPOUND_EXPR.
+ * tree.c (build_cplus_new): Call complete_type_or_maybe_complain.
+
+ DR 657
+ * pt.c (tsubst_function_type): Call abstract_virtuals_error_sfinae.
+ (tsubst_arg_types): Likewise.
+
+ PR c++/54277
+ * semantics.c (lambda_capture_field_type): Don't build a
+ magic decltype for pointer types.
+ (lambda_proxy_type): Likewise.
+ (finish_non_static_data_member): Get the quals from
+ the object.
+
+ PR c++/52374
+ * pt.c (tsubst_qualified_id): Use current_nonlambda_class_type.
+
+ PR c++/54764
+ PR c++/55972
+ * name-lookup.h (tag_scope): Add ts_lambda.
+ * semantics.c (begin_lambda_type): Use it.
+ * decl.c (xref_tag_1): Set CLASSTYPE_LAMBDA_EXPR.
+ * pt.c (check_default_tmpl_args): Ignore lambdas.
+ (push_template_decl_real): Handle lambdas.
+ * tree.c (no_linkage_check): Adjust lambda check.
+
+ PR c++/56039
+ * tree.c (strip_typedefs_expr): Complain about lambda, don't abort.
+
+ PR c++/56447
+ PR c++/55532
+ * pt.c (instantiate_class_template_1): Instantiate lambda capture
+ list here.
+ (tsubst_copy_and_build): Not here.
+
+2013-03-22 Jakub Jelinek <jakub@redhat.com>
+
+ Backported from mainline
+ 2013-03-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/56607
+ * typeck.c (cp_build_binary_op): When calling warn_for_div_by_zero,
+ pass op1 through maybe_constant_value first.
+
+ * tree.c (cp_tree_equal): Fix a pasto.
+
2013-03-22 Release Manager
* GCC 4.8.0 released.
diff --git a/gcc-4.8/gcc/cp/call.c b/gcc-4.8/gcc/cp/call.c
index 530835b87..72c1dac25 100644
--- a/gcc-4.8/gcc/cp/call.c
+++ b/gcc-4.8/gcc/cp/call.c
@@ -555,7 +555,7 @@ null_ptr_cst_p (tree t)
{
/* Core issue 903 says only literal 0 is a null pointer constant. */
if (cxx_dialect < cxx0x)
- t = maybe_constant_value (t);
+ t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none));
STRIP_NOPS (t);
if (integer_zerop (t) && !TREE_OVERFLOW (t))
return true;
@@ -1276,7 +1276,10 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
static_fn_type (tofn)))
return NULL;
- from = build_memfn_type (fromfn, tbase, cp_type_quals (tbase));
+ from = build_memfn_type (fromfn,
+ tbase,
+ cp_type_quals (tbase),
+ type_memfn_rqual (tofn));
from = build_ptrmemfunc_type (build_pointer_type (from));
conv = build_conv (ck_pmem, from, conv);
conv->base_p = true;
@@ -1950,7 +1953,21 @@ add_function_candidate (struct z_candidate **candidates,
{
parmtype = cp_build_qualified_type
(ctype, cp_type_quals (TREE_TYPE (parmtype)));
- parmtype = build_pointer_type (parmtype);
+ if (FUNCTION_REF_QUALIFIED (TREE_TYPE (fn)))
+ {
+ /* If the function has a ref-qualifier, the implicit
+ object parameter has reference type. */
+ bool rv = FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (fn));
+ parmtype = cp_build_reference_type (parmtype, rv);
+ if (TREE_CODE (arg) == CONVERT_EXPR
+ && TYPE_PTR_P (TREE_TYPE (arg)))
+ /* Strip conversion from reference to pointer. */
+ arg = TREE_OPERAND (arg, 0);
+ arg = build_fold_indirect_ref (arg);
+ argtype = lvalue_type (arg);
+ }
+ else
+ parmtype = build_pointer_type (parmtype);
}
/* Core issue 899: When [copy-]initializing a temporary to be bound
@@ -6696,6 +6713,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
/* else continue to get conversion error. */
}
+ /* N3276 magic doesn't apply to nested calls. */
+ int decltype_flag = (complain & tf_decltype);
+ complain &= ~tf_decltype;
+
/* Find maximum size of vector to hold converted arguments. */
parmlen = list_length (parm);
nargs = vec_safe_length (args) + (first_arg != NULL_TREE ? 1 : 0);
@@ -7067,7 +7088,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return error_mark_node;
}
- return build_cxx_call (fn, nargs, argarray, complain);
+ return build_cxx_call (fn, nargs, argarray, complain|decltype_flag);
}
/* Build and return a call to FN, using NARGS arguments in ARGARRAY.
@@ -7109,12 +7130,20 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
if (VOID_TYPE_P (TREE_TYPE (fn)))
return fn;
- fn = require_complete_type_sfinae (fn, complain);
- if (fn == error_mark_node)
- return error_mark_node;
+ /* 5.2.2/11: If a function call is a prvalue of object type: if the
+ function call is either the operand of a decltype-specifier or the
+ right operand of a comma operator that is the operand of a
+ decltype-specifier, a temporary object is not introduced for the
+ prvalue. The type of the prvalue may be incomplete. */
+ if (!(complain & tf_decltype))
+ {
+ fn = require_complete_type_sfinae (fn, complain);
+ if (fn == error_mark_node)
+ return error_mark_node;
- if (MAYBE_CLASS_TYPE_P (TREE_TYPE (fn)))
- fn = build_cplus_new (TREE_TYPE (fn), fn, complain);
+ if (MAYBE_CLASS_TYPE_P (TREE_TYPE (fn)))
+ fn = build_cplus_new (TREE_TYPE (fn), fn, complain);
+ }
return convert_from_reference (fn);
}
diff --git a/gcc-4.8/gcc/cp/class.c b/gcc-4.8/gcc/cp/class.c
index 746c29d2d..37aea5c27 100644
--- a/gcc-4.8/gcc/cp/class.c
+++ b/gcc-4.8/gcc/cp/class.c
@@ -1045,6 +1045,12 @@ add_method (tree type, tree method, tree using_decl)
overloaded if any of them is a static member
function declaration.
+ [over.load] Member function declarations with the same name and
+ the same parameter-type-list as well as member function template
+ declarations with the same name, the same parameter-type-list, and
+ the same template parameter lists cannot be overloaded if any of
+ them, but not all, have a ref-qualifier.
+
[namespace.udecl] When a using-declaration brings names
from a base class into a derived class scope, member
functions in the derived class override and/or hide member
@@ -1060,11 +1066,13 @@ add_method (tree type, tree method, tree using_decl)
coming from the using class in overload resolution. */
if (! DECL_STATIC_FUNCTION_P (fn)
&& ! DECL_STATIC_FUNCTION_P (method)
- && TREE_TYPE (TREE_VALUE (parms1)) != error_mark_node
- && TREE_TYPE (TREE_VALUE (parms2)) != error_mark_node
- && (cp_type_quals (TREE_TYPE (TREE_VALUE (parms1)))
- != cp_type_quals (TREE_TYPE (TREE_VALUE (parms2)))))
- continue;
+ /* Either both or neither need to be ref-qualified for
+ differing quals to allow overloading. */
+ && (FUNCTION_REF_QUALIFIED (fn_type)
+ == FUNCTION_REF_QUALIFIED (method_type))
+ && (type_memfn_quals (fn_type) != type_memfn_quals (method_type)
+ || type_memfn_rqual (fn_type) != type_memfn_rqual (method_type)))
+ continue;
/* For templates, the return type and template parameters
must be identical. */
@@ -2063,6 +2071,8 @@ same_signature_p (const_tree fndecl, const_tree base_fndecl)
base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
if ((cp_type_quals (TREE_TYPE (TREE_VALUE (base_types)))
== cp_type_quals (TREE_TYPE (TREE_VALUE (types))))
+ && (type_memfn_rqual (TREE_TYPE (fndecl))
+ == type_memfn_rqual (TREE_TYPE (base_fndecl)))
&& compparms (TREE_CHAIN (base_types), TREE_CHAIN (types)))
return 1;
}
diff --git a/gcc-4.8/gcc/cp/cp-tree.h b/gcc-4.8/gcc/cp/cp-tree.h
index c3b2aecf3..b8080833b 100644
--- a/gcc-4.8/gcc/cp/cp-tree.h
+++ b/gcc-4.8/gcc/cp/cp-tree.h
@@ -107,8 +107,10 @@ c-common.h, not after.
or FIELD_DECL).
IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
DECL_TINFO_P (in VAR_DECL)
+ FUNCTION_REF_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE)
5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE)
DECL_VTABLE_OR_VTT_P (in VAR_DECL)
+ FUNCTION_RVALUE_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE)
6: IDENTIFIER_REPO_CHOSEN (in IDENTIFIER_NODE)
DECL_CONSTRUCTION_VTABLE_P (in VAR_DECL)
TYPE_MARKED_P (in _TYPE)
@@ -420,9 +422,11 @@ typedef enum cpp0x_warn_str
/* inheriting constructors */
CPP0X_INHERITING_CTORS,
/* C++11 attributes */
- CPP0X_ATTRIBUTES
+ CPP0X_ATTRIBUTES,
+ /* ref-qualified member functions */
+ CPP0X_REF_QUALIFIER
} cpp0x_warn_str;
-
+
/* The various kinds of operation used by composite_pointer_type. */
typedef enum composite_pointer_operation
@@ -2502,6 +2506,14 @@ struct GTY((variable_size)) lang_decl {
/* 1 iff VAR_DECL node NODE is virtual table or VTT. */
#define DECL_VTABLE_OR_VTT_P(NODE) TREE_LANG_FLAG_5 (VAR_DECL_CHECK (NODE))
+/* 1 iff FUNCTION_TYPE or METHOD_TYPE has a ref-qualifier (either & or &&). */
+#define FUNCTION_REF_QUALIFIED(NODE) \
+ TREE_LANG_FLAG_4 (FUNC_OR_METHOD_CHECK (NODE))
+
+/* 1 iff FUNCTION_TYPE or METHOD_TYPE has &&-ref-qualifier. */
+#define FUNCTION_RVALUE_QUALIFIED(NODE) \
+ TREE_LANG_FLAG_5 (FUNC_OR_METHOD_CHECK (NODE))
+
/* Returns 1 iff VAR_DECL is a construction virtual table.
DECL_VTABLE_OR_VTT_P will be true in this case and must be checked
before using this macro. */
@@ -4190,6 +4202,9 @@ enum tsubst_flags {
conversion might be permissible,
not actually performing the
conversion. */
+ tf_decltype = 1 << 7, /* We are the operand of decltype.
+ Used to implement the special rules
+ for calls in decltype (5.2.2/11). */
tf_partial = 1 << 8, /* Doing initial explicit argument
substitution in fn_type_unification. */
/* Convenient substitution flags combinations. */
@@ -4662,6 +4677,23 @@ enum virt_specifier
typedef int cp_virt_specifiers;
+/* Wherever there is a function-cv-qual, there could also be a ref-qualifier:
+
+ [dcl.fct]
+ The return type, the parameter-type-list, the ref-qualifier, and
+ the cv-qualifier-seq, but not the default arguments or the exception
+ specification, are part of the function type.
+
+ REF_QUAL_NONE Ordinary member function with no ref-qualifier
+ REF_QUAL_LVALUE Member function with the &-ref-qualifier
+ REF_QUAL_RVALUE Member function with the &&-ref-qualifier */
+
+enum cp_ref_qualifier {
+ REF_QUAL_NONE = 0,
+ REF_QUAL_LVALUE = 1,
+ REF_QUAL_RVALUE = 2
+};
+
/* A storage class. */
typedef enum cp_storage_class {
@@ -4823,6 +4855,8 @@ struct cp_declarator {
cp_cv_quals qualifiers;
/* The virt-specifiers for the function. */
cp_virt_specifiers virt_specifiers;
+ /* The ref-qualifier for the function. */
+ cp_ref_qualifier ref_qualifier;
/* The exception-specification for the function. */
tree exception_specification;
/* The late-specified return type, if any. */
@@ -5171,14 +5205,15 @@ extern tree cxx_maybe_build_cleanup (tree, tsubst_flags_t);
/* in decl2.c */
extern bool check_java_method (tree);
-extern tree build_memfn_type (tree, tree, cp_cv_quals);
+extern tree build_memfn_type (tree, tree, cp_cv_quals, cp_ref_qualifier);
+extern tree build_pointer_ptrmemfn_type (tree);
extern tree change_return_type (tree, tree);
extern void maybe_retrofit_in_chrg (tree);
extern void maybe_make_one_only (tree);
extern bool vague_linkage_p (tree);
extern void grokclassfn (tree, tree,
enum overload_flags);
-extern tree grok_array_decl (location_t, tree, tree);
+extern tree grok_array_decl (location_t, tree, tree, bool);
extern tree delete_sanity (tree, tree, bool, int, tsubst_flags_t);
extern tree check_classfn (tree, tree, tree);
extern void check_member_template (tree);
@@ -5282,7 +5317,8 @@ extern tree get_type_value (tree);
extern tree build_zero_init (tree, tree, bool);
extern tree build_value_init (tree, tsubst_flags_t);
extern tree build_value_init_noctor (tree, tsubst_flags_t);
-extern tree build_offset_ref (tree, tree, bool);
+extern tree build_offset_ref (tree, tree, bool,
+ tsubst_flags_t);
extern tree build_new (vec<tree, va_gc> **, tree, tree,
vec<tree, va_gc> **, int,
tsubst_flags_t);
@@ -5642,7 +5678,8 @@ extern tree finish_call_expr (tree, vec<tree, va_gc> **, bool,
extern tree finish_increment_expr (tree, enum tree_code);
extern tree finish_this_expr (void);
extern tree finish_pseudo_destructor_expr (tree, tree, tree);
-extern tree finish_unary_op_expr (location_t, enum tree_code, tree);
+extern tree finish_unary_op_expr (location_t, enum tree_code, tree,
+ tsubst_flags_t);
extern tree finish_compound_literal (tree, tree, tsubst_flags_t);
extern tree finish_fname (tree);
extern void finish_translation_unit (void);
@@ -5676,7 +5713,7 @@ extern void add_typedef_to_current_template_for_access_check (tree, tree,
location_t);
extern void check_accessibility_of_qualified_id (tree, tree, tree);
extern tree finish_qualified_id_expr (tree, tree, bool, bool,
- bool, bool);
+ bool, bool, tsubst_flags_t);
extern void simplify_aggr_init_expr (tree *);
extern void finalize_nrv (tree *, tree, tree);
extern void note_decl_for_pch (tree);
@@ -5777,6 +5814,7 @@ extern void diagnose_non_constexpr_vec_init (tree);
extern tree hash_tree_cons (tree, tree, tree);
extern tree hash_tree_chain (tree, tree);
extern tree build_qualified_name (tree, tree, tree, bool);
+extern tree build_ref_qualified_type (tree, cp_ref_qualifier);
extern int is_overloaded_fn (tree);
extern tree dependent_name (tree);
extern tree get_fns (tree);
@@ -5934,7 +5972,8 @@ extern tree build_ptrmemfunc (tree, tree, int, bool,
tsubst_flags_t);
extern int cp_type_quals (const_tree);
extern int type_memfn_quals (const_tree);
-extern tree apply_memfn_quals (tree, cp_cv_quals);
+extern cp_ref_qualifier type_memfn_rqual (const_tree);
+extern tree apply_memfn_quals (tree, cp_cv_quals, cp_ref_qualifier);
extern bool cp_has_mutable_p (const_tree);
extern bool at_least_as_qualified_p (const_tree, const_tree);
extern void cp_apply_type_quals_to_decl (int, tree);
diff --git a/gcc-4.8/gcc/cp/decl.c b/gcc-4.8/gcc/cp/decl.c
index 0e6684081..09296debe 100644
--- a/gcc-4.8/gcc/cp/decl.c
+++ b/gcc-4.8/gcc/cp/decl.c
@@ -1027,6 +1027,7 @@ decls_match (tree newdecl, tree olddecl)
else
types_match =
compparms (p1, p2)
+ && type_memfn_rqual (f1) == type_memfn_rqual (f2)
&& (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE
|| comp_type_attributes (TREE_TYPE (newdecl),
TREE_TYPE (olddecl)) != 0);
@@ -1756,12 +1757,16 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
}
- if (DECL_DELETED_FN (newdecl))
+ if (!(DECL_TEMPLATE_INSTANTIATION (olddecl)
+ && DECL_TEMPLATE_SPECIALIZATION (newdecl)))
{
- error ("deleted definition of %qD", newdecl);
- error ("after previous declaration %q+D", olddecl);
+ if (DECL_DELETED_FN (newdecl))
+ {
+ error ("deleted definition of %qD", newdecl);
+ error ("after previous declaration %q+D", olddecl);
+ }
+ DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
}
- DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
}
/* Deal with C++: must preserve virtual function table size. */
@@ -4760,7 +4765,7 @@ grok_reference_init (tree decl, tree type, tree init, int flags)
is valid, i.e., does not have a designated initializer. */
static bool
-check_array_designated_initializer (const constructor_elt *ce,
+check_array_designated_initializer (constructor_elt *ce,
unsigned HOST_WIDE_INT index)
{
/* Designated initializers for array elements are not supported. */
@@ -4769,9 +4774,21 @@ check_array_designated_initializer (const constructor_elt *ce,
/* The parser only allows identifiers as designated
initializers. */
if (ce->index == error_mark_node)
- error ("name used in a GNU-style designated "
- "initializer for an array");
- else if (TREE_CODE (ce->index) == INTEGER_CST)
+ {
+ error ("name used in a GNU-style designated "
+ "initializer for an array");
+ return false;
+ }
+ else if (TREE_CODE (ce->index) == IDENTIFIER_NODE)
+ {
+ error ("name %qD used in a GNU-style designated "
+ "initializer for an array", ce->index);
+ return false;
+ }
+
+ ce->index = cxx_constant_value (ce->index);
+
+ if (TREE_CODE (ce->index) == INTEGER_CST)
{
/* A C99 designator is OK if it matches the current index. */
if (TREE_INT_CST_LOW (ce->index) == index)
@@ -4780,11 +4797,8 @@ check_array_designated_initializer (const constructor_elt *ce,
sorry ("non-trivial designated initializers not supported");
}
else
- {
- gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
- error ("name %qD used in a GNU-style designated "
- "initializer for an array", ce->index);
- }
+ gcc_unreachable ();
+
return false;
}
@@ -5186,6 +5200,9 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
/* Handle designated initializers, as an extension. */
if (d->cur->index)
{
+ if (d->cur->index == error_mark_node)
+ return error_mark_node;
+
if (TREE_CODE (d->cur->index) == INTEGER_CST)
{
if (complain & tf_error)
@@ -6111,7 +6128,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
tree d_init;
if (init == NULL_TREE)
{
- if (DECL_TEMPLATE_INSTANTIATION (decl)
+ if (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_INSTANTIATION (decl)
&& !DECL_TEMPLATE_INSTANTIATED (decl))
{
/* init is null because we're deferring instantiating the
@@ -6133,6 +6151,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
auto_node);
if (type == error_mark_node)
return;
+ cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
}
if (!ensure_literal_type_for_constexpr_object (decl))
@@ -7317,6 +7336,7 @@ grokfndecl (tree ctype,
int virtualp,
enum overload_flags flags,
cp_cv_quals quals,
+ cp_ref_qualifier rqual,
tree raises,
int check,
int friendp,
@@ -7333,6 +7353,8 @@ grokfndecl (tree ctype,
int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
tree t;
+ if (rqual)
+ type = build_ref_qualified_type (type, rqual);
if (raises)
type = build_exception_variant (type, raises);
@@ -7536,13 +7558,25 @@ grokfndecl (tree ctype,
DECL_DECLARED_CONSTEXPR_P (decl) = true;
DECL_EXTERNAL (decl) = 1;
- if (quals && TREE_CODE (type) == FUNCTION_TYPE)
+ if (TREE_CODE (type) == FUNCTION_TYPE)
{
- error (ctype
- ? G_("static member function %qD cannot have cv-qualifier")
- : G_("non-member function %qD cannot have cv-qualifier"),
- decl);
- quals = TYPE_UNQUALIFIED;
+ if (quals)
+ {
+ error (ctype
+ ? G_("static member function %qD cannot have cv-qualifier")
+ : G_("non-member function %qD cannot have cv-qualifier"),
+ decl);
+ quals = TYPE_UNQUALIFIED;
+ }
+
+ if (rqual)
+ {
+ error (ctype
+ ? G_("static member function %qD cannot have ref-qualifier")
+ : G_("non-member function %qD cannot have ref-qualifier"),
+ decl);
+ rqual = REF_QUAL_NONE;
+ }
}
if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))
@@ -7980,7 +8014,8 @@ build_ptrmem_type (tree class_type, tree member_type)
if (TREE_CODE (member_type) == METHOD_TYPE)
{
cp_cv_quals quals = type_memfn_quals (member_type);
- member_type = build_memfn_type (member_type, class_type, quals);
+ cp_ref_qualifier rqual = type_memfn_rqual (member_type);
+ member_type = build_memfn_type (member_type, class_type, quals, rqual);
return build_ptrmemfunc_type (build_pointer_type (member_type));
}
else
@@ -8629,6 +8664,9 @@ grokdeclarator (const cp_declarator *declarator,
/* virt-specifiers that apply to the declarator, for a declaration of
a member function. */
cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
+ /* ref-qualifier that applies to the declarator, for a declaration of
+ a member function. */
+ cp_ref_qualifier rqual = REF_QUAL_NONE;
/* cv-qualifiers that apply to the type specified by the DECLSPECS. */
int type_quals;
tree raises = NULL_TREE;
@@ -9438,6 +9476,8 @@ grokdeclarator (const cp_declarator *declarator,
memfn_quals = declarator->u.function.qualifiers;
/* Pick up virt-specifiers. */
virt_specifiers = declarator->u.function.virt_specifiers;
+ /* And ref-qualifier, too */
+ rqual = declarator->u.function.ref_qualifier;
/* Pick up the exception specifications. */
raises = declarator->u.function.exception_specification;
/* If the exception-specification is ill-formed, let's pretend
@@ -9505,12 +9545,13 @@ grokdeclarator (const cp_declarator *declarator,
therefore returns a void type. */
/* ISO C++ 12.4/2. A destructor may not be declared
- const or volatile. A destructor may not be
- static.
+ const or volatile. A destructor may not be static.
+ A destructor may not be declared with ref-qualifier.
ISO C++ 12.1. A constructor may not be declared
const or volatile. A constructor may not be
- virtual. A constructor may not be static. */
+ virtual. A constructor may not be static.
+ A constructor may not be declared with ref-qualifier. */
if (staticp == 2)
error ((flags == DTOR_FLAG)
? G_("destructor cannot be static member function")
@@ -9523,6 +9564,15 @@ grokdeclarator (const cp_declarator *declarator,
memfn_quals = TYPE_UNQUALIFIED;
}
+ if (rqual)
+ {
+ maybe_warn_cpp0x (CPP0X_REF_QUALIFIER);
+ error ((flags == DTOR_FLAG)
+ ? "destructors may not be ref-qualified"
+ : "constructors may not be ref-qualified");
+ rqual = REF_QUAL_NONE;
+ }
+
if (decl_context == FIELD
&& !member_function_or_else (ctype,
current_class_type,
@@ -9642,14 +9692,18 @@ grokdeclarator (const cp_declarator *declarator,
memfn_quals |= type_memfn_quals (type);
type = build_memfn_type (type,
declarator->u.pointer.class_type,
- memfn_quals);
+ memfn_quals,
+ rqual);
if (type == error_mark_node)
return error_mark_node;
+
+ rqual = REF_QUAL_NONE;
memfn_quals = TYPE_UNQUALIFIED;
}
if (TREE_CODE (type) == FUNCTION_TYPE
- && type_memfn_quals (type) != TYPE_UNQUALIFIED)
+ && (type_memfn_quals (type) != TYPE_UNQUALIFIED
+ || type_memfn_rqual (type) != REF_QUAL_NONE))
error (declarator->kind == cdk_reference
? G_("cannot declare reference to qualified function type %qT")
: G_("cannot declare pointer to qualified function type %qT"),
@@ -9996,12 +10050,13 @@ grokdeclarator (const cp_declarator *declarator,
example "f S::*" declares a pointer to a const-qualified
member function of S. We record the cv-qualification in the
function type. */
- if (memfn_quals && TREE_CODE (type) == FUNCTION_TYPE)
+ if ((rqual || memfn_quals) && TREE_CODE (type) == FUNCTION_TYPE)
{
- type = apply_memfn_quals (type, memfn_quals);
+ type = apply_memfn_quals (type, memfn_quals, rqual);
/* We have now dealt with these qualifiers. */
memfn_quals = TYPE_UNQUALIFIED;
+ rqual = REF_QUAL_NONE;
}
if (type_uses_auto (type))
@@ -10131,8 +10186,10 @@ grokdeclarator (const cp_declarator *declarator,
if (decl_context != TYPENAME)
{
/* A cv-qualifier-seq shall only be part of the function type
- for a non-static member function. [8.3.5/4 dcl.fct] */
- if (type_memfn_quals (type) != TYPE_UNQUALIFIED
+ for a non-static member function. A ref-qualifier shall only
+ .... /same as above/ [dcl.fct] */
+ if ((type_memfn_quals (type) != TYPE_UNQUALIFIED
+ || type_memfn_rqual (type) != REF_QUAL_NONE)
&& (current_class_type == NULL_TREE || staticp) )
{
error (staticp
@@ -10146,6 +10203,7 @@ grokdeclarator (const cp_declarator *declarator,
/* The qualifiers on the function type become the qualifiers on
the non-static member function. */
memfn_quals |= type_memfn_quals (type);
+ rqual = type_memfn_rqual (type);
type_quals = TYPE_UNQUALIFIED;
}
}
@@ -10203,17 +10261,19 @@ grokdeclarator (const cp_declarator *declarator,
type = void_type_node;
}
}
- else if (memfn_quals)
+ else if (memfn_quals || rqual)
{
if (ctype == NULL_TREE
&& TREE_CODE (type) == METHOD_TYPE)
ctype = TYPE_METHOD_BASETYPE (type);
if (ctype)
- type = build_memfn_type (type, ctype, memfn_quals);
- /* Core issue #547: need to allow this in template type args. */
- else if (template_type_arg && TREE_CODE (type) == FUNCTION_TYPE)
- type = apply_memfn_quals (type, memfn_quals);
+ type = build_memfn_type (type, ctype, memfn_quals, rqual);
+ /* Core issue #547: need to allow this in template type args.
+ Allow it in general in C++11 for alias-declarations. */
+ else if ((template_type_arg || cxx_dialect >= cxx11)
+ && TREE_CODE (type) == FUNCTION_TYPE)
+ type = apply_memfn_quals (type, memfn_quals, rqual);
else
error ("invalid qualifiers on non-member function type");
}
@@ -10282,7 +10342,7 @@ grokdeclarator (const cp_declarator *declarator,
cp_cv_quals real_quals = memfn_quals;
if (constexpr_p && sfk != sfk_constructor && sfk != sfk_destructor)
real_quals |= TYPE_QUAL_CONST;
- type = build_memfn_type (type, ctype, real_quals);
+ type = build_memfn_type (type, ctype, real_quals, rqual);
}
{
@@ -10414,7 +10474,7 @@ grokdeclarator (const cp_declarator *declarator,
? unqualified_id : dname,
parms,
unqualified_id,
- virtualp, flags, memfn_quals, raises,
+ virtualp, flags, memfn_quals, rqual, raises,
friendp ? -1 : 0, friendp, publicp,
inlinep | (2 * constexpr_p),
sfk,
@@ -10635,7 +10695,7 @@ grokdeclarator (const cp_declarator *declarator,
|| storage_class != sc_static);
decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
- virtualp, flags, memfn_quals, raises,
+ virtualp, flags, memfn_quals, rqual, raises,
1, friendp,
publicp, inlinep | (2 * constexpr_p), sfk,
funcdef_flag,
@@ -11892,11 +11952,12 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
static tree
xref_tag_1 (enum tag_types tag_code, tree name,
- tag_scope scope, bool template_header_p)
+ tag_scope orig_scope, bool template_header_p)
{
enum tree_code code;
tree t;
tree context = NULL_TREE;
+ tag_scope scope;
gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
@@ -11916,6 +11977,11 @@ xref_tag_1 (enum tag_types tag_code, tree name,
gcc_unreachable ();
}
+ if (orig_scope == ts_lambda)
+ scope = ts_current;
+ else
+ scope = orig_scope;
+
/* In case of anonymous name, xref_tag is only called to
make type node and push name. Name lookup is not required. */
if (ANON_AGGRNAME_P (name))
@@ -11989,6 +12055,10 @@ xref_tag_1 (enum tag_types tag_code, tree name,
{
t = make_class_type (code);
TYPE_CONTEXT (t) = context;
+ if (orig_scope == ts_lambda)
+ /* Remember that we're declaring a lambda to avoid bogus errors
+ in push_template_decl. */
+ CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
t = pushtag (name, t, scope);
}
}
@@ -14181,8 +14251,9 @@ static_fn_type (tree memfntype)
return memfntype;
gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE);
args = TYPE_ARG_TYPES (memfntype);
+ cp_ref_qualifier rqual = type_memfn_rqual (memfntype);
fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args));
- fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype));
+ fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype), rqual);
fntype = (cp_build_type_attribute_variant
(fntype, TYPE_ATTRIBUTES (memfntype)));
fntype = (build_exception_variant
@@ -14198,9 +14269,10 @@ revert_static_member_fn (tree decl)
{
tree stype = static_fn_type (decl);
cp_cv_quals quals = type_memfn_quals (stype);
+ cp_ref_qualifier rqual = type_memfn_rqual (stype);
- if (quals != TYPE_UNQUALIFIED)
- stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
+ if (quals != TYPE_UNQUALIFIED || rqual != REF_QUAL_NONE)
+ stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED, REF_QUAL_NONE);
TREE_TYPE (decl) = stype;
diff --git a/gcc-4.8/gcc/cp/decl2.c b/gcc-4.8/gcc/cp/decl2.c
index 82bc6f79e..628be934b 100644
--- a/gcc-4.8/gcc/cp/decl2.c
+++ b/gcc-4.8/gcc/cp/decl2.c
@@ -109,7 +109,8 @@ int at_eof;
that apply to the function). */
tree
-build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
+build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals,
+ cp_ref_qualifier rqual)
{
tree raises;
tree attrs;
@@ -129,10 +130,12 @@ build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
(TREE_CODE (fntype) == METHOD_TYPE
? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
: TYPE_ARG_TYPES (fntype)));
- if (raises)
- fntype = build_exception_variant (fntype, raises);
if (attrs)
fntype = cp_build_type_attribute_variant (fntype, attrs);
+ if (rqual)
+ fntype = build_ref_qualified_type (fntype, rqual);
+ if (raises)
+ fntype = build_exception_variant (fntype, raises);
return fntype;
}
@@ -157,7 +160,9 @@ change_return_type (tree new_ret, tree fntype)
if (TREE_CODE (fntype) == FUNCTION_TYPE)
{
newtype = build_function_type (new_ret, args);
- newtype = apply_memfn_quals (newtype, type_memfn_quals (fntype));
+ newtype = apply_memfn_quals (newtype,
+ type_memfn_quals (fntype),
+ type_memfn_rqual (fntype));
}
else
newtype = build_method_type_directly
@@ -330,10 +335,11 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags)
}
/* Create an ARRAY_REF, checking for the user doing things backwards
- along the way. */
+ along the way. DECLTYPE_P is for N3276, as in the parser. */
tree
-grok_array_decl (location_t loc, tree array_expr, tree index_exp)
+grok_array_decl (location_t loc, tree array_expr, tree index_exp,
+ bool decltype_p)
{
tree type;
tree expr;
@@ -359,8 +365,13 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp)
/* If they have an `operator[]', use that. */
if (MAYBE_CLASS_TYPE_P (type) || MAYBE_CLASS_TYPE_P (TREE_TYPE (index_exp)))
- expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, array_expr, index_exp,
- NULL_TREE, /*overload=*/NULL, tf_warning_or_error);
+ {
+ tsubst_flags_t complain = tf_warning_or_error;
+ if (decltype_p)
+ complain |= tf_decltype;
+ expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, array_expr,
+ index_exp, NULL_TREE, /*overload=*/NULL, complain);
+ }
else
{
tree p1, p2, i1, i2;
@@ -672,6 +683,11 @@ check_classfn (tree ctype, tree function, tree template_parms)
if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL))
continue;
+ /* ref-qualifier or absence of same must match. */
+ if (type_memfn_rqual (TREE_TYPE (function))
+ != type_memfn_rqual (TREE_TYPE (fndecl)))
+ continue;
+
/* While finding a match, same types and params are not enough
if the function is versioned. Also check version ("target")
attributes. */
@@ -1261,7 +1277,9 @@ cp_reconstruct_complex_type (tree type, tree bottom)
{
inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
outer = build_function_type (inner, TYPE_ARG_TYPES (type));
- outer = apply_memfn_quals (outer, type_memfn_quals (type));
+ outer = apply_memfn_quals (outer,
+ type_memfn_quals (type),
+ type_memfn_rqual (type));
}
else if (TREE_CODE (type) == METHOD_TYPE)
{
@@ -2195,9 +2213,6 @@ determine_visibility (tree decl)
&& !lookup_attribute ("visibility", attribs))
{
int depth = TMPL_ARGS_DEPTH (args);
- int class_depth = 0;
- if (class_type && CLASSTYPE_TEMPLATE_INFO (class_type))
- class_depth = TMPL_ARGS_DEPTH (CLASSTYPE_TI_ARGS (class_type));
if (DECL_VISIBILITY_SPECIFIED (decl))
{
/* A class template member with explicit visibility
@@ -2210,7 +2225,7 @@ determine_visibility (tree decl)
constrain_visibility_for_template (decl, lev);
}
}
- else if (depth > class_depth)
+ else if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)))
/* Limit visibility based on its template arguments. */
constrain_visibility_for_template (decl, args);
}
diff --git a/gcc-4.8/gcc/cp/error.c b/gcc-4.8/gcc/cp/error.c
index c2bf54dcb..35ea0dfe7 100644
--- a/gcc-4.8/gcc/cp/error.c
+++ b/gcc-4.8/gcc/cp/error.c
@@ -78,6 +78,7 @@ static void dump_aggr_init_expr_args (tree, int, bool);
static void dump_expr_list (tree, int);
static void dump_global_iord (tree);
static void dump_parameters (tree, int);
+static void dump_ref_qualifier (tree, int);
static void dump_exception_spec (tree, int);
static void dump_template_argument (tree, int);
static void dump_template_argument_list (tree, int);
@@ -832,6 +833,7 @@ dump_type_suffix (tree t, int flags)
pp_cxx_cv_qualifier_seq (cxx_pp, class_of_this_parm (t));
else
pp_cxx_cv_qualifier_seq (cxx_pp, t);
+ dump_ref_qualifier (t, flags);
dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
dump_type_suffix (TREE_TYPE (t), flags);
break;
@@ -1426,6 +1428,7 @@ dump_function_decl (tree t, int flags)
{
pp_base (cxx_pp)->padding = pp_before;
pp_cxx_cv_qualifier_seq (cxx_pp, class_of_this_parm (fntype));
+ dump_ref_qualifier (fntype, flags);
}
if (flags & TFF_EXCEPTION_SPECIFICATION)
@@ -1507,6 +1510,21 @@ dump_parameters (tree parmtypes, int flags)
pp_cxx_right_paren (cxx_pp);
}
+/* Print ref-qualifier of a FUNCTION_TYPE or METHOD_TYPE. FLAGS are ignored. */
+
+static void
+dump_ref_qualifier (tree t, int flags ATTRIBUTE_UNUSED)
+{
+ if (FUNCTION_REF_QUALIFIED (t))
+ {
+ pp_base (cxx_pp)->padding = pp_before;
+ if (FUNCTION_RVALUE_QUALIFIED (t))
+ pp_cxx_ws_string (cxx_pp, "&&");
+ else
+ pp_cxx_ws_string (cxx_pp, "&");
+ }
+}
+
/* Print an exception specification. T is the exception specification. */
static void
@@ -3348,7 +3366,7 @@ maybe_warn_cpp0x (cpp0x_warn_str str)
break;
case CPP0X_AUTO:
pedwarn (input_location, 0,
- "C++0x auto only available with -std=c++11 or -std=gnu++11");
+ "C++11 auto only available with -std=c++11 or -std=gnu++11");
break;
case CPP0X_SCOPED_ENUMS:
pedwarn (input_location, 0,
@@ -3394,6 +3412,11 @@ maybe_warn_cpp0x (cpp0x_warn_str str)
"c++11 attributes "
"only available with -std=c++11 or -std=gnu++11");
break;
+ case CPP0X_REF_QUALIFIER:
+ pedwarn (input_location, 0,
+ "ref-qualifiers "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
default:
gcc_unreachable ();
}
diff --git a/gcc-4.8/gcc/cp/init.c b/gcc-4.8/gcc/cp/init.c
index 697f11ff5..a0efbbce4 100644
--- a/gcc-4.8/gcc/cp/init.c
+++ b/gcc-4.8/gcc/cp/init.c
@@ -634,7 +634,12 @@ perform_member_init (tree member, tree init)
init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
tf_warning_or_error);
if (TREE_TYPE (init) != type)
- init = digest_init (type, init, tf_warning_or_error);
+ {
+ if (BRACE_ENCLOSED_INITIALIZER_P (init)
+ && CP_AGGREGATE_TYPE_P (type))
+ init = reshape_init (type, init, tf_warning_or_error);
+ init = digest_init (type, init, tf_warning_or_error);
+ }
if (init == error_mark_node)
return;
/* A FIELD_DECL doesn't really have a suitable lifetime, but
@@ -1817,7 +1822,8 @@ get_type_value (tree name)
@@ This function should be rewritten and placed in search.c. */
tree
-build_offset_ref (tree type, tree member, bool address_p)
+build_offset_ref (tree type, tree member, bool address_p,
+ tsubst_flags_t complain)
{
tree decl;
tree basebinfo = NULL_TREE;
@@ -1841,7 +1847,8 @@ build_offset_ref (tree type, tree member, bool address_p)
type = TYPE_MAIN_VARIANT (type);
if (!COMPLETE_OR_OPEN_TYPE_P (complete_type (type)))
{
- error ("incomplete type %qT does not have member %qD", type, member);
+ if (complain & tf_error)
+ error ("incomplete type %qT does not have member %qD", type, member);
return error_mark_node;
}
@@ -1854,7 +1861,8 @@ build_offset_ref (tree type, tree member, bool address_p)
if (TREE_CODE (member) == FIELD_DECL && DECL_C_BIT_FIELD (member))
{
- error ("invalid pointer to bit-field %qD", member);
+ if (complain & tf_error)
+ error ("invalid pointer to bit-field %qD", member);
return error_mark_node;
}
@@ -1883,10 +1891,10 @@ build_offset_ref (tree type, tree member, bool address_p)
if (address_p && DECL_P (t)
&& DECL_NONSTATIC_MEMBER_P (t))
perform_or_defer_access_check (TYPE_BINFO (type), t, t,
- tf_warning_or_error);
+ complain);
else
perform_or_defer_access_check (basebinfo, t, t,
- tf_warning_or_error);
+ complain);
if (DECL_STATIC_FUNCTION_P (t))
return t;
@@ -1900,7 +1908,7 @@ build_offset_ref (tree type, tree member, bool address_p)
check_accessibility_of_qualified_id in case it is
a pointer to non-static member. */
perform_or_defer_access_check (TYPE_BINFO (type), member, member,
- tf_warning_or_error);
+ complain);
if (!address_p)
{
@@ -1932,15 +1940,17 @@ build_offset_ref (tree type, tree member, bool address_p)
if (flag_ms_extensions)
{
PTRMEM_OK_P (member) = 1;
- return cp_build_addr_expr (member, tf_warning_or_error);
+ return cp_build_addr_expr (member, complain);
}
- error ("invalid use of non-static member function %qD",
- TREE_OPERAND (member, 1));
+ if (complain & tf_error)
+ error ("invalid use of non-static member function %qD",
+ TREE_OPERAND (member, 1));
return error_mark_node;
}
else if (TREE_CODE (member) == FIELD_DECL)
{
- error ("invalid use of non-static data member %qD", member);
+ if (complain & tf_error)
+ error ("invalid use of non-static data member %qD", member);
return error_mark_node;
}
return member;
@@ -2920,6 +2930,7 @@ build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
if (dependent_type_p (type)
|| any_type_dependent_arguments_p (*placement)
|| (nelts && type_dependent_expression_p (nelts))
+ || (nelts && *init)
|| any_type_dependent_arguments_p (*init))
return build_raw_new_expr (*placement, type, nelts, *init,
use_global_new);
diff --git a/gcc-4.8/gcc/cp/mangle.c b/gcc-4.8/gcc/cp/mangle.c
index da464606b..dd5ed8d0d 100644
--- a/gcc-4.8/gcc/cp/mangle.c
+++ b/gcc-4.8/gcc/cp/mangle.c
@@ -350,6 +350,7 @@ canonicalize_for_substitution (tree node)
&& TYPE_CANONICAL (node) != node
&& TYPE_MAIN_VARIANT (node) != node)
{
+ tree orig = node;
/* Here we want to strip the topmost typedef only.
We need to do that so is_std_substitution can do proper
name matching. */
@@ -361,6 +362,9 @@ canonicalize_for_substitution (tree node)
else
node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node),
cp_type_quals (node));
+ if (TREE_CODE (node) == FUNCTION_TYPE
+ || TREE_CODE (node) == METHOD_TYPE)
+ node = build_ref_qualified_type (node, type_memfn_rqual (orig));
}
return node;
}
@@ -906,9 +910,11 @@ write_unscoped_template_name (const tree decl)
/* Write the nested name, including CV-qualifiers, of DECL.
- <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
- ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
+ <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
+ ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
+ <ref-qualifier> ::= R # & ref-qualifier
+ ::= O # && ref-qualifier
<CV-qualifiers> ::= [r] [V] [K] */
static void
@@ -928,6 +934,13 @@ write_nested_name (const tree decl)
write_char ('V');
if (DECL_CONST_MEMFUNC_P (decl))
write_char ('K');
+ if (FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)))
+ {
+ if (FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl)))
+ write_char ('O');
+ else
+ write_char ('R');
+ }
}
/* Is this a template instance? */
@@ -1882,7 +1895,13 @@ write_type (tree type)
mangle the unqualified type. The recursive call is needed here
since both the qualified and unqualified types are substitution
candidates. */
- write_type (TYPE_MAIN_VARIANT (type));
+ {
+ tree t = TYPE_MAIN_VARIANT (type);
+ if (TREE_CODE (t) == FUNCTION_TYPE
+ || TREE_CODE (t) == METHOD_TYPE)
+ t = build_ref_qualified_type (t, type_memfn_rqual (type));
+ write_type (t);
+ }
else if (TREE_CODE (type) == ARRAY_TYPE)
/* It is important not to use the TYPE_MAIN_VARIANT of TYPE here
so that the cv-qualification of the element type is available
@@ -1894,6 +1913,9 @@ write_type (tree type)
/* See through any typedefs. */
type = TYPE_MAIN_VARIANT (type);
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ type = build_ref_qualified_type (type, type_memfn_rqual (type_orig));
/* According to the C++ ABI, some library classes are passed the
same as the scalar type of their single member and use the same
@@ -2329,7 +2351,7 @@ write_builtin_type (tree type)
METHOD_TYPE. The return type is mangled before the parameter
types.
- <function-type> ::= F [Y] <bare-function-type> E */
+ <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E */
static void
write_function_type (const tree type)
@@ -2362,6 +2384,13 @@ write_function_type (const tree type)
See [dcl.link]. */
write_bare_function_type (type, /*include_return_type_p=*/1,
/*decl=*/NULL);
+ if (FUNCTION_REF_QUALIFIED (type))
+ {
+ if (FUNCTION_RVALUE_QUALIFIED (type))
+ write_char ('O');
+ else
+ write_char ('R');
+ }
write_char ('E');
}
diff --git a/gcc-4.8/gcc/cp/name-lookup.h b/gcc-4.8/gcc/cp/name-lookup.h
index f9a0fbe4d..b88ada37c 100644
--- a/gcc-4.8/gcc/cp/name-lookup.h
+++ b/gcc-4.8/gcc/cp/name-lookup.h
@@ -132,10 +132,11 @@ typedef enum tag_scope {
ts_global = 1, /* All scopes. This is the 3.4.1
[basic.lookup.unqual] lookup mentioned
in [basic.lookup.elab]/2. */
- ts_within_enclosing_non_class = 2 /* Search within enclosing non-class
+ ts_within_enclosing_non_class = 2, /* Search within enclosing non-class
only, for friend class lookup
according to [namespace.memdef]/3
and [class.friend]/9. */
+ ts_lambda = 3 /* Declaring a lambda closure. */
} tag_scope;
typedef struct GTY(()) cp_class_binding {
diff --git a/gcc-4.8/gcc/cp/parser.c b/gcc-4.8/gcc/cp/parser.c
index ff4faa32d..50b3e2239 100644
--- a/gcc-4.8/gcc/cp/parser.c
+++ b/gcc-4.8/gcc/cp/parser.c
@@ -1188,7 +1188,7 @@ clear_decl_specs (cp_decl_specifier_seq *decl_specs)
VAR_DECLs or FUNCTION_DECLs) should do that directly. */
static cp_declarator *make_call_declarator
- (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, tree, tree);
+ (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier, tree, tree);
static cp_declarator *make_array_declarator
(cp_declarator *, tree);
static cp_declarator *make_pointer_declarator
@@ -1367,6 +1367,7 @@ make_call_declarator (cp_declarator *target,
tree parms,
cp_cv_quals cv_qualifiers,
cp_virt_specifiers virt_specifiers,
+ cp_ref_qualifier ref_qualifier,
tree exception_specification,
tree late_return_type)
{
@@ -1377,6 +1378,7 @@ make_call_declarator (cp_declarator *target,
declarator->u.function.parameters = parms;
declarator->u.function.qualifiers = cv_qualifiers;
declarator->u.function.virt_specifiers = virt_specifiers;
+ declarator->u.function.ref_qualifier = ref_qualifier;
declarator->u.function.exception_specification = exception_specification;
declarator->u.function.late_return_type = late_return_type;
if (target)
@@ -1802,9 +1804,9 @@ static tree cp_parser_nested_name_specifier
static tree cp_parser_qualifying_entity
(cp_parser *, bool, bool, bool, bool, bool);
static tree cp_parser_postfix_expression
- (cp_parser *, bool, bool, bool, cp_id_kind *);
+ (cp_parser *, bool, bool, bool, bool, cp_id_kind *);
static tree cp_parser_postfix_open_square_expression
- (cp_parser *, tree, bool);
+ (cp_parser *, tree, bool, bool);
static tree cp_parser_postfix_dot_deref_expression
(cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
static vec<tree, va_gc> *cp_parser_parenthesized_expression_list
@@ -1832,7 +1834,7 @@ static vec<tree, va_gc> *cp_parser_new_initializer
static tree cp_parser_delete_expression
(cp_parser *);
static tree cp_parser_cast_expression
- (cp_parser *, bool, bool, cp_id_kind *);
+ (cp_parser *, bool, bool, bool, cp_id_kind *);
static tree cp_parser_binary_expression
(cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *);
static tree cp_parser_question_colon_clause
@@ -1843,6 +1845,8 @@ static enum tree_code cp_parser_assignment_operator_opt
(cp_parser *);
static tree cp_parser_expression
(cp_parser *, bool, cp_id_kind *);
+static tree cp_parser_expression
+ (cp_parser *, bool, bool, cp_id_kind *);
static tree cp_parser_constant_expression
(cp_parser *, bool, bool *);
static tree cp_parser_builtin_offsetof
@@ -1970,6 +1974,8 @@ static cp_cv_quals cp_parser_cv_qualifier_seq_opt
(cp_parser *);
static cp_virt_specifiers cp_parser_virt_specifier_seq_opt
(cp_parser *);
+static cp_ref_qualifier cp_parser_ref_qualifier_seq_opt
+ (cp_parser *);
static tree cp_parser_late_return_type_opt
(cp_parser *, cp_cv_quals);
static tree cp_parser_declarator_id
@@ -3840,6 +3846,18 @@ cp_parser_translation_unit (cp_parser* parser)
return success;
}
+/* Return the appropriate tsubst flags for parsing, possibly in N3276
+ decltype context. */
+
+static inline tsubst_flags_t
+complain_flags (bool decltype_p)
+{
+ tsubst_flags_t complain = tf_warning_or_error;
+ if (decltype_p)
+ complain |= tf_decltype;
+ return complain;
+}
+
/* Expressions [gram.expr] */
/* Parse a primary-expression.
@@ -3901,6 +3919,7 @@ cp_parser_primary_expression (cp_parser *parser,
bool address_p,
bool cast_p,
bool template_arg_p,
+ bool decltype_p,
cp_id_kind *idk)
{
cp_token *token = NULL;
@@ -4052,7 +4071,7 @@ cp_parser_primary_expression (cp_parser *parser,
else
{
/* Parse the parenthesized expression. */
- expr = cp_parser_expression (parser, cast_p, idk);
+ expr = cp_parser_expression (parser, cast_p, decltype_p, idk);
/* Let the front end know that this expression was
enclosed in parentheses. This matters in case, for
example, the expression is of the form `A::B', since
@@ -4404,6 +4423,17 @@ cp_parser_primary_expression (cp_parser *parser,
}
}
+static inline tree
+cp_parser_primary_expression (cp_parser *parser,
+ bool address_p,
+ bool cast_p,
+ bool template_arg_p,
+ cp_id_kind *idk)
+{
+ return cp_parser_primary_expression (parser, address_p, cast_p, template_arg_p,
+ /*decltype*/false, idk);
+}
+
/* Parse an id-expression.
id-expression:
@@ -5365,7 +5395,7 @@ cp_parser_qualifying_entity (cp_parser *parser,
static tree
cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
- bool member_access_only_p,
+ bool member_access_only_p, bool decltype_p,
cp_id_kind * pidk_return)
{
cp_token *token;
@@ -5626,11 +5656,17 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
postfix_expression
= cp_parser_primary_expression (parser, address_p, cast_p,
/*template_arg_p=*/false,
+ decltype_p,
&idk);
}
break;
}
+ /* Note that we don't need to worry about calling build_cplus_new on a
+ class-valued CALL_EXPR in decltype when it isn't the end of the
+ postfix-expression; unary_complex_lvalue will take care of that for
+ all these cases. */
+
/* Keep looping until the postfix-expression is complete. */
while (true)
{
@@ -5657,7 +5693,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
postfix_expression
= cp_parser_postfix_open_square_expression (parser,
postfix_expression,
- false);
+ false,
+ decltype_p);
idk = CP_ID_KIND_NONE;
is_member_access = false;
break;
@@ -5669,6 +5706,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
bool is_builtin_constant_p;
bool saved_integral_constant_expression_p = false;
bool saved_non_integral_constant_expression_p = false;
+ tsubst_flags_t complain = complain_flags (decltype_p);
vec<tree, va_gc> *args;
is_member_access = false;
@@ -5727,7 +5765,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
postfix_expression
= perform_koenig_lookup (postfix_expression, args,
/*include_std=*/false,
- tf_warning_or_error);
+ complain);
}
else
postfix_expression
@@ -5753,7 +5791,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
postfix_expression
= perform_koenig_lookup (postfix_expression, args,
/*include_std=*/false,
- tf_warning_or_error);
+ complain);
}
}
}
@@ -5785,21 +5823,21 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
: LOOKUP_NORMAL),
/*fn_p=*/NULL,
- tf_warning_or_error));
+ complain));
}
else
postfix_expression
= finish_call_expr (postfix_expression, &args,
/*disallow_virtual=*/false,
/*koenig_p=*/false,
- tf_warning_or_error);
+ complain);
}
else if (TREE_CODE (postfix_expression) == OFFSET_REF
|| TREE_CODE (postfix_expression) == MEMBER_REF
|| TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
postfix_expression = (build_offset_ref_call_from_tree
(postfix_expression, &args,
- tf_warning_or_error));
+ complain));
else if (idk == CP_ID_KIND_QUALIFIED)
/* A call to a static class member, or a namespace-scope
function. */
@@ -5807,14 +5845,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
= finish_call_expr (postfix_expression, &args,
/*disallow_virtual=*/true,
koenig_p,
- tf_warning_or_error);
+ complain);
else
/* All other function calls. */
postfix_expression
= finish_call_expr (postfix_expression, &args,
/*disallow_virtual=*/false,
koenig_p,
- tf_warning_or_error);
+ complain);
/* The POSTFIX_EXPRESSION is certainly no longer an id. */
idk = CP_ID_KIND_NONE;
@@ -5899,7 +5937,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
static tree
cp_parser_postfix_open_square_expression (cp_parser *parser,
tree postfix_expression,
- bool for_offsetof)
+ bool for_offsetof,
+ bool decltype_p)
{
tree index;
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
@@ -5933,7 +5972,8 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
/* Build the ARRAY_REF. */
- postfix_expression = grok_array_decl (loc, postfix_expression, index);
+ postfix_expression = grok_array_decl (loc, postfix_expression,
+ index, decltype_p);
/* When not doing offsetof, array references are not permitted in
constant-expressions. */
@@ -6415,7 +6455,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
static tree
cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
- cp_id_kind * pidk)
+ bool decltype_p, cp_id_kind * pidk)
{
cp_token *token;
enum tree_code unary_operator;
@@ -6629,6 +6669,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
tree expression = error_mark_node;
non_integral_constant non_constant_p = NIC_NONE;
location_t loc = token->location;
+ tsubst_flags_t complain = complain_flags (decltype_p);
/* Consume the operator token. */
token = cp_lexer_consume_token (parser->lexer);
@@ -6636,7 +6677,9 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
cast_expression
= cp_parser_cast_expression (parser,
unary_operator == ADDR_EXPR,
- /*cast_p=*/false, pidk);
+ /*cast_p=*/false,
+ /*decltype*/false,
+ pidk);
/* Now, build an appropriate representation. */
switch (unary_operator)
{
@@ -6644,7 +6687,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
non_constant_p = NIC_STAR;
expression = build_x_indirect_ref (loc, cast_expression,
RO_UNARY_STAR,
- tf_warning_or_error);
+ complain);
break;
case ADDR_EXPR:
@@ -6653,7 +6696,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
case BIT_NOT_EXPR:
expression = build_x_unary_op (loc, unary_operator,
cast_expression,
- tf_warning_or_error);
+ complain);
break;
case PREINCREMENT_EXPR:
@@ -6665,7 +6708,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
case NEGATE_EXPR:
case TRUTH_NOT_EXPR:
expression = finish_unary_op_expr (loc, unary_operator,
- cast_expression);
+ cast_expression, complain);
break;
default:
@@ -6682,9 +6725,18 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
return cp_parser_postfix_expression (parser, address_p, cast_p,
/*member_access_only_p=*/false,
+ decltype_p,
pidk);
}
+static inline tree
+cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
+ cp_id_kind * pidk)
+{
+ return cp_parser_unary_expression (parser, address_p, cast_p,
+ /*decltype*/false, pidk);
+}
+
/* Returns ERROR_MARK if TOKEN is not a unary-operator. If TOKEN is a
unary-operator, the corresponding tree code is returned. */
@@ -7163,7 +7215,7 @@ cp_parser_tokens_start_cast_expression (cp_parser *parser)
static tree
cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
- cp_id_kind * pidk)
+ bool decltype_p, cp_id_kind * pidk)
{
/* If it's a `(', then we might be looking at a cast. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
@@ -7237,7 +7289,9 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
cp_parser_parse_definitely (parser);
expr = cp_parser_cast_expression (parser,
/*address_p=*/false,
- /*cast_p=*/true, pidk);
+ /*cast_p=*/true,
+ /*decltype_p=*/false,
+ pidk);
/* Warn about old-style casts, if so requested. */
if (warn_old_style_cast
@@ -7263,7 +7317,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
/* If we get here, then it's not a cast, so it must be a
unary-expression. */
- return cp_parser_unary_expression (parser, address_p, cast_p, pidk);
+ return cp_parser_unary_expression (parser, address_p, cast_p,
+ decltype_p, pidk);
}
/* Parse a binary expression of the general form:
@@ -7348,6 +7403,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
static tree
cp_parser_binary_expression (cp_parser* parser, bool cast_p,
bool no_toplevel_fold_p,
+ bool decltype_p,
enum cp_parser_prec prec,
cp_id_kind * pidk)
{
@@ -7362,7 +7418,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
/* Parse the first expression. */
current.lhs = cp_parser_cast_expression (parser, /*address_p=*/false,
- cast_p, pidk);
+ cast_p, decltype_p, pidk);
current.lhs_type = ERROR_MARK;
current.prec = prec;
@@ -7479,7 +7535,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
current.lhs = build_x_binary_op (current.loc, current.tree_type,
current.lhs, current.lhs_type,
rhs, rhs_type, &overload,
- tf_warning_or_error);
+ complain_flags (decltype_p));
current.lhs_type = current.tree_type;
if (EXPR_P (current.lhs))
SET_EXPR_LOCATION (current.lhs, current.loc);
@@ -7499,6 +7555,15 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
return current.lhs;
}
+static tree
+cp_parser_binary_expression (cp_parser* parser, bool cast_p,
+ bool no_toplevel_fold_p,
+ enum cp_parser_prec prec,
+ cp_id_kind * pidk)
+{
+ return cp_parser_binary_expression (parser, cast_p, no_toplevel_fold_p,
+ /*decltype*/false, prec, pidk);
+}
/* Parse the `? expression : assignment-expression' part of a
conditional-expression. The LOGICAL_OR_EXPR is the
@@ -7568,12 +7633,13 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
throw-expression
CAST_P is true if this expression is the target of a cast.
+ DECLTYPE_P is true if this expression is the operand of decltype.
Returns a representation for the expression. */
static tree
cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
- cp_id_kind * pidk)
+ bool decltype_p, cp_id_kind * pidk)
{
tree expr;
@@ -7587,6 +7653,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
{
/* Parse the binary expressions (logical-or-expression). */
expr = cp_parser_binary_expression (parser, cast_p, false,
+ decltype_p,
PREC_NOT_OPERATOR, pidk);
/* If the next token is a `?' then we're actually looking at a
conditional-expression. */
@@ -7623,7 +7690,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
expr = build_x_modify_expr (loc, expr,
assignment_operator,
rhs,
- tf_warning_or_error);
+ complain_flags (decltype_p));
input_location = saved_input_location;
}
}
@@ -7632,6 +7699,14 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
return expr;
}
+static tree
+cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
+ cp_id_kind * pidk)
+{
+ return cp_parser_assignment_expression (parser, cast_p,
+ /*decltype*/false, pidk);
+}
+
/* Parse an (optional) assignment-operator.
assignment-operator: one of
@@ -7723,11 +7798,14 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
expression , assignment-expression
CAST_P is true if this expression is the target of a cast.
+ DECLTYPE_P is true if this expression is the immediate operand of decltype,
+ except possibly parenthesized or on the RHS of a comma (N3276).
Returns a representation of the expression. */
static tree
-cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
+cp_parser_expression (cp_parser* parser, bool cast_p, bool decltype_p,
+ cp_id_kind * pidk)
{
tree expression = NULL_TREE;
location_t loc = UNKNOWN_LOCATION;
@@ -7738,7 +7816,19 @@ cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
/* Parse the next assignment-expression. */
assignment_expression
- = cp_parser_assignment_expression (parser, cast_p, pidk);
+ = cp_parser_assignment_expression (parser, cast_p, decltype_p, pidk);
+
+ /* We don't create a temporary for a call that is the immediate operand
+ of decltype or on the RHS of a comma. But when we see a comma, we
+ need to create a temporary for a call on the LHS. */
+ if (decltype_p && !processing_template_decl
+ && TREE_CODE (assignment_expression) == CALL_EXPR
+ && CLASS_TYPE_P (TREE_TYPE (assignment_expression))
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ assignment_expression
+ = build_cplus_new (TREE_TYPE (assignment_expression),
+ assignment_expression, tf_warning_or_error);
+
/* If this is the first assignment-expression, we can just
save it away. */
if (!expression)
@@ -7746,7 +7836,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
else
expression = build_x_compound_expr (loc, expression,
assignment_expression,
- tf_warning_or_error);
+ complain_flags (decltype_p));
/* If the next token is not a comma, then we are done with the
expression. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
@@ -7762,6 +7852,12 @@ cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
return expression;
}
+static inline tree
+cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
+{
+ return cp_parser_expression (parser, cast_p, /*decltype*/false, pidk);
+}
+
/* Parse a constant-expression.
constant-expression:
@@ -7891,12 +7987,14 @@ cp_parser_builtin_offsetof (cp_parser *parser)
{
case CPP_OPEN_SQUARE:
/* offsetof-member-designator "[" expression "]" */
- expr = cp_parser_postfix_open_square_expression (parser, expr, true);
+ expr = cp_parser_postfix_open_square_expression (parser, expr,
+ true, false);
break;
case CPP_DEREF:
/* offsetof-member-designator "->" identifier */
- expr = grok_array_decl (token->location, expr, integer_zero_node);
+ expr = grok_array_decl (token->location, expr,
+ integer_zero_node, false);
/* FALLTHRU */
case CPP_DOT:
@@ -8526,6 +8624,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
declarator = make_call_declarator (declarator, param_list, quals,
VIRT_SPEC_UNSPECIFIED,
+ REF_QUAL_NONE,
exception_spec,
/*late_return_type=*/NULL_TREE);
declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr);
@@ -9496,7 +9595,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl)
range_expr = error_mark_node;
stmt = begin_range_for_stmt (scope, init);
finish_range_for_decl (stmt, range_decl, range_expr);
- if (!type_dependent_expression_p (range_expr)
+ if (range_expr != error_mark_node
+ && !type_dependent_expression_p (range_expr)
+ /* The length of an array might be dependent. */
+ && COMPLETE_TYPE_P (complete_type (TREE_TYPE (range_expr)))
/* do_auto_deduction doesn't mess with template init-lists. */
&& !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
do_range_for_auto_deduction (range_decl, range_expr);
@@ -9644,7 +9746,8 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
/* The new increment expression. */
expression = finish_unary_op_expr (input_location,
- PREINCREMENT_EXPR, begin);
+ PREINCREMENT_EXPR, begin,
+ tf_warning_or_error);
finish_for_expr (expression, statement);
/* The declaration is initialized with *__begin inside the loop body. */
@@ -11299,7 +11402,7 @@ cp_parser_decltype (cp_parser *parser)
/* Parse a class member access. */
expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
- /*cast_p=*/false,
+ /*cast_p=*/false, /*decltype*/true,
/*member_access_only_p=*/true, NULL);
if (expr
@@ -11327,7 +11430,8 @@ cp_parser_decltype (cp_parser *parser)
parser->greater_than_is_operator_p = true;
/* Parse a full expression. */
- expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ expr = cp_parser_expression (parser, /*cast_p=*/false,
+ /*decltype*/true, NULL);
/* The `>' token might be the end of a template-id or
template-parameter-list now. */
@@ -16168,6 +16272,7 @@ cp_parser_declarator (cp_parser* parser,
declarator-id
direct-declarator ( parameter-declaration-clause )
cv-qualifier-seq [opt]
+ ref-qualifier [opt]
exception-specification [opt]
direct-declarator [ constant-expression [opt] ]
( declarator )
@@ -16176,6 +16281,7 @@ cp_parser_declarator (cp_parser* parser,
direct-abstract-declarator [opt]
( parameter-declaration-clause )
cv-qualifier-seq [opt]
+ ref-qualifier [opt]
exception-specification [opt]
direct-abstract-declarator [opt] [ constant-expression [opt] ]
( abstract-declarator )
@@ -16290,15 +16396,18 @@ cp_parser_direct_declarator (cp_parser* parser,
/* Consume the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
- /* If all went well, parse the cv-qualifier-seq and the
- exception-specification. */
+ /* If all went well, parse the cv-qualifier-seq,
+ ref-qualifier and the exception-specification. */
if (member_p || cp_parser_parse_definitely (parser))
{
cp_cv_quals cv_quals;
cp_virt_specifiers virt_specifiers;
+ cp_ref_qualifier ref_qual;
tree exception_specification;
tree late_return;
tree attrs;
+ bool memfn = (member_p || (pushed_scope
+ && CLASS_TYPE_P (pushed_scope)));
is_declarator = true;
@@ -16308,6 +16417,8 @@ cp_parser_direct_declarator (cp_parser* parser,
/* Parse the cv-qualifier-seq. */
cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
+ /* Parse the ref-qualifier. */
+ ref_qual = cp_parser_ref_qualifier_seq_opt (parser);
/* And the exception-specification. */
exception_specification
= cp_parser_exception_specification_opt (parser);
@@ -16315,7 +16426,7 @@ cp_parser_direct_declarator (cp_parser* parser,
attrs = cp_parser_std_attribute_spec_seq (parser);
late_return = (cp_parser_late_return_type_opt
- (parser, member_p ? cv_quals : -1));
+ (parser, memfn ? cv_quals : -1));
/* Parse the virt-specifier-seq. */
virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
@@ -16325,6 +16436,7 @@ cp_parser_direct_declarator (cp_parser* parser,
params,
cv_quals,
virt_specifiers,
+ ref_qual,
exception_specification,
late_return);
declarator->std_attributes = attrs;
@@ -16857,6 +16969,37 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
return cv_quals;
}
+/* Parse an (optional) ref-qualifier
+
+ ref-qualifier:
+ &
+ &&
+
+ Returns cp_ref_qualifier representing ref-qualifier. */
+
+static cp_ref_qualifier
+cp_parser_ref_qualifier_seq_opt (cp_parser* parser)
+{
+ cp_ref_qualifier ref_qual = REF_QUAL_NONE;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ switch (token->type)
+ {
+ case CPP_AND:
+ ref_qual = REF_QUAL_LVALUE;
+ break;
+ case CPP_AND_AND:
+ ref_qual = REF_QUAL_RVALUE;
+ break;
+ }
+
+ if (ref_qual)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return ref_qual;
+}
+
/* Parse an (optional) virt-specifier-seq.
virt-specifier-seq:
@@ -16964,17 +17107,21 @@ cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals)
/* Consume the ->. */
cp_lexer_consume_token (parser->lexer);
+ tree save_ccp = current_class_ptr;
+ tree save_ccr = current_class_ref;
if (quals >= 0)
{
/* DR 1207: 'this' is in scope in the trailing return type. */
- gcc_assert (current_class_ptr == NULL_TREE);
inject_this_parameter (current_class_type, quals);
}
type = cp_parser_trailing_type_id (parser);
if (quals >= 0)
- current_class_ptr = current_class_ref = NULL_TREE;
+ {
+ current_class_ptr = save_ccp;
+ current_class_ref = save_ccr;
+ }
return type;
}
@@ -20674,8 +20821,13 @@ cp_parser_std_attribute (cp_parser *parser)
token = cp_lexer_peek_token (parser->lexer);
}
else
- attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id),
- NULL_TREE);
+ {
+ attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id),
+ NULL_TREE);
+ /* C++11 noreturn attribute is equivalent to GNU's. */
+ if (is_attribute_p ("noreturn", attr_id))
+ TREE_PURPOSE (TREE_PURPOSE (attribute)) = get_identifier ("gnu");
+ }
/* Now parse the optional argument clause of the attribute. */
@@ -22033,7 +22185,7 @@ static tree
cp_parser_simple_cast_expression (cp_parser *parser)
{
return cp_parser_cast_expression (parser, /*address_p=*/false,
- /*cast_p=*/false, NULL);
+ /*cast_p=*/false, /*decltype*/false, NULL);
}
/* Parse a functional cast to TYPE. Returns an expression
@@ -26830,7 +26982,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
op = (token->type == CPP_PLUS_PLUS
? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
cp_lexer_consume_token (parser->lexer);
- lhs = cp_parser_cast_expression (parser, false, false, NULL);
+ lhs = cp_parser_simple_cast_expression (parser);
if (lhs != decl)
return error_mark_node;
return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
diff --git a/gcc-4.8/gcc/cp/pt.c b/gcc-4.8/gcc/cp/pt.c
index eb9fc7f94..65bce34c7 100644
--- a/gcc-4.8/gcc/cp/pt.c
+++ b/gcc-4.8/gcc/cp/pt.c
@@ -4306,6 +4306,13 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary,
local scope. */
return true;
+ if (TREE_CODE (decl) == TYPE_DECL
+ && TREE_TYPE (decl)
+ && LAMBDA_TYPE_P (TREE_TYPE (decl)))
+ /* A lambda doesn't have an explicit declaration; don't complain
+ about the parms of the enclosing class. */
+ return true;
+
if (current_class_type
&& !TYPE_BEING_DEFINED (current_class_type)
&& DECL_LANG_SPECIFIC (decl)
@@ -4674,6 +4681,8 @@ push_template_decl_real (tree decl, bool is_friend)
if (!ctx
|| TREE_CODE (ctx) == FUNCTION_DECL
|| (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx))
+ || (TREE_CODE (decl) == TYPE_DECL
+ && LAMBDA_TYPE_P (TREE_TYPE (decl)))
|| (is_friend && !DECL_TEMPLATE_INFO (decl)))
{
if (DECL_LANG_SPECIFIC (decl)
@@ -6353,7 +6362,8 @@ convert_template_argument (tree parm,
val = error_mark_node;
}
}
- else if (!uses_template_parms (orig_arg) && !uses_template_parms (t))
+ else if (!dependent_template_arg_p (orig_arg)
+ && !uses_template_parms (t))
/* We used to call digest_init here. However, digest_init
will report errors, which we don't want when complain
is zero. More importantly, digest_init will try too
@@ -7001,7 +7011,7 @@ maybe_get_template_decl_from_type_decl (tree decl)
? CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)) : decl;
}
-/* Given an IDENTIFIER_NODE (type TEMPLATE_DECL) and a chain of
+/* Given an IDENTIFIER_NODE (or type TEMPLATE_DECL) and a chain of
parameters, find the desired type.
D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
@@ -7082,6 +7092,11 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
d1 = DECL_NAME (templ);
context = DECL_CONTEXT (templ);
}
+ else if (DECL_TEMPLATE_TEMPLATE_PARM_P (d1))
+ {
+ templ = d1;
+ d1 = DECL_NAME (templ);
+ }
/* Issue an error message if we didn't find a template. */
if (! templ)
@@ -8992,12 +9007,26 @@ instantiate_class_template_1 (tree type)
}
}
- if (CLASSTYPE_LAMBDA_EXPR (type))
+ if (tree expr = CLASSTYPE_LAMBDA_EXPR (type))
{
tree decl = lambda_function (type);
if (decl)
{
instantiate_decl (decl, false, false);
+
+ /* We need to instantiate the capture list from the template
+ after we've instantiated the closure members, but before we
+ consider adding the conversion op. Also keep any captures
+ that may have been added during instantiation of the op(). */
+ tree tmpl_expr = CLASSTYPE_LAMBDA_EXPR (pattern);
+ tree tmpl_cap
+ = tsubst_copy_and_build (LAMBDA_EXPR_CAPTURE_LIST (tmpl_expr),
+ args, tf_warning_or_error, NULL_TREE,
+ false, false);
+
+ LAMBDA_EXPR_CAPTURE_LIST (expr)
+ = chainon (tmpl_cap, nreverse (LAMBDA_EXPR_CAPTURE_LIST (expr)));
+
maybe_add_lambda_conv_op (type);
}
else
@@ -9169,8 +9198,15 @@ use_pack_expansion_extra_args_p (tree parm_packs,
int arg_pack_len,
bool has_empty_arg)
{
+ /* If one pack has an expansion and another pack has a normal
+ argument or if one pack has an empty argument and an another
+ one hasn't then tsubst_pack_expansion cannot perform the
+ substitution and need to fall back on the
+ PACK_EXPANSION_EXTRA mechanism. */
if (parm_packs == NULL_TREE)
return false;
+ else if (has_empty_arg)
+ return true;
bool has_expansion_arg = false;
for (int i = 0 ; i < arg_pack_len; ++i)
@@ -9188,13 +9224,7 @@ use_pack_expansion_extra_args_p (tree parm_packs,
has_non_expansion_arg = true;
}
- /* If one pack has an expansion and another pack has a normal
- argument or if one pack has an empty argument another one
- hasn't then tsubst_pack_expansion cannot perform the
- substitution and need to fall back on the
- PACK_EXPANSION_EXTRA mechanism. */
- if ((has_expansion_arg && has_non_expansion_arg)
- || (has_empty_arg && (has_expansion_arg || has_non_expansion_arg)))
+ if (has_expansion_arg && has_non_expansion_arg)
return true;
}
return false;
@@ -10826,6 +10856,9 @@ tsubst_arg_types (tree arg_types,
}
return error_mark_node;
}
+ /* DR 657. */
+ if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain))
+ return error_mark_node;
/* Do array-to-pointer, function-to-pointer conversion, and ignore
top-level qualifiers as required. */
@@ -10888,10 +10921,8 @@ tsubst_function_type (tree t,
return_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
if (return_type == error_mark_node)
return error_mark_node;
- /* The standard does not presently indicate that creation of a
- function type with an invalid return type is a deduction failure.
- However, that is clearly analogous to creating an array of "void"
- or a reference to a reference. This is core issue #486. */
+ /* DR 486 clarifies that creation of a function type with an
+ invalid return type is a deduction failure. */
if (TREE_CODE (return_type) == ARRAY_TYPE
|| TREE_CODE (return_type) == FUNCTION_TYPE)
{
@@ -10904,6 +10935,9 @@ tsubst_function_type (tree t,
}
return error_mark_node;
}
+ /* And DR 657. */
+ if (abstract_virtuals_error_sfinae (NULL_TREE, return_type, complain))
+ return error_mark_node;
/* Substitute the argument types. */
arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, NULL_TREE,
@@ -10915,7 +10949,9 @@ tsubst_function_type (tree t,
if (TREE_CODE (t) == FUNCTION_TYPE)
{
fntype = build_function_type (return_type, arg_types);
- fntype = apply_memfn_quals (fntype, type_memfn_quals (t));
+ fntype = apply_memfn_quals (fntype,
+ type_memfn_quals (t),
+ type_memfn_rqual (t));
}
else
{
@@ -10937,6 +10973,7 @@ tsubst_function_type (tree t,
fntype = build_method_type_directly (r, return_type,
TREE_CHAIN (arg_types));
+ fntype = build_ref_qualified_type (fntype, type_memfn_rqual (t));
}
fntype = cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
@@ -11569,7 +11606,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
/* The type of the implicit object parameter gets its
cv-qualifiers from the FUNCTION_TYPE. */
tree memptr;
- tree method_type = build_memfn_type (type, r, type_memfn_quals (type));
+ tree method_type
+ = build_memfn_type (type, r, type_memfn_quals (type),
+ type_memfn_rqual (type));
memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
return cp_build_qualified_type_real (memptr, cp_type_quals (t),
complain);
@@ -11757,7 +11796,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
++c_inhibit_evaluation_warnings;
type = tsubst_expr (DECLTYPE_TYPE_EXPR (t), args,
- complain, in_decl,
+ complain|tf_decltype, in_decl,
/*integral_constant_expression_p=*/false);
--cp_unevaluated_operand;
@@ -11768,8 +11807,17 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else if (DECLTYPE_FOR_LAMBDA_PROXY (t))
type = lambda_proxy_type (type);
else
- type = finish_decltype_type
- (type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t), complain);
+ {
+ bool id = DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t);
+ if (id && TREE_CODE (DECLTYPE_TYPE_EXPR (t)) == BIT_NOT_EXPR
+ && EXPR_P (type))
+ /* In a template ~id could be either a complement expression
+ or an unqualified-id naming a destructor; if instantiating
+ it produces an expression, it's not an id-expression or
+ member access. */
+ id = false;
+ type = finish_decltype_type (type, id, complain);
+ }
return cp_build_qualified_type_real (type,
cp_type_quals (t)
| cp_type_quals (type),
@@ -12010,11 +12058,11 @@ tsubst_qualified_id (tree qualified_id, tree args,
else if (TYPE_P (scope))
{
expr = (adjust_result_of_qualified_name_lookup
- (expr, scope, current_class_type));
+ (expr, scope, current_nonlambda_class_type ()));
expr = (finish_qualified_id_expr
(scope, expr, done, address_p && PTRMEM_OK_P (qualified_id),
QUALIFIED_NAME_IS_TEMPLATE (qualified_id),
- /*template_arg_p=*/false));
+ /*template_arg_p=*/false, complain));
}
/* Expressions do not generally have reference type. */
@@ -13393,6 +13441,11 @@ tsubst_copy_and_build (tree t,
if (EXPR_HAS_LOCATION (t))
input_location = EXPR_LOCATION (t);
+ /* N3276 decltype magic only applies to calls at the top level or on the
+ right side of a comma. */
+ tsubst_flags_t decltype_flag = (complain & tf_decltype);
+ complain &= ~tf_decltype;
+
switch (TREE_CODE (t))
{
case USING_DECL:
@@ -13479,7 +13532,8 @@ tsubst_copy_and_build (tree t,
r = convert_from_reference (r);
}
else
- r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR, complain);
+ r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR,
+ complain|decltype_flag);
RETURN (r);
}
@@ -13556,7 +13610,8 @@ tsubst_copy_and_build (tree t,
case POSTINCREMENT_EXPR:
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
args, complain, in_decl);
- RETURN (build_x_unary_op (input_location, TREE_CODE (t), op1, complain));
+ RETURN (build_x_unary_op (input_location, TREE_CODE (t), op1,
+ complain|decltype_flag));
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
@@ -13568,7 +13623,8 @@ tsubst_copy_and_build (tree t,
case REALPART_EXPR:
case IMAGPART_EXPR:
RETURN (build_x_unary_op (input_location, TREE_CODE (t),
- RECUR (TREE_OPERAND (t, 0)), complain));
+ RECUR (TREE_OPERAND (t, 0)),
+ complain|decltype_flag));
case FIX_TRUNC_EXPR:
RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)),
@@ -13585,7 +13641,8 @@ tsubst_copy_and_build (tree t,
else
op1 = tsubst_non_call_postfix_expression (op1, args, complain,
in_decl);
- RETURN (build_x_unary_op (input_location, ADDR_EXPR, op1, complain));
+ RETURN (build_x_unary_op (input_location, ADDR_EXPR, op1,
+ complain|decltype_flag));
case PLUS_EXPR:
case MINUS_EXPR:
@@ -13634,7 +13691,7 @@ tsubst_copy_and_build (tree t,
? ERROR_MARK
: TREE_CODE (TREE_OPERAND (t, 1))),
/*overload=*/NULL,
- complain);
+ complain|decltype_flag);
if (EXPR_P (r) && TREE_NO_WARNING (t))
TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
@@ -13650,7 +13707,8 @@ tsubst_copy_and_build (tree t,
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
args, complain, in_decl);
RETURN (build_x_array_ref (EXPR_LOCATION (t), op1,
- RECUR (TREE_OPERAND (t, 1)), complain));
+ RECUR (TREE_OPERAND (t, 1)),
+ complain|decltype_flag));
case SIZEOF_EXPR:
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
@@ -13743,7 +13801,7 @@ tsubst_copy_and_build (tree t,
RECUR (TREE_OPERAND (t, 0)),
TREE_CODE (TREE_OPERAND (t, 1)),
RECUR (TREE_OPERAND (t, 2)),
- complain);
+ complain|decltype_flag);
/* TREE_NO_WARNING must be set if either the expression was
parenthesized or it uses an operator such as >>= rather
than plain assignment. In the former case, it was already
@@ -13824,10 +13882,16 @@ tsubst_copy_and_build (tree t,
complain));
case COMPOUND_EXPR:
- RETURN (build_x_compound_expr (EXPR_LOCATION (t),
- RECUR (TREE_OPERAND (t, 0)),
- RECUR (TREE_OPERAND (t, 1)),
- complain));
+ {
+ tree op0 = tsubst_copy_and_build (TREE_OPERAND (t, 0), args,
+ complain & ~tf_decltype, in_decl,
+ /*function_p=*/false,
+ integral_constant_expression_p);
+ RETURN (build_x_compound_expr (EXPR_LOCATION (t),
+ op0,
+ RECUR (TREE_OPERAND (t, 1)),
+ complain|decltype_flag));
+ }
case CALL_EXPR:
{
@@ -14004,6 +14068,9 @@ tsubst_copy_and_build (tree t,
if (DECL_P (function))
mark_used (function);
+ /* Put back tf_decltype for the actual call. */
+ complain |= decltype_flag;
+
if (TREE_CODE (function) == OFFSET_REF)
ret = build_offset_ref_call_from_tree (function, &call_args,
complain);
@@ -14293,7 +14360,10 @@ tsubst_copy_and_build (tree t,
newlen = vec_safe_length (n);
FOR_EACH_VEC_SAFE_ELT (n, idx, ce)
{
- if (ce->index && process_index_p)
+ if (ce->index && process_index_p
+ /* An identifier index is looked up in the type
+ being initialized, not the current scope. */
+ && TREE_CODE (ce->index) != IDENTIFIER_NODE)
ce->index = RECUR (ce->index);
if (PACK_EXPANSION_P (ce->value))
@@ -14471,12 +14541,6 @@ tsubst_copy_and_build (tree t,
declaration of the op() for later calls to lambda_function. */
complete_type (type);
- /* The capture list refers to closure members, so this needs to
- wait until after we finish instantiating the type. Also keep
- any captures that may have been added during instantiation. */
- LAMBDA_EXPR_CAPTURE_LIST (r)
- = chainon (RECUR (LAMBDA_EXPR_CAPTURE_LIST (t)),
- LAMBDA_EXPR_CAPTURE_LIST (r));
LAMBDA_EXPR_THIS_CAPTURE (r) = NULL_TREE;
RETURN (build_lambda_object (r));
@@ -15805,7 +15869,7 @@ resolve_nondeduced_context (tree orig_expr)
{
tree base
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (offset, 0)));
- expr = build_offset_ref (base, expr, addr);
+ expr = build_offset_ref (base, expr, addr, tf_warning_or_error);
}
if (addr)
expr = cp_build_addr_expr (expr, tf_warning_or_error);
@@ -16155,10 +16219,10 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
arg = NULL_TREE;
if (TREE_VALUE (pack)
&& (pargs = ARGUMENT_PACK_EXPLICIT_ARGS (TREE_VALUE (pack)))
- && (i < TREE_VEC_LENGTH (pargs)))
+ && (i - start < TREE_VEC_LENGTH (pargs)))
{
any_explicit = true;
- arg = TREE_VEC_ELT (pargs, i);
+ arg = TREE_VEC_ELT (pargs, i - start);
}
TMPL_ARG (targs, level, idx) = arg;
}
@@ -17039,10 +17103,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
build_function_type (TREE_TYPE (method_type),
TREE_CHAIN (TYPE_ARG_TYPES (method_type)));
- /* Extract the cv-qualifiers of the member function from the
- implicit object parameter and place them on the function
- type to be restored later. */
- fntype = apply_memfn_quals (fntype, type_memfn_quals (method_type));
+ /* Extract the cv-qualifiers and ref-qualifier of the member
+ function from the implicit object parameter and place them
+ on the function type to be restored later. */
+ fntype = apply_memfn_quals (fntype,
+ type_memfn_quals (method_type),
+ type_memfn_rqual (method_type));
return unify (tparms, targs, TREE_TYPE (parm), fntype, strict, explain_p);
}
@@ -19917,7 +19983,8 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
case TRAIT_EXPR:
if (dependent_type_p (TRAIT_EXPR_TYPE1 (*tp))
- || dependent_type_p (TRAIT_EXPR_TYPE2 (*tp)))
+ || (TRAIT_EXPR_TYPE2 (*tp)
+ && dependent_type_p (TRAIT_EXPR_TYPE2 (*tp))))
return *tp;
*walk_subtrees = false;
return NULL_TREE;
diff --git a/gcc-4.8/gcc/cp/search.c b/gcc-4.8/gcc/cp/search.c
index 4cc02ba7d..54a5e4ae7 100644
--- a/gcc-4.8/gcc/cp/search.c
+++ b/gcc-4.8/gcc/cp/search.c
@@ -188,6 +188,14 @@ lookup_base (tree t, tree base, base_access access,
tree t_binfo;
base_kind bk;
+ /* "Nothing" is definitely not derived from Base. */
+ if (t == NULL_TREE)
+ {
+ if (kind_ptr)
+ *kind_ptr = bk_not_base;
+ return NULL_TREE;
+ }
+
if (t == error_mark_node || base == error_mark_node)
{
if (kind_ptr)
diff --git a/gcc-4.8/gcc/cp/semantics.c b/gcc-4.8/gcc/cp/semantics.c
index e909b9846..8a7fe3807 100644
--- a/gcc-4.8/gcc/cp/semantics.c
+++ b/gcc-4.8/gcc/cp/semantics.c
@@ -1574,9 +1574,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
else
{
/* Set the cv qualifiers. */
- int quals = (current_class_ref
- ? cp_type_quals (TREE_TYPE (current_class_ref))
- : TYPE_UNQUALIFIED);
+ int quals = cp_type_quals (TREE_TYPE (object));
if (DECL_MUTABLE_P (decl))
quals &= ~TYPE_QUAL_CONST;
@@ -1740,7 +1738,8 @@ finish_qualified_id_expr (tree qualifying_class,
bool done,
bool address_p,
bool template_p,
- bool template_arg_p)
+ bool template_arg_p,
+ tsubst_flags_t complain)
{
gcc_assert (TYPE_P (qualifying_class));
@@ -1760,10 +1759,14 @@ finish_qualified_id_expr (tree qualifying_class,
if (TREE_CODE (expr) == SCOPE_REF)
expr = TREE_OPERAND (expr, 1);
expr = build_offset_ref (qualifying_class, expr,
- /*address_p=*/true);
+ /*address_p=*/true, complain);
return expr;
}
+ /* No need to check access within an enum. */
+ if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE)
+ return expr;
+
/* Within the scope of a class, turn references to non-static
members into expression of the form "this->...". */
if (template_arg_p)
@@ -1790,11 +1793,12 @@ finish_qualified_id_expr (tree qualifying_class,
expr,
BASELINK_ACCESS_BINFO (expr),
/*preserve_reference=*/false,
- tf_warning_or_error));
+ complain));
else if (done)
/* The expression is a qualified name whose address is not
being taken. */
- expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false);
+ expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
+ complain);
}
else if (BASELINK_P (expr))
;
@@ -2370,10 +2374,12 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor)
/* Finish an expression of the form CODE EXPR. */
tree
-finish_unary_op_expr (location_t loc, enum tree_code code, tree expr)
+finish_unary_op_expr (location_t loc, enum tree_code code, tree expr,
+ tsubst_flags_t complain)
{
- tree result = build_x_unary_op (loc, code, expr, tf_warning_or_error);
- if (TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
+ tree result = build_x_unary_op (loc, code, expr, complain);
+ if ((complain & tf_warning)
+ && TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
overflow_warning (input_location, result);
return result;
@@ -3229,7 +3235,8 @@ finish_id_expression (tree id_expression,
decl = finish_qualified_id_expr (scope, decl,
done, address_p,
template_p,
- template_arg_p);
+ template_arg_p,
+ tf_warning_or_error);
else
{
tree type = NULL_TREE;
@@ -3345,7 +3352,8 @@ finish_id_expression (tree id_expression,
done,
address_p,
template_p,
- template_arg_p);
+ template_arg_p,
+ tf_warning_or_error);
else
decl = convert_from_reference (decl);
}
@@ -5345,6 +5353,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
break;
case COMPONENT_REF:
+ case COMPOUND_EXPR:
mark_type_use (expr);
type = is_bitfield_expr_with_lowered_type (expr);
if (!type)
@@ -5362,8 +5371,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
break;
default:
- gcc_unreachable ();
- return error_mark_node;
+ /* Handle instantiated template non-type arguments. */
+ type = TREE_TYPE (expr);
+ break;
}
}
else
@@ -7007,6 +7017,13 @@ cxx_eval_array_reference (const constexpr_call *call, tree t,
*non_constant_p = true;
return t;
}
+ else if (tree_int_cst_lt (index, integer_zero_node))
+ {
+ if (!allow_non_constant)
+ error ("negative array subscript");
+ *non_constant_p = true;
+ return t;
+ }
i = tree_low_cst (index, 0);
if (TREE_CODE (ary) == CONSTRUCTOR)
return (*CONSTRUCTOR_ELTS (ary))[i].value;
@@ -7571,15 +7588,17 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
}
}
}
- /* *(foo *)fooarrptreturn> (*fooarrptr)[0] */
+ /* *(foo *)fooarrptr => (*fooarrptr)[0] */
else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
&& (same_type_ignoring_top_level_qualifiers_p
(type, TREE_TYPE (TREE_TYPE (subtype)))))
{
tree type_domain;
tree min_val = size_zero_node;
- sub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL);
- if (!sub)
+ tree newsub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL);
+ if (newsub)
+ sub = newsub;
+ else
sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub);
type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
if (type_domain && TYPE_MIN_VALUE (type_domain))
@@ -7649,6 +7668,8 @@ cxx_eval_indirect_ref (const constexpr_call *call, tree t,
if (r == NULL_TREE)
{
+ if (addr && op0 != orig_op0)
+ return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
if (!addr)
VERIFY_CONSTANT (t);
return t;
@@ -8390,7 +8411,11 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
}
}
else
- fun = get_first_fn (fun);
+ {
+ if (!potential_constant_expression_1 (fun, true, flags))
+ return false;
+ fun = get_first_fn (fun);
+ }
/* Skip initial arguments to base constructors. */
if (DECL_BASE_CONSTRUCTOR_P (fun))
i = num_artificial_parms_for (fun);
@@ -8967,7 +8992,7 @@ begin_lambda_type (tree lambda)
/* Create the new RECORD_TYPE for this lambda. */
type = xref_tag (/*tag_code=*/record_type,
name,
- /*scope=*/ts_within_enclosing_non_class,
+ /*scope=*/ts_lambda,
/*template_header_p=*/false);
}
@@ -9039,7 +9064,8 @@ tree
lambda_capture_field_type (tree expr)
{
tree type;
- if (type_dependent_expression_p (expr))
+ if (type_dependent_expression_p (expr)
+ && !(TREE_TYPE (expr) && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE))
{
type = cxx_make_type (DECLTYPE_TYPE);
DECLTYPE_TYPE_EXPR (type) = expr;
@@ -9189,13 +9215,12 @@ void
insert_capture_proxy (tree var)
{
cp_binding_level *b;
- int skip;
tree stmt_list;
/* Put the capture proxy in the extra body block so that it won't clash
with a later local variable. */
b = current_binding_level;
- for (skip = 0; ; ++skip)
+ for (;;)
{
cp_binding_level *n = b->level_chain;
if (n->kind == sk_function_parms)
@@ -9206,7 +9231,7 @@ insert_capture_proxy (tree var)
/* And put a DECL_EXPR in the STATEMENT_LIST for the same block. */
var = build_stmt (DECL_SOURCE_LOCATION (var), DECL_EXPR, var);
- stmt_list = (*stmt_list_stack)[stmt_list_stack->length () - 1 - skip];
+ stmt_list = (*stmt_list_stack)[1];
gcc_assert (stmt_list);
append_to_statement_list_force (var, &stmt_list);
}
@@ -9248,7 +9273,8 @@ lambda_proxy_type (tree ref)
if (REFERENCE_REF_P (ref))
ref = TREE_OPERAND (ref, 0);
type = TREE_TYPE (ref);
- if (!dependent_type_p (type))
+ if (!dependent_type_p (type)
+ || (type && TREE_CODE (type) == POINTER_TYPE))
return type;
type = cxx_make_type (DECLTYPE_TYPE);
DECLTYPE_TYPE_EXPR (type) = ref;
@@ -9438,6 +9464,11 @@ lambda_expr_this_capture (tree lambda)
tree this_capture = LAMBDA_EXPR_THIS_CAPTURE (lambda);
+ /* In unevaluated context this isn't an odr-use, so just return the
+ nearest 'this'. */
+ if (cp_unevaluated_operand)
+ return lookup_name (this_identifier);
+
/* Try to default capture 'this' if we can. */
if (!this_capture
&& LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE)
@@ -9507,11 +9538,6 @@ lambda_expr_this_capture (tree lambda)
if (!this_capture)
{
- /* In unevaluated context this isn't an odr-use, so just return the
- nearest 'this'. */
- if (cp_unevaluated_operand)
- return lookup_name (this_identifier);
-
error ("%<this%> was not captured for this lambda function");
result = error_mark_node;
}
@@ -9549,7 +9575,8 @@ maybe_resolve_dummy (tree object)
if (type != current_class_type
&& current_class_type
- && LAMBDA_TYPE_P (current_class_type))
+ && LAMBDA_TYPE_P (current_class_type)
+ && DERIVED_FROM_P (type, current_nonlambda_class_type ()))
{
/* In a lambda, need to go through 'this' capture. */
tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
diff --git a/gcc-4.8/gcc/cp/tree.c b/gcc-4.8/gcc/cp/tree.c
index 178b80aa2..a75663406 100644
--- a/gcc-4.8/gcc/cp/tree.c
+++ b/gcc-4.8/gcc/cp/tree.c
@@ -469,6 +469,9 @@ build_cplus_new (tree type, tree init, tsubst_flags_t complain)
tree rval = build_aggr_init_expr (type, init);
tree slot;
+ if (!complete_type_or_maybe_complain (type, init, complain))
+ return error_mark_node;
+
/* Make sure that we're not trying to create an instance of an
abstract class. */
if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain))
@@ -826,10 +829,12 @@ build_cplus_array_type (tree elt_type, tree index_type)
if (TYPE_MAIN_VARIANT (t) != m)
{
- if (COMPLETE_TYPE_P (t) && !COMPLETE_TYPE_P (m))
+ if (COMPLETE_TYPE_P (TREE_TYPE (t)) && !COMPLETE_TYPE_P (m))
{
/* m was built before the element type was complete, so we
- also need to copy the layout info from t. */
+ also need to copy the layout info from t. We might
+ end up doing this multiple times if t is an array of
+ unknown bound. */
tree size = TYPE_SIZE (t);
tree size_unit = TYPE_SIZE_UNIT (t);
unsigned int align = TYPE_ALIGN (t);
@@ -1078,6 +1083,15 @@ cp_build_qualified_type_real (tree type,
/* Retrieve (or create) the appropriately qualified variant. */
result = build_qualified_type (type, type_quals);
+ /* Preserve exception specs and ref-qualifier since build_qualified_type
+ doesn't know about them. */
+ if (TREE_CODE (result) == FUNCTION_TYPE
+ || TREE_CODE (result) == METHOD_TYPE)
+ {
+ result = build_exception_variant (result, TYPE_RAISES_EXCEPTIONS (type));
+ result = build_ref_qualified_type (result, type_memfn_rqual (type));
+ }
+
/* If this was a pointer-to-method type, and we just made a copy,
then we need to unshare the record that holds the cached
pointer-to-member-function type, because these will be distinct
@@ -1211,7 +1225,9 @@ strip_typedefs (tree t)
{
result = build_function_type (type,
arg_types);
- result = apply_memfn_quals (result, type_memfn_quals (t));
+ result = apply_memfn_quals (result,
+ type_memfn_quals (t),
+ type_memfn_rqual (t));
}
if (TYPE_RAISES_EXCEPTIONS (t))
@@ -1241,8 +1257,13 @@ strip_typedefs (tree t)
changed = true;
}
if (changed)
- fullname = lookup_template_function (TREE_OPERAND (fullname, 0),
- new_args);
+ {
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_args)
+ = NON_DEFAULT_TEMPLATE_ARGS_COUNT (args);
+ fullname
+ = lookup_template_function (TREE_OPERAND (fullname, 0),
+ new_args);
+ }
else
ggc_free (new_args);
}
@@ -1375,8 +1396,8 @@ strip_typedefs_expr (tree t)
r = copy_node (t);
for (i = 0; i < n; ++i)
TREE_VEC_ELT (r, i) = (*vec)[i];
- SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
- (r, GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (t));
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT (r)
+ = NON_DEFAULT_TEMPLATE_ARGS_COUNT (t);
}
else
r = t;
@@ -1418,7 +1439,8 @@ strip_typedefs_expr (tree t)
}
case LAMBDA_EXPR:
- gcc_unreachable ();
+ error ("lambda-expression in a constant expression");
+ return error_mark_node;
default:
break;
@@ -1698,6 +1720,66 @@ build_qualified_name (tree type, tree scope, tree name, bool template_p)
return t;
}
+/* Like check_qualified_type, but also check ref-qualifier and exception
+ specification. */
+
+static bool
+cp_check_qualified_type (const_tree cand, const_tree base, int type_quals,
+ cp_ref_qualifier rqual, tree raises)
+{
+ return (check_qualified_type (cand, base, type_quals)
+ && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (cand),
+ ce_exact)
+ && type_memfn_rqual (cand) == rqual);
+}
+
+/* Build the FUNCTION_TYPE or METHOD_TYPE with the ref-qualifier RQUAL. */
+
+tree
+build_ref_qualified_type (tree type, cp_ref_qualifier rqual)
+{
+ tree t;
+
+ if (rqual == type_memfn_rqual (type))
+ return type;
+
+ int type_quals = TYPE_QUALS (type);
+ tree raises = TYPE_RAISES_EXCEPTIONS (type);
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ if (cp_check_qualified_type (t, type, type_quals, rqual, raises))
+ return t;
+
+ t = build_variant_type_copy (type);
+ switch (rqual)
+ {
+ case REF_QUAL_RVALUE:
+ FUNCTION_RVALUE_QUALIFIED (t) = 1;
+ FUNCTION_REF_QUALIFIED (t) = 1;
+ break;
+ case REF_QUAL_LVALUE:
+ FUNCTION_RVALUE_QUALIFIED (t) = 0;
+ FUNCTION_REF_QUALIFIED (t) = 1;
+ break;
+ default:
+ FUNCTION_REF_QUALIFIED (t) = 0;
+ break;
+ }
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (type))
+ /* Propagate structural equality. */
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (type) != type)
+ /* Build the underlying canonical type, since it is different
+ from TYPE. */
+ TYPE_CANONICAL (t) = build_ref_qualified_type (TYPE_CANONICAL (type),
+ rqual);
+ else
+ /* T is its own canonical type. */
+ TYPE_CANONICAL (t) = t;
+
+ return t;
+}
+
/* Returns nonzero if X is an expression for a (possibly overloaded)
function. If "f" is a function or function template, "f", "c->f",
"c.f", "C::f", and "f<int>" will all be considered possibly
@@ -1903,9 +1985,9 @@ build_exception_variant (tree type, tree raises)
return type;
type_quals = TYPE_QUALS (type);
+ cp_ref_qualifier rqual = type_memfn_rqual (type);
for (v = TYPE_MAIN_VARIANT (type); v; v = TYPE_NEXT_VARIANT (v))
- if (check_qualified_type (v, type, type_quals)
- && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), ce_exact))
+ if (cp_check_qualified_type (v, type, type_quals, rqual, raises))
return v;
/* Need to build a new variant. */
@@ -2024,11 +2106,12 @@ no_linkage_check (tree t, bool relaxed_p)
if (TYPE_PTRMEMFUNC_P (t))
goto ptrmem;
/* Lambda types that don't have mangling scope have no linkage. We
- check CLASSTYPE_LAMBDA_EXPR here rather than LAMBDA_TYPE_P because
+ check CLASSTYPE_LAMBDA_EXPR for error_mark_node because
when we get here from pushtag none of the lambda information is
set up yet, so we want to assume that the lambda has linkage and
fix it up later if not. */
if (CLASSTYPE_LAMBDA_EXPR (t)
+ && CLASSTYPE_LAMBDA_EXPR (t) != error_mark_node
&& LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE)
return t;
/* Fall through. */
@@ -2486,7 +2569,7 @@ cp_tree_equal (tree t1, tree t2)
t1 = TREE_OPERAND (t1, 0);
for (code2 = TREE_CODE (t2);
CONVERT_EXPR_CODE_P (code2)
- || code1 == NON_LVALUE_EXPR;
+ || code2 == NON_LVALUE_EXPR;
code2 = TREE_CODE (t2))
t2 = TREE_OPERAND (t2, 0);
@@ -3303,8 +3386,12 @@ cp_build_type_attribute_variant (tree type, tree attributes)
new_type = build_type_attribute_variant (type, attributes);
if (TREE_CODE (new_type) == FUNCTION_TYPE
|| TREE_CODE (new_type) == METHOD_TYPE)
- new_type = build_exception_variant (new_type,
- TYPE_RAISES_EXCEPTIONS (type));
+ {
+ new_type = build_exception_variant (new_type,
+ TYPE_RAISES_EXCEPTIONS (type));
+ new_type = build_ref_qualified_type (new_type,
+ type_memfn_rqual (type));
+ }
/* Making a new main variant of a class type is broken. */
gcc_assert (!CLASS_TYPE_P (type) || new_type == type);
diff --git a/gcc-4.8/gcc/cp/typeck.c b/gcc-4.8/gcc/cp/typeck.c
index 58ebcc0ab..21b5d414b 100644
--- a/gcc-4.8/gcc/cp/typeck.c
+++ b/gcc-4.8/gcc/cp/typeck.c
@@ -833,7 +833,10 @@ merge_types (tree t1, tree t2)
rval = build_function_type (valtype, parms);
gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2));
- rval = apply_memfn_quals (rval, type_memfn_quals (t1));
+ gcc_assert (type_memfn_rqual (t1) == type_memfn_rqual (t2));
+ rval = apply_memfn_quals (rval,
+ type_memfn_quals (t1),
+ type_memfn_rqual (t1));
raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
TYPE_RAISES_EXCEPTIONS (t2),
NULL_TREE);
@@ -849,6 +852,7 @@ merge_types (tree t1, tree t2)
tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
TYPE_RAISES_EXCEPTIONS (t2),
NULL_TREE);
+ cp_ref_qualifier rqual = type_memfn_rqual (t1);
tree t3;
/* If this was a member function type, get back to the
@@ -862,6 +866,7 @@ merge_types (tree t1, tree t2)
t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
TYPE_ARG_TYPES (t3));
t1 = build_exception_variant (t3, raises);
+ t1 = build_ref_qualified_type (t1, rqual);
break;
}
@@ -1186,6 +1191,12 @@ structural_comptypes (tree t1, tree t2, int strict)
if (TREE_CODE (t1) == FUNCTION_TYPE
&& type_memfn_quals (t1) != type_memfn_quals (t2))
return false;
+ /* Need to check this before TYPE_MAIN_VARIANT.
+ FIXME function qualifiers should really change the main variant. */
+ if ((TREE_CODE (t1) == FUNCTION_TYPE
+ || TREE_CODE (t1) == METHOD_TYPE)
+ && type_memfn_rqual (t1) != type_memfn_rqual (t2))
+ return false;
if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
return false;
@@ -1718,15 +1729,19 @@ cxx_alignas_expr (tree e)
When the alignment-specifier is of the form
alignas(type-id ), it shall have the same effect as
- alignas( alignof(type-id )). */
+ alignas(alignof(type-id )). */
return cxx_sizeof_or_alignof_type (e, ALIGNOF_EXPR, false);
-
/* If we reach this point, it means the alignas expression if of
the form "alignas(assignment-expression)", so we should follow
what is stated by [dcl.align]/2. */
+ if (value_dependent_expression_p (e))
+ /* Leave value-dependent expression alone for now. */
+ return e;
+
+ e = fold_non_dependent_expr (e);
e = mark_rvalue_use (e);
/* [dcl.align]/2 says:
@@ -1734,18 +1749,7 @@ cxx_alignas_expr (tree e)
the assignment-expression shall be an integral constant
expression. */
- e = fold_non_dependent_expr (e);
- if (value_dependent_expression_p (e))
- /* Leave value-dependent expression alone for now. */;
- else
- e = cxx_constant_value (e);
-
- if (e == NULL_TREE
- || e == error_mark_node
- || TREE_CODE (e) != INTEGER_CST)
- return error_mark_node;
-
- return e;
+ return cxx_constant_value (e);
}
@@ -2670,6 +2674,23 @@ finish_class_member_access_expr (tree object, tree name, bool template_p,
return error_mark_node;
}
+ if (TREE_CODE (scope) == ENUMERAL_TYPE)
+ {
+ /* Looking up a member enumerator (c++/56793). */
+ if (!TYPE_CLASS_SCOPE_P (scope)
+ || !DERIVED_FROM_P (TYPE_CONTEXT (scope), object_type))
+ {
+ if (complain & tf_error)
+ error ("%<%D::%D%> is not a member of %qT",
+ scope, name, object_type);
+ return error_mark_node;
+ }
+ tree val = lookup_enumerator (scope, name);
+ if (TREE_SIDE_EFFECTS (object))
+ val = build2 (COMPOUND_EXPR, TREE_TYPE (val), object, val);
+ return val;
+ }
+
gcc_assert (CLASS_TYPE_P (scope));
gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE
|| TREE_CODE (name) == BIT_NOT_EXPR);
@@ -3939,6 +3960,7 @@ cp_build_binary_op (location_t location,
return error_mark_node;
case stv_firstarg:
{
+ op0 = save_expr (op0);
op0 = convert (TREE_TYPE (type1), op0);
op0 = build_vector_from_val (type1, op0);
type0 = TREE_TYPE (op0);
@@ -3948,6 +3970,7 @@ cp_build_binary_op (location_t location,
}
case stv_secondarg:
{
+ op1 = save_expr (op1);
op1 = convert (TREE_TYPE (type0), op1);
op1 = build_vector_from_val (type0, op1);
type1 = TREE_TYPE (op1);
@@ -4014,8 +4037,9 @@ cp_build_binary_op (location_t location,
|| code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
{
enum tree_code tcode0 = code0, tcode1 = code1;
+ tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
- warn_for_div_by_zero (location, op1);
+ warn_for_div_by_zero (location, maybe_constant_value (cop1));
if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
@@ -4051,7 +4075,11 @@ cp_build_binary_op (location_t location,
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
- warn_for_div_by_zero (location, op1);
+ {
+ tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+
+ warn_for_div_by_zero (location, maybe_constant_value (cop1));
+ }
if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
&& TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
@@ -4099,7 +4127,8 @@ cp_build_binary_op (location_t location,
}
else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
- tree const_op1 = maybe_constant_value (op1);
+ tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+ const_op1 = maybe_constant_value (const_op1);
if (TREE_CODE (const_op1) != INTEGER_CST)
const_op1 = op1;
result_type = type0;
@@ -4145,7 +4174,8 @@ cp_build_binary_op (location_t location,
}
else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
- tree const_op1 = maybe_constant_value (op1);
+ tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+ const_op1 = maybe_constant_value (const_op1);
if (TREE_CODE (const_op1) != INTEGER_CST)
const_op1 = op1;
result_type = type0;
@@ -5109,7 +5139,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
" Say %<&%T::%D%>",
base, name);
}
- arg = build_offset_ref (base, fn, /*address_p=*/true);
+ arg = build_offset_ref (base, fn, /*address_p=*/true, complain);
}
/* Uninstantiated types are all functions. Taking the
@@ -8553,6 +8583,22 @@ cp_type_quals (const_tree type)
return quals;
}
+/* Returns the function-ref-qualifier for TYPE */
+
+cp_ref_qualifier
+type_memfn_rqual (const_tree type)
+{
+ gcc_assert (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE);
+
+ if (!FUNCTION_REF_QUALIFIED (type))
+ return REF_QUAL_NONE;
+ else if (FUNCTION_RVALUE_QUALIFIED (type))
+ return REF_QUAL_RVALUE;
+ else
+ return REF_QUAL_LVALUE;
+}
+
/* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
METHOD_TYPE. */
@@ -8568,18 +8614,22 @@ type_memfn_quals (const_tree type)
}
/* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
- MEMFN_QUALS. */
+ MEMFN_QUALS and its ref-qualifier to RQUAL. */
tree
-apply_memfn_quals (tree type, cp_cv_quals memfn_quals)
+apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual)
{
/* Could handle METHOD_TYPE here if necessary. */
gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
- if (TYPE_QUALS (type) == memfn_quals)
+ if (TYPE_QUALS (type) == memfn_quals
+ && type_memfn_rqual (type) == rqual)
return type;
+
/* This should really have a different TYPE_MAIN_VARIANT, but that gets
complex. */
- return build_qualified_type (type, memfn_quals);
+ tree result = build_qualified_type (type, memfn_quals);
+ result = build_exception_variant (result, TYPE_RAISES_EXCEPTIONS (type));
+ return build_ref_qualified_type (result, rqual);
}
/* Returns nonzero if TYPE is const or volatile. */
diff --git a/gcc-4.8/gcc/cp/typeck2.c b/gcc-4.8/gcc/cp/typeck2.c
index d227a821d..9b7db6218 100644
--- a/gcc-4.8/gcc/cp/typeck2.c
+++ b/gcc-4.8/gcc/cp/typeck2.c
@@ -1612,7 +1612,7 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
if (TYPE_PTRDATAMEM_P (ptrmem_type))
{
- bool is_lval = real_lvalue_p (datum);
+ cp_lvalue_kind kind = lvalue_kind (datum);
tree ptype;
/* Compute the type of the field, as described in [expr.ref].
@@ -1642,12 +1642,39 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
return error_mark_node;
/* If the object expression was an rvalue, return an rvalue. */
- if (!is_lval)
+ if (kind & clk_class)
+ datum = rvalue (datum);
+ else if (kind & clk_rvalueref)
datum = move (datum);
return datum;
}
else
- return build2 (OFFSET_REF, type, datum, component);
+ {
+ /* 5.5/6: In a .* expression whose object expression is an rvalue, the
+ program is ill-formed if the second operand is a pointer to member
+ function with ref-qualifier &. In a .* expression whose object
+ expression is an lvalue, the program is ill-formed if the second
+ operand is a pointer to member function with ref-qualifier &&. */
+ if (FUNCTION_REF_QUALIFIED (type))
+ {
+ bool lval = real_lvalue_p (datum);
+ if (lval && FUNCTION_RVALUE_QUALIFIED (type))
+ {
+ if (complain & tf_error)
+ error ("pointer-to-member-function type %qT requires an rvalue",
+ ptrmem_type);
+ return error_mark_node;
+ }
+ else if (!lval && !FUNCTION_RVALUE_QUALIFIED (type))
+ {
+ if (complain & tf_error)
+ error ("pointer-to-member-function type %qT requires an lvalue",
+ ptrmem_type);
+ return error_mark_node;
+ }
+ }
+ return build2 (OFFSET_REF, type, datum, component);
+ }
}
/* Return a tree node for the expression TYPENAME '(' PARMS ')'. */