static int ambi_op_p (enum tree_code);
static int unary_op_p (enum tree_code);
static void push_local_name (tree);
-static tree grok_reference_init (tree, tree, tree, tree *);
+static tree grok_reference_init (tree, tree, tree, tree *, int);
static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
int, int, tree);
+static int check_static_variable_definition (tree, tree);
static void record_unknown_type (tree, const char *);
static tree builtin_function_1 (tree, tree, bool);
static tree build_library_fn_1 (tree, enum tree_code, tree);
/* The binding level to which this entry is *currently* attached.
This is initially the binding level in which the goto appeared,
but is modified as scopes are closed. */
- struct cp_binding_level *binding_level;
+ cp_binding_level *binding_level;
/* The head of the names list that was current when the goto appeared,
or the inner scope popped. These are the decls that will *not* be
skipped when jumping to the label. */
/* The binding level to which the label is *currently* attached.
This is initially set to the binding level in which the label
is defined, but is modified as scopes are closed. */
- struct cp_binding_level *binding_level;
+ cp_binding_level *binding_level;
/* The head of the names list that was current when the label was
defined, or the inner scope popped. These are the decls that will
be skipped when jumping to the label. */
int n_template_parm_scopes = 0;
int seen_specialization_p = 0;
int innermost_specialization_p = 0;
- struct cp_binding_level *b;
+ cp_binding_level *b;
/* Scan through the template parameter scopes. */
for (b = current_binding_level;
void
objc_mark_locals_volatile (void *enclosing_blk)
{
- struct cp_binding_level *scope;
+ cp_binding_level *scope;
for (scope = current_binding_level;
scope && scope != enclosing_blk;
poplevel_named_label_1 (void **slot, void *data)
{
struct named_label_entry *ent = (struct named_label_entry *) *slot;
- struct cp_binding_level *bl = (struct cp_binding_level *) data;
- struct cp_binding_level *obl = bl->level_chain;
+ cp_binding_level *bl = (cp_binding_level *) data;
+ cp_binding_level *obl = bl->level_chain;
if (ent->binding_level == bl)
{
for (link = decls; link; link = TREE_CHAIN (link))
{
if (leaving_for_scope && TREE_CODE (link) == VAR_DECL
+ /* It's hard to make this ARM compatibility hack play nicely with
+ lambdas, and it really isn't necessary in C++11 mode. */
+ && cxx_dialect < cxx0x
&& DECL_NAME (link))
{
tree name = DECL_NAME (link);
int
wrapup_globals_for_namespace (tree name_space, void* data)
{
- struct cp_binding_level *level = NAMESPACE_LEVEL (name_space);
+ cp_binding_level *level = NAMESPACE_LEVEL (name_space);
VEC(tree,gc) *statics = level->static_decls;
tree *vec = VEC_address (tree, statics);
int len = VEC_length (tree, statics);
|| TREE_TYPE (olddecl) == error_mark_node)
return error_mark_node;
+ if (UDLIT_OPER_P (DECL_NAME (newdecl))
+ && UDLIT_OPER_P (DECL_NAME (olddecl)))
+ {
+ if (TREE_CODE (newdecl) == TEMPLATE_DECL
+ && TREE_CODE (olddecl) != TEMPLATE_DECL
+ && check_raw_literal_operator (olddecl))
+ error ("literal operator template %q+D conflicts with"
+ " raw literal operator %qD", newdecl, olddecl);
+ else if (TREE_CODE (newdecl) != TEMPLATE_DECL
+ && TREE_CODE (olddecl) == TEMPLATE_DECL
+ && check_raw_literal_operator (newdecl))
+ error ("raw literal operator %q+D conflicts with"
+ " literal operator template %qD", newdecl, olddecl);
+ }
+
if (DECL_P (olddecl)
&& TREE_CODE (newdecl) == FUNCTION_DECL
&& TREE_CODE (olddecl) == FUNCTION_DECL
if (DECL_BUILT_IN_CLASS (olddecl) == BUILT_IN_NORMAL
&& DECL_ANTICIPATED (olddecl)
&& TREE_NOTHROW (newdecl)
- && !TREE_NOTHROW (olddecl)
- && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != NULL_TREE
- && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != olddecl
- && types_match)
- TREE_NOTHROW (built_in_decls [DECL_FUNCTION_CODE (olddecl)]) = 1;
+ && !TREE_NOTHROW (olddecl))
+ {
+ enum built_in_function fncode = DECL_FUNCTION_CODE (olddecl);
+ tree tmpdecl = builtin_decl_explicit (fncode);
+ if (tmpdecl && tmpdecl != olddecl && types_match)
+ TREE_NOTHROW (tmpdecl) = 1;
+ }
/* Whether or not the builtin can throw exceptions has no
bearing on this declarator. */
error_at (DECL_SOURCE_LOCATION (newdecl), errmsg, newdecl);
if (DECL_NAME (olddecl) != NULL_TREE)
error ((DECL_INITIAL (olddecl) && namespace_bindings_p ())
- ? "%q+#D previously defined here"
- : "%q+#D previously declared here", olddecl);
+ ? G_("%q+#D previously defined here")
+ : G_("%q+#D previously declared here"), olddecl);
return error_mark_node;
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
error ("deleted definition of %qD", newdecl);
error ("after previous declaration %q+D", olddecl);
}
+ DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
}
/* Deal with C++: must preserve virtual function table size. */
tree oldtype = TREE_TYPE (olddecl);
tree newtype;
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ maybe_instantiate_noexcept (olddecl);
+
/* Merge the data types specified in the two decls. */
newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
/* If we're keeping the built-in definition, keep the rtl,
regardless of declaration matches. */
COPY_DECL_RTL (olddecl, newdecl);
+ if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
+ {
+ enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
+ switch (fncode)
+ {
+ /* If a compatible prototype of these builtin functions
+ is seen, assume the runtime implements it with the
+ expected semantics. */
+ case BUILT_IN_STPCPY:
+ if (builtin_decl_explicit_p (fncode))
+ set_builtin_decl_implicit_p (fncode, true);
+ break;
+ default:
+ break;
+ }
+ }
}
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
true if all is well. */
static bool
-check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names,
+check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
bool exited_omp, const location_t *locus)
{
- struct cp_binding_level *b;
+ cp_binding_level *b;
bool identified = false, saw_eh = false, saw_omp = false;
if (exited_omp)
tree new_decls, old_decls = (b == level ? names : NULL_TREE);
for (new_decls = b->names; new_decls != old_decls;
- new_decls = DECL_CHAIN (new_decls))
+ new_decls = (DECL_P (new_decls) ? DECL_CHAIN (new_decls)
+ : TREE_CHAIN (new_decls)))
{
int problem = decl_jump_unsafe (new_decls);
if (! problem)
}
static bool
-check_switch_goto (struct cp_binding_level* level)
+check_switch_goto (cp_binding_level* level)
{
return check_previous_goto_1 (NULL_TREE, level, level->names, false, NULL);
}
error (" enters OpenMP structured block");
else if (flag_openmp)
{
- struct cp_binding_level *b;
+ cp_binding_level *b;
for (b = current_binding_level; b ; b = b->level_chain)
{
if (b == ent->binding_level)
bool
check_omp_return (void)
{
- struct cp_binding_level *b;
+ cp_binding_level *b;
for (b = current_binding_level; b ; b = b->level_chain)
if (b->kind == sk_omp)
{
error ("invalid exit from OpenMP structured block");
return false;
}
+ else if (b->kind == sk_function_parms)
+ break;
return true;
}
define_label_1 (location_t location, tree name)
{
struct named_label_entry *ent, dummy;
- struct cp_binding_level *p;
+ cp_binding_level *p;
tree decl;
decl = lookup_label (name);
struct cp_switch
{
- struct cp_binding_level *level;
+ cp_binding_level *level;
struct cp_switch *next;
/* The SWITCH_STMT being built. */
tree switch_stmt;
free (cs);
}
+/* Convert a case constant VALUE in a switch to the type TYPE of the switch
+ condition. Note that if TYPE and VALUE are already integral we don't
+ really do the conversion because the language-independent
+ warning/optimization code will work better that way. */
+
+static tree
+case_conversion (tree type, tree value)
+{
+ if (value == NULL_TREE)
+ return value;
+
+ if (cxx_dialect >= cxx0x
+ && (SCOPED_ENUM_P (type)
+ || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))))
+ {
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ type = type_promotes_to (type);
+ value = perform_implicit_conversion (type, value, tf_warning_or_error);
+ }
+ return cxx_constant_value (value);
+}
+
/* Note that we've seen a definition of a case label, and complain if this
is a bad place for one. */
finish_case_label (location_t loc, tree low_value, tree high_value)
{
tree cond, r;
- struct cp_binding_level *p;
+ cp_binding_level *p;
+ tree type;
if (processing_template_decl)
{
if (!check_switch_goto (switch_stack->level))
return error_mark_node;
- if (low_value)
- low_value = cxx_constant_value (low_value);
- if (high_value)
- high_value = cxx_constant_value (high_value);
+ type = SWITCH_STMT_TYPE (switch_stack->switch_stmt);
+
+ low_value = case_conversion (type, low_value);
+ high_value = case_conversion (type, high_value);
- r = c_add_case_label (loc, switch_stack->cases, cond,
- SWITCH_STMT_TYPE (switch_stack->switch_stmt),
+ r = c_add_case_label (loc, switch_stack->cases, cond, type,
low_value, high_value);
/* After labels, make any new cleanups in the function go into their
if (!t)
{
if (complain & tf_error)
- error (want_template ? "no class template named %q#T in %q#T"
- : "no type named %q#T in %q#T", name, context);
+ error (want_template ? G_("no class template named %q#T in %q#T")
+ : G_("no type named %q#T in %q#T"), name, context);
return error_mark_node;
}
tree void_ftype;
tree void_ftype_ptr;
- build_common_tree_nodes (flag_signed_char);
-
/* Create all the identifiers we need. */
initialize_predefined_identifiers ();
TREE_PUBLIC (global_namespace) = 1;
begin_scope (sk_namespace, global_namespace);
- current_lang_name = NULL_TREE;
-
if (flag_visibility_ms_compat)
default_visibility = VISIBILITY_HIDDEN;
init_list_type_node = make_node (LANG_TYPE);
record_unknown_type (init_list_type_node, "init list");
+ dependent_lambda_return_type_node = make_node (LANG_TYPE);
+ record_unknown_type (dependent_lambda_return_type_node,
+ "undeduced lambda return type");
+
{
/* Make sure we get a unique function type, so we can give
its pointer type a name. (This wins for gdb.) */
current_lang_name = lang_name_cplusplus;
{
+ tree newattrs, extvisattr;
tree newtype, deltype;
tree ptr_ftype_sizetype;
tree new_eh_spec;
else
new_eh_spec = noexcept_false_spec;
- newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec);
- deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
+ /* Ensure attribs.c is initialized. */
+ init_attributes ();
+ extvisattr = build_tree_list (get_identifier ("externally_visible"),
+ NULL_TREE);
+ newattrs = tree_cons (get_identifier ("alloc_size"),
+ build_tree_list (NULL_TREE, integer_one_node),
+ extvisattr);
+ newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs);
+ newtype = build_exception_variant (newtype, new_eh_spec);
+ deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
+ deltype = build_exception_variant (deltype, empty_except_spec);
push_cp_library_fn (NEW_EXPR, newtype);
push_cp_library_fn (VEC_NEW_EXPR, newtype);
global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
TYPE_UNSIGNED (nullptr_type_node) = 1;
TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
- SET_TYPE_MODE (nullptr_type_node, Pmode);
+ SET_TYPE_MODE (nullptr_type_node, ptr_mode);
record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
nullptr_node = build_int_cst (nullptr_type_node, 0);
}
if (current_function_decl)
{
- struct cp_binding_level *b = current_binding_level;
+ cp_binding_level *b = current_binding_level;
if (b->kind == sk_function_parms)
return error_mark_node;
while (b->level_chain->kind != sk_function_parms)
Quotes on semantics can be found in ARM 8.4.3. */
static tree
-grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
+grok_reference_init (tree decl, tree type, tree init, tree *cleanup,
+ int flags)
{
tree tmp;
DECL_INITIAL for local references (instead assigning to them
explicitly); we need to allow the temporary to be initialized
first. */
- tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error);
+ tmp = initialize_reference (type, init, decl, cleanup, flags,
+ tf_warning_or_error);
+ if (DECL_DECLARED_CONSTEXPR_P (decl))
+ {
+ tmp = cxx_constant_value (tmp);
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
+ = reduced_constant_expression_p (tmp);
+ }
if (tmp == error_mark_node)
return NULL_TREE;
is valid, i.e., does not have a designated initializer. */
static bool
-check_array_designated_initializer (const constructor_elt *ce)
+check_array_designated_initializer (const constructor_elt *ce,
+ unsigned HOST_WIDE_INT index)
{
/* Designated initializers for array elements are not supported. */
if (ce->index)
error ("name used in a GNU-style designated "
"initializer for an array");
else if (TREE_CODE (ce->index) == INTEGER_CST)
- /* An index added by reshape_init. */
- return true;
+ {
+ /* A C99 designator is OK if it matches the current index. */
+ if (TREE_INT_CST_LOW (ce->index) == index)
+ return true;
+ else
+ sorry ("non-trivial designated initializers not supported");
+ }
else
{
gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
constructor_elt *ce;
HOST_WIDE_INT i;
FOR_EACH_VEC_ELT (constructor_elt, v, i, ce)
- if (!check_array_designated_initializer (ce))
+ if (!check_array_designated_initializer (ce, i))
failure = 1;
}
if (TREE_CODE (decl) == VAR_DECL
&& TREE_CODE (type) != REFERENCE_TYPE
&& CP_TYPE_CONST_P (type)
- && (!TYPE_NEEDS_CONSTRUCTING (type)
- || !type_has_user_provided_default_constructor (type))
&& !DECL_INITIAL (decl))
{
+ tree field = default_init_uninitialized_part (type);
+ if (!field)
+ return;
+
permerror (DECL_SOURCE_LOCATION (decl),
"uninitialized const %qD", decl);
- if (CLASS_TYPE_P (type)
- && !type_has_user_provided_default_constructor (type))
+ if (CLASS_TYPE_P (type))
{
tree defaulted_ctor;
inform (DECL_SOURCE_LOCATION (defaulted_ctor),
"constructor is not user-provided because it is "
"explicitly defaulted in the class body");
+ inform (0, "and the implicitly-defined constructor does not "
+ "initialize %q+#D", field);
}
}
}
{
tree elt_init;
- check_array_designated_initializer (d->cur);
+ check_array_designated_initializer (d->cur, index);
elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
complain);
if (elt_init == error_mark_node)
{
int saved_stmts_are_full_exprs_p = 0;
- if (building_stmt_tree ())
+ if (building_stmt_list_p ())
{
saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
}
init = build_aggr_init (decl, init, flags, tf_warning_or_error);
- if (building_stmt_tree ())
+ if (building_stmt_list_p ())
current_stmt_tree ()->stmts_are_full_exprs_p =
saved_stmts_are_full_exprs_p;
return init;
type. */
TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl));
+ if (DECL_HAS_VALUE_EXPR_P (decl))
+ {
+ /* A variable with DECL_HAS_VALUE_EXPR_P set is just a placeholder,
+ it doesn't have storage to be initialized. */
+ gcc_assert (init == NULL_TREE);
+ return NULL_TREE;
+ }
+
if (type == error_mark_node)
/* We will have already complained. */
return NULL_TREE;
else if (!init && DECL_REALLY_EXTERN (decl))
;
else if (TREE_CODE (type) == REFERENCE_TYPE)
- init = grok_reference_init (decl, type, init, cleanup);
- else if (init || TYPE_NEEDS_CONSTRUCTING (type))
+ init = grok_reference_init (decl, type, init, cleanup, flags);
+ else if (init || type_build_ctor_call (type))
{
if (!init)
check_for_uninitialized_const_var (decl);
init = error_mark_node;
}
else
- init = reshape_init (type, init, tf_warning_or_error);
+ {
+ init = reshape_init (type, init, tf_warning_or_error);
+ if (cxx_dialect >= cxx0x && SCALAR_TYPE_P (type))
+ check_narrowing (type, init);
+ }
}
/* If DECL has an array type without a specific bound, deduce the
if (type == error_mark_node)
return NULL_TREE;
- if (TYPE_NEEDS_CONSTRUCTING (type)
+ if (type_build_ctor_call (type)
|| (CLASS_TYPE_P (type)
&& !(init && BRACE_ENCLOSED_INITIALIZER_P (init))))
{
static tree
wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data)
{
- if (TYPE_P (*stmt_p))
+ /* Stop at types or full-expression boundaries. */
+ if (TYPE_P (*stmt_p)
+ || TREE_CODE (*stmt_p) == CLEANUP_POINT_EXPR)
{
*walk_subtrees = 0;
return NULL_TREE;
if (cleanup && TREE_CODE (type) != ARRAY_TYPE)
wrap_temporary_cleanups (init, cleanup);
- gcc_assert (building_stmt_tree ());
+ gcc_assert (building_stmt_list_p ());
saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
finish_expr_stmt (init);
cleanup = NULL_TREE;
/* If a name was specified, get the string. */
- if (global_scope_p (current_binding_level))
+ if (at_namespace_scope_p ())
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
if (asmspec_tree && asmspec_tree != error_mark_node)
asmspec = TREE_STRING_POINTER (asmspec_tree);
if (current_class_type
&& CP_DECL_CONTEXT (decl) == current_class_type
&& TYPE_BEING_DEFINED (current_class_type)
+ && !CLASSTYPE_TEMPLATE_INSTANTIATION (current_class_type)
&& (DECL_INITIAL (decl) || init))
DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
d_init = build_x_compound_expr_from_list (d_init, ELK_INIT,
tf_warning_or_error);
d_init = resolve_nondeduced_context (d_init);
- if (describable_type (d_init))
- {
- type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
- auto_node);
- if (type == error_mark_node)
- return;
- }
+ type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
+ auto_node);
+ if (type == error_mark_node)
+ return;
}
- if (TREE_CODE (decl) == FUNCTION_DECL
- /* For members, defer until finalize_literal_type_property. */
- && (!DECL_CLASS_SCOPE_P (decl)
- || !TYPE_BEING_DEFINED (DECL_CONTEXT (decl))))
- validate_constexpr_fundecl (decl);
-
- else if (!ensure_literal_type_for_constexpr_object (decl))
+ if (!ensure_literal_type_for_constexpr_object (decl))
DECL_DECLARED_CONSTEXPR_P (decl) = 0;
+ if (TREE_CODE (decl) == VAR_DECL
+ && DECL_CLASS_SCOPE_P (decl)
+ && DECL_INITIALIZED_IN_CLASS_P (decl))
+ check_static_variable_definition (decl, type);
+
if (init && TREE_CODE (decl) == FUNCTION_DECL)
{
tree clone;
if (init && TREE_CODE (decl) == VAR_DECL)
{
DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+ /* If DECL is a reference, then we want to know whether init is a
+ reference constant; init_const_expr_p as passed tells us whether
+ it's an rvalue constant. */
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ init_const_expr_p = potential_constant_expression (init);
if (init_const_expr_p)
{
/* Set these flags now for templates. We'll update the flags in
return;
}
+ /* Just store non-static data member initializers for later. */
+ if (init && TREE_CODE (decl) == FIELD_DECL)
+ DECL_INITIAL (decl) = init;
+
/* Take care of TYPE_DECLs up front. */
if (TREE_CODE (decl) == TYPE_DECL)
{
/* Add this declaration to the statement-tree. This needs to happen
after the call to check_initializer so that the DECL_EXPR for a
reference temp is added before the DECL_EXPR for the reference itself. */
- if (at_function_scope_p ())
+ if (DECL_FUNCTION_SCOPE_P (decl))
add_decl_expr (decl);
/* Let the middle end know about variables and functions -- but not
if (was_readonly)
TREE_READONLY (decl) = 1;
+
+ invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
}
/* Returns a declaration for a VAR_DECL as if:
dso_handle_node = declare_global_var (get_identifier ("__dso_handle"),
ptr_type_node);
+#ifdef HAVE_GAS_HIDDEN
+ DECL_VISIBILITY (dso_handle_node) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (dso_handle_node) = 1;
+#endif
+
return dso_handle_node;
}
tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE;
tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
tree guard, guard_addr;
- tree acquire_fn, release_fn, abort_fn;
tree flag, begin;
/* Emit code to perform this initialization but once. This code
if (flag_threadsafe_statics)
{
+ tree vfntype = NULL_TREE;
+ tree acquire_name, release_name, abort_name;
+ tree acquire_fn, release_fn, abort_fn;
guard_addr = build_address (guard);
- acquire_fn = get_identifier ("__cxa_guard_acquire");
- release_fn = get_identifier ("__cxa_guard_release");
- abort_fn = get_identifier ("__cxa_guard_abort");
- if (!get_global_value_if_present (acquire_fn, &acquire_fn))
- {
- tree vfntype = build_function_type_list (void_type_node,
- TREE_TYPE (guard_addr),
- NULL_TREE);
- acquire_fn = push_library_fn
- (acquire_fn, build_function_type_list (integer_type_node,
+ acquire_name = get_identifier ("__cxa_guard_acquire");
+ release_name = get_identifier ("__cxa_guard_release");
+ abort_name = get_identifier ("__cxa_guard_abort");
+ acquire_fn = identifier_global_value (acquire_name);
+ release_fn = identifier_global_value (release_name);
+ abort_fn = identifier_global_value (abort_name);
+ if (!acquire_fn)
+ acquire_fn = push_library_fn
+ (acquire_name, build_function_type_list (integer_type_node,
TREE_TYPE (guard_addr),
NULL_TREE),
- NULL_TREE);
- release_fn = push_library_fn (release_fn, vfntype, NULL_TREE);
- abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE);
- }
- else
- {
- release_fn = identifier_global_value (release_fn);
- abort_fn = identifier_global_value (abort_fn);
- }
+ NULL_TREE);
+ if (!release_fn || !abort_fn)
+ vfntype = build_function_type_list (void_type_node,
+ TREE_TYPE (guard_addr),
+ NULL_TREE);
+ if (!release_fn)
+ release_fn = push_library_fn (release_name, vfntype, NULL_TREE);
+ if (!abort_fn)
+ abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE);
inner_if_stmt = begin_if_stmt ();
finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
tree parm;
cp_cv_quals this_quals;
- this_type = type_of_this_parm (type);
+ if (CLASS_TYPE_P (type))
+ {
+ this_type
+ = cp_build_qualified_type (type, quals & ~TYPE_QUAL_RESTRICT);
+ this_type = build_pointer_type (this_type);
+ }
+ else
+ this_type = type_of_this_parm (type);
/* The `this' parameter is implicitly `const'; it cannot be
assigned to. */
this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
return parm;
}
+/* DECL is a static member function. Complain if it was declared
+ with function-cv-quals. */
+
+static void
+check_static_quals (tree decl, cp_cv_quals quals)
+{
+ if (quals != TYPE_UNQUALIFIED)
+ error ("static member function %q#D declared with type qualifiers",
+ decl);
+}
+
/* CTYPE is class type, or null if non-class.
TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
or METHOD_TYPE.
if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))
&& !grok_op_properties (decl, /*complain=*/true))
return NULL_TREE;
+ else if (UDLIT_OPER_P (DECL_NAME (decl)))
+ {
+ bool long_long_unsigned_p;
+ bool long_double_p;
+ const char *suffix = NULL;
+ /* [over.literal]/6: Literal operators shall not have C linkage. */
+ if (DECL_LANGUAGE (decl) == lang_c)
+ {
+ error ("literal operator with C linkage");
+ return NULL_TREE;
+ }
+
+ if (DECL_NAMESPACE_SCOPE_P (decl))
+ {
+ if (!check_literal_operator_args (decl, &long_long_unsigned_p,
+ &long_double_p))
+ {
+ error ("%qD has invalid argument list", decl);
+ return NULL_TREE;
+ }
+
+ suffix = UDLIT_OP_SUFFIX (DECL_NAME (decl));
+ if (long_long_unsigned_p)
+ {
+ if (cpp_interpret_int_suffix (suffix, strlen (suffix)))
+ warning (0, "integer suffix %<%s%>"
+ " shadowed by implementation", suffix);
+ }
+ else if (long_double_p)
+ {
+ if (cpp_interpret_float_suffix (suffix, strlen (suffix)))
+ warning (0, "floating point suffix %<%s%>"
+ " shadowed by implementation", suffix);
+ }
+ }
+ else
+ {
+ error ("%qD must be a non-member function", decl);
+ return NULL_TREE;
+ }
+ }
if (funcdef_flag)
/* Make the init_value nonzero so pushdecl knows this is not
if (decl == error_mark_node)
return NULL_TREE;
+ if (DECL_STATIC_FUNCTION_P (decl))
+ check_static_quals (decl, quals);
+
if (attrlist)
{
cplus_decl_attributes (&decl, *attrlist, 0);
if (DECL_STATIC_FUNCTION_P (old_decl)
&& TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
- /* Remove the `this' parm added by grokclassfn.
- XXX Isn't this done in start_function, too? */
- revert_static_member_fn (decl);
+ {
+ /* Remove the `this' parm added by grokclassfn. */
+ revert_static_member_fn (decl);
+ check_static_quals (decl, quals);
+ }
if (DECL_ARTIFICIAL (old_decl))
{
error ("definition of implicitly-declared %qD", old_decl);
return NULL_TREE;
}
+ else if (DECL_DEFAULTED_FN (old_decl))
+ {
+ error ("definition of explicitly-defaulted %q+D", decl);
+ error ("%q+#D explicitly defaulted here", old_decl);
+ return NULL_TREE;
+ }
/* Since we've smashed OLD_DECL to its
DECL_TEMPLATE_RESULT, we must do the same to DECL. */
messages. Return 1 if the definition is particularly bad, or 0
otherwise. */
-int
+static int
check_static_variable_definition (tree decl, tree type)
{
+ /* Can't check yet if we don't know the type. */
+ if (dependent_type_p (type))
+ return 0;
/* If DECL is declared constexpr, we'll do the appropriate checks
in check_initializer. */
if (DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl))
else if (cxx_dialect >= cxx0x && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
{
if (literal_type_p (type))
- error ("%<constexpr%> needed for in-class initialization of static "
- "data member %q#D of non-integral type", decl);
+ permerror (input_location,
+ "%<constexpr%> needed for in-class initialization of "
+ "static data member %q#D of non-integral type", decl);
else
error ("in-class initialization of static data member %q#D of "
"non-literal type", decl);
if (type == error_mark_node || size == error_mark_node)
return error_mark_node;
+ /* 8.3.4/1: If the type of the identifier of D contains the auto
+ type-specifier, the program is ill-formed. */
+ if (pedantic && type_uses_auto (type))
+ pedwarn (input_location, OPT_pedantic,
+ "declaration of %qD as array of %<auto%>", name);
+
/* If there are some types which cannot be array elements,
issue an error-message and return. */
switch (TREE_CODE (type))
else if (TYPE_P (qualifying_scope))
{
ctype = qualifying_scope;
- if (innermost_code != cdk_function
- && current_class_type
- && !UNIQUELY_DERIVED_FROM_P (ctype,
- current_class_type))
+ if (!MAYBE_CLASS_TYPE_P (ctype))
+ {
+ error ("%q#T is not a class or a namespace", ctype);
+ ctype = NULL_TREE;
+ }
+ else if (innermost_code != cdk_function
+ && current_class_type
+ && !UNIQUELY_DERIVED_FROM_P (ctype,
+ current_class_type))
{
error ("type %qT is not derived from type %qT",
ctype, current_class_type);
error ("declaration of %qD as non-function", dname);
return error_mark_node;
}
+
+ if (dname
+ && TREE_CODE (dname) == IDENTIFIER_NODE
+ && UDLIT_OPER_P (dname)
+ && innermost_code != cdk_function)
+ {
+ error ("declaration of %qD as non-function", dname);
+ return error_mark_node;
+ }
+
+ if (dname && IDENTIFIER_OPNAME_P (dname))
+ {
+ if (declspecs->specs[(int)ds_typedef])
+ {
+ error ("declaration of %qD as %<typedef%>", dname);
+ return error_mark_node;
+ }
+ else if (decl_context == PARM || decl_context == CATCHPARM)
+ {
+ error ("declaration of %qD as parameter", dname);
+ return error_mark_node;
+ }
+ }
/* Anything declared one level down from the top level
must be one of the parameters of a function
if (decl_context == NORMAL && !toplevel_bindings_p ())
{
- struct cp_binding_level *b = current_binding_level;
+ cp_binding_level *b = current_binding_level;
current_binding_level = b->level_chain;
if (current_binding_level != 0 && toplevel_bindings_p ())
decl_context = PARM;
ctype = NULL_TREE;
+ if (explicit_int128)
+ {
+ if (int128_integer_type_node == NULL_TREE)
+ {
+ error ("%<__int128%> is not supported by this target");
+ explicit_int128 = false;
+ }
+ else if (pedantic && ! in_system_header)
+ pedwarn (input_location, OPT_pedantic,
+ "ISO C++ does not support %<__int128%> for %qs", name);
+ }
+
/* Now process the modifiers that were specified
and check for invalid combinations. */
error ("%<signed%> and %<unsigned%> specified together for %qs", name);
else if (longlong && TREE_CODE (type) != INTEGER_TYPE)
error ("%<long long%> invalid for %qs", name);
- else if (explicit_int128 && TREE_CODE (type) != INTEGER_TYPE)
- error ("%<__int128%> invalid for %qs", name);
else if (long_p && TREE_CODE (type) == REAL_TYPE)
error ("%<long%> invalid for %qs", name);
else if (short_p && TREE_CODE (type) == REAL_TYPE)
if (flag_pedantic_errors)
ok = 0;
}
- if (explicit_int128)
- {
- if (int128_integer_type_node == NULL_TREE)
- {
- error ("%<__int128%> is not supported by this target");
- ok = 0;
- }
- else if (pedantic)
- {
- pedwarn (input_location, OPT_pedantic,
- "ISO C++ does not support %<__int128%> for %qs",
- name);
- if (flag_pedantic_errors)
- ok = 0;
- }
- }
}
/* Discard the type modifiers if they are invalid. */
long_p = false;
short_p = false;
longlong = 0;
- explicit_int128 = false;
}
}
|| thread_p)
error ("storage class specifiers invalid in parameter declarations");
- if (type_uses_auto (type))
- {
- error ("parameter declared %<auto%>");
- type = error_mark_node;
- }
-
/* Function parameters cannot be constexpr. If we saw one, moan
and pretend it wasn't there. */
if (constexpr_p)
virt_specifiers = declarator->u.function.virt_specifiers;
/* Pick up the exception specifications. */
raises = declarator->u.function.exception_specification;
+ /* If the exception-specification is ill-formed, let's pretend
+ there wasn't one. */
+ if (raises == error_mark_node)
+ raises = NULL_TREE;
/* Say it's a definition only for the CALL_EXPR
closest to the identifier. */
virtual. A constructor may not be static. */
if (staticp == 2)
error ((flags == DTOR_FLAG)
- ? "destructor cannot be static member function"
- : "constructor cannot be static member function");
+ ? G_("destructor cannot be static member function")
+ : G_("constructor cannot be static member function"));
if (memfn_quals)
{
error ((flags == DTOR_FLAG)
- ? "destructors may not be cv-qualified"
- : "constructors may not be cv-qualified");
+ ? G_("destructors may not be cv-qualified")
+ : G_("constructors may not be cv-qualified"));
memfn_quals = TYPE_UNQUALIFIED;
}
to create the type "rvalue reference to cv TD' creates the
type TD."
*/
- if (!VOID_TYPE_P (type))
+ if (VOID_TYPE_P (type))
+ /* We already gave an error. */;
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (declarator->u.reference.rvalue_ref)
+ /* Leave type alone. */;
+ else
+ type = cp_build_reference_type (TREE_TYPE (type), false);
+ }
+ else
type = cp_build_reference_type
- ((TREE_CODE (type) == REFERENCE_TYPE
- ? TREE_TYPE (type) : type),
- (declarator->u.reference.rvalue_ref
- && (TREE_CODE(type) != REFERENCE_TYPE
- || TYPE_REF_IS_RVALUE (type))));
+ (type, declarator->u.reference.rvalue_ref);
/* In C++0x, we need this check for direct reference to
reference declarations, which are forbidden by
error ("both %<const%> and %<constexpr%> cannot be used here");
if (type_quals & TYPE_QUAL_VOLATILE)
error ("both %<volatile%> and %<constexpr%> cannot be used here");
- type_quals |= TYPE_QUAL_CONST;
- type = cp_build_qualified_type (type, type_quals);
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ {
+ type_quals |= TYPE_QUAL_CONST;
+ type = cp_build_qualified_type (type, type_quals);
+ }
}
if (unqualified_id && TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR
would not have exited the loop above. */
if (declarator
&& declarator->u.id.qualifying_scope
- && TYPE_P (declarator->u.id.qualifying_scope))
+ && MAYBE_CLASS_TYPE_P (declarator->u.id.qualifying_scope))
{
tree t;
&& (!friendp || funcdef_flag))
{
error (funcdef_flag
- ? "cannot define member function %<%T::%s%> within %<%T%>"
- : "cannot declare member function %<%T::%s%> within %<%T%>",
+ ? G_("cannot define member function %<%T::%s%> "
+ "within %<%T%>")
+ : G_("cannot declare member function %<%T::%s%> "
+ "within %<%T%>"),
ctype, name, current_class_type);
return error_mark_node;
}
if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
ctype = current_class_type;
- /* A constexpr non-static member function is implicitly const. */
- if (constexpr_p && ctype && staticp == 0
- && TREE_CODE (type) == FUNCTION_TYPE
- && sfk != sfk_constructor && sfk != sfk_destructor)
- memfn_quals |= TYPE_QUAL_CONST;
-
/* Now TYPE has the actual type. */
if (returned_attrs)
memfn_quals = TYPE_UNQUALIFIED;
}
+ if (type_uses_auto (type))
+ {
+ error ("typedef declared %<auto%>");
+ type = error_mark_node;
+ }
+
if (decl_context == FIELD)
decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
else
&& TYPE_NAME (type)
&& TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
&& TYPE_ANONYMOUS_P (type)
+ && declspecs->type_definition_p
&& cp_type_quals (type) == TYPE_UNQUALIFIED)
{
tree t;
if (ctype || in_namespace)
error ("cannot use %<::%> in parameter declaration");
+ if (type_uses_auto (type))
+ {
+ error ("parameter declared %<auto%>");
+ type = error_mark_node;
+ }
+
/* A parameter declared as an array of T is really a pointer to T.
One declared as a function is really a pointer to a function.
One declared as a member is really a pointer to member. */
if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
&& !NEW_DELETE_OPNAME_P (unqualified_id))
- type = build_memfn_type (type, ctype, memfn_quals);
+ {
+ 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);
+ }
{
tree decl;
instantiation made the field's type be incomplete. */
if (current_class_type
&& TYPE_NAME (current_class_type)
- && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type))
+ && IDENTIFIER_TEMPLATE (current_class_name)
&& declspecs->type
&& declspecs->type == type)
error (" in instantiation of template %qT",
return error_mark_node;
}
- DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
decl = do_friend (ctype, unqualified_id, decl,
*attrlist, flags,
funcdef_flag);
if (decl == NULL_TREE)
{
- if (initialized)
- {
- if (!staticp)
- {
- /* An attempt is being made to initialize a non-static
- member. But, from [class.mem]:
-
- 4 A member-declarator can contain a
- constant-initializer only if it declares a static
- member (_class.static_) of integral or enumeration
- type, see _class.static.data_.
-
- This used to be relatively common practice, but
- the rest of the compiler does not correctly
- handle the initialization unless the member is
- static so we make it static below. */
- if (cxx_dialect >= cxx0x)
- {
- sorry ("non-static data member initializers");
- }
- else
- {
- permerror (input_location, "ISO C++ forbids initialization of member %qD",
- unqualified_id);
- permerror (input_location, "making %qD static", unqualified_id);
- staticp = 1;
- }
- }
-
- if (uses_template_parms (type))
- /* We'll check at instantiation time. */
- ;
- else if (constexpr_p)
- /* constexpr has the same requirements. */
- ;
- else if (check_static_variable_definition (unqualified_id,
- type))
- /* If we just return the declaration, crashes
- will sometimes occur. We therefore return
- void_type_node, as if this was a friend
- declaration, to cause callers to completely
- ignore this declaration. */
- return error_mark_node;
- }
-
if (staticp)
{
/* C++ allows static class members. All other work
DECL_MUTABLE_P (decl) = 1;
storage_class = sc_none;
}
+
+ if (initialized)
+ /* An attempt is being made to initialize a non-static
+ member. This is new in C++11. */
+ maybe_warn_cpp0x (CPP0X_NSDMI);
}
bad_specifiers (decl, BSP_FIELD, virtualp,
"declared out of global scope", name);
}
- if (ctype != NULL_TREE
- && TREE_CODE (ctype) != NAMESPACE_DECL && !MAYBE_CLASS_TYPE_P (ctype))
- {
- error ("%q#T is not a class or a namespace", ctype);
- ctype = NULL_TREE;
- }
-
if (ctype == NULL_TREE)
{
if (virtualp)
|| sfk == sfk_destructor)
{
error (funcdef_flag
- ? "%qs defined in a non-class scope"
- : "%qs declared in a non-class scope", name);
+ ? G_("%qs defined in a non-class scope")
+ : G_("%qs declared in a non-class scope"), name);
sfk = sfk_none;
}
}
}
}
else if (constexpr_p && DECL_EXTERNAL (decl))
- error ("declaration of constexpr variable %qD is not a definition",
- decl);
+ {
+ error ("declaration of constexpr variable %qD is not a definition",
+ decl);
+ constexpr_p = false;
+ }
}
if (storage_class == sc_extern && initialized && !funcdef_flag)
else if (storage_class == sc_static)
DECL_THIS_STATIC (decl) = 1;
- /* Don't forget constexprness. */
- if (constexpr_p)
+ /* Set constexpr flag on vars (functions got it in grokfndecl). */
+ if (constexpr_p && TREE_CODE (decl) == VAR_DECL)
DECL_DECLARED_CONSTEXPR_P (decl) = true;
/* Record constancy and volatility on the DECL itself . There's
init = check_default_argument (decl, init);
}
- if (TREE_CODE (decl) == PARM_DECL
- && FUNCTION_PARAMETER_PACK_P (decl)
- && TREE_CHAIN (parm)
- && TREE_CHAIN (parm) != void_list_node)
- error ("parameter packs must be at the end of the parameter list");
-
DECL_CHAIN (decl) = decls;
decls = decl;
result = tree_cons (init, type, result);
tag_scope scope, bool template_header_p)
{
tree ret;
- timevar_start (TV_NAME_LOOKUP);
+ bool subtime;
+ subtime = timevar_cond_start (TV_NAME_LOOKUP);
ret = xref_tag_1 (tag_code, name, scope, template_header_p);
- timevar_stop (TV_NAME_LOOKUP);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
return ret;
}
tree prev_value;
bool overflowed;
- /* The next value is the previous value plus one.
- add_double doesn't know the type of the target expression,
- so we must check with int_fits_type_p as well. */
+ /* C++03 7.2/4: If no initializer is specified for the first
+ enumerator, the type is an unspecified integral
+ type. Otherwise the type is the same as the type of the
+ initializing value of the preceding enumerator unless the
+ incremented value is not representable in that type, in
+ which case the type is an unspecified integral type
+ sufficient to contain the incremented value. */
prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
if (error_operand_p (prev_value))
value = error_mark_node;
overflowed = add_double (TREE_INT_CST_LOW (prev_value),
TREE_INT_CST_HIGH (prev_value),
1, 0, &lo, &hi);
- value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi);
- overflowed
- |= !int_fits_type_p (value, TREE_TYPE (prev_value));
+ if (!overflowed)
+ {
+ double_int di;
+ tree type = TREE_TYPE (prev_value);
+ bool pos = (TYPE_UNSIGNED (type) || hi >= 0);
+ di.low = lo; di.high = hi;
+ if (!double_int_fits_to_tree_p (type, di))
+ {
+ unsigned int itk;
+ for (itk = itk_int; itk != itk_none; itk++)
+ {
+ type = integer_types[itk];
+ if (type != NULL_TREE
+ && (pos || !TYPE_UNSIGNED (type))
+ && double_int_fits_to_tree_p (type, di))
+ break;
+ }
+ if (type && cxx_dialect < cxx0x
+ && itk > itk_unsigned_long)
+ pedwarn (input_location, OPT_Wlong_long, pos ? "\
+incremented enumerator value is too large for %<unsigned long%>" : "\
+incremented enumerator value is too large for %<long%>");
+ }
+ if (type == NULL_TREE)
+ overflowed = true;
+ else
+ value = double_int_to_tree (type, di);
+ }
if (overflowed)
{
tree fntype;
tree restype;
int doing_friend = 0;
- struct cp_binding_level *bl;
+ cp_binding_level *bl;
tree current_function_parms;
struct c_fileinfo *finfo
= get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
/* Sometimes we don't notice that a function is a static member, and
build a METHOD_TYPE for it. Fix that up now. */
- if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
- && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE)
- {
- revert_static_member_fn (decl1);
- ctype = NULL_TREE;
- }
+ gcc_assert (!(ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
+ && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE));
/* Set up current_class_type, and enter the scope of the class, if
appropriate. */
maybe_apply_pragma_weak (decl1);
}
- /* constexpr functions must have literal argument types and
- literal return type. */
- validate_constexpr_fundecl (decl1);
-
/* Reset this in case the call to pushdecl changed it. */
current_function_decl = decl1;
cp_function_chain->x_current_class_ref
= cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
+ /* Set this second to avoid shortcut in cp_build_indirect_ref. */
cp_function_chain->x_current_class_ptr = t;
/* Constructors and destructors need to know whether they're "in
compiler-generated functions. */
&& !DECL_ARTIFICIAL (decl1));
- if (DECL_INTERFACE_KNOWN (decl1))
+ if (processing_template_decl)
+ /* Don't mess with interface flags. */;
+ else if (DECL_INTERFACE_KNOWN (decl1))
{
tree ctx = decl_function_context (decl1);
else if (!finfo->interface_unknown && honor_interface)
{
if (DECL_DECLARED_INLINE_P (decl1)
- || DECL_TEMPLATE_INSTANTIATION (decl1)
- || processing_template_decl)
+ || DECL_TEMPLATE_INSTANTIATION (decl1))
{
DECL_EXTERNAL (decl1)
= (finfo->interface_only
not creating the EH_SPEC_BLOCK we save a little memory,
and we avoid spurious warnings about unreachable
code. */
- && !DECL_ARTIFICIAL (fn));
+ && !DECL_DEFAULTED_FN (fn));
}
/* Store the parameter declarations into the current function declaration.
DECL_SAVED_FUNCTION_DATA (decl) = f;
/* Clear out the bits we don't need. */
- f->base.x_stmt_tree.x_cur_stmt_list = NULL_TREE;
+ f->base.x_stmt_tree.x_cur_stmt_list = NULL;
f->bindings = NULL;
f->x_local_names = NULL;
}
/* Do the necessary processing for the beginning of a function body, which
in this case includes member-initializers, but not the catch clauses of
a function-try-block. Currently, this means opening a binding level
- for the member-initializers (in a ctor) and member cleanups (in a dtor). */
+ for the member-initializers (in a ctor), member cleanups (in a dtor),
+ and capture proxies (in a lambda operator()). */
tree
begin_function_body (void)
This caused &foo to be of type ptr-to-const-function
which then got a warning when stored in a ptr-to-function variable. */
- gcc_assert (building_stmt_tree ());
+ gcc_assert (building_stmt_list_p ());
/* The current function is being defined, so its DECL_INITIAL should
be set, and unless there's a multiple definition, it should be
error_mark_node. */
{
if (DECL_MAIN_P (current_function_decl))
{
- tree stmt;
-
/* Make it so that `main' always returns 0 by default (or
1 for VMS). */
#if VMS_TARGET
- stmt = finish_return_stmt (integer_one_node);
+ finish_return_stmt (integer_one_node);
#else
- stmt = finish_return_stmt (integer_zero_node);
+ finish_return_stmt (integer_zero_node);
#endif
- /* Hack. We don't want the middle-end to warn that this
- return is unreachable, so put the statement on the
- special line 0. */
- {
- location_t linezero = linemap_line_start (line_table, 0, 1);
- SET_EXPR_LOCATION (stmt, linezero);
- }
}
if (use_eh_spec_block (current_function_decl))
unused_but_set_errorcount = errorcount;
}
+ /* Complain about locally defined typedefs that are not used in this
+ function. */
+ maybe_warn_unused_local_typedefs ();
+
/* Genericize before inlining. */
if (!processing_template_decl)
{
revert_static_member_fn (tree decl)
{
tree stype = static_fn_type (decl);
+ cp_cv_quals quals = type_memfn_quals (stype);
+
+ if (quals != TYPE_UNQUALIFIED)
+ stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
- if (type_memfn_quals (stype) != TYPE_UNQUALIFIED)
- {
- error ("static member function %q#D declared with type qualifiers", decl);
- stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
- }
TREE_TYPE (decl) = stype;
if (DECL_ARGUMENTS (decl))
switch (TREE_CODE (&t->generic))
{
case DEFAULT_ARG: return TS_CP_DEFAULT_ARG;
+ case DEFERRED_NOEXCEPT: return TS_CP_DEFERRED_NOEXCEPT;
case IDENTIFIER_NODE: return TS_CP_IDENTIFIER;
case OVERLOAD: return TS_CP_OVERLOAD;
case TEMPLATE_PARM_INDEX: return TS_CP_TPI;
case TRAIT_EXPR: return TS_CP_TRAIT_EXPR;
case LAMBDA_EXPR: return TS_CP_LAMBDA_EXPR;
case TEMPLATE_INFO: return TS_CP_TEMPLATE_INFO;
+ case USERDEF_LITERAL: return TS_CP_USERDEF_LITERAL;
default: return TS_CP_GENERIC;
}
}