#include "expr.h"
#include "flags.h"
#include "cp-tree.h"
-#include "tree-iterator.h"
#include "tree-inline.h"
#include "decl.h"
#include "intl.h"
return 1;
}
-/* Saved errorcount to avoid -Wunused-but-set-{parameter,variable} warnings
- when errors were reported, except for -Werror-unused-but-set-*. */
-static int unused_but_set_errorcount;
-
/* Exit a binding level.
Pop the level off, and restore the state of the identifier-decl mappings
that were in effect when this level was entered.
= current_binding_level->kind == sk_for && flag_new_for_scope == 1;
/* Before we remove the declarations first check for unused variables. */
- if ((warn_unused_variable || warn_unused_but_set_variable)
+ if (warn_unused_variable
&& !processing_template_decl)
for (decl = getdecls (); decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == VAR_DECL
- && (! TREE_USED (decl) || !DECL_READ_P (decl))
+ && ! TREE_USED (decl)
&& ! DECL_IN_SYSTEM_HEADER (decl)
&& DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
- {
- if (! TREE_USED (decl))
- warning (OPT_Wunused_variable, "unused variable %q+D", decl);
- else if (DECL_CONTEXT (decl) == current_function_decl
- && TREE_TYPE (decl) != error_mark_node
- && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
- && errorcount == unused_but_set_errorcount
- && (!CLASS_TYPE_P (TREE_TYPE (decl))
- || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
- {
- warning (OPT_Wunused_but_set_variable,
- "variable %q+D set but not used", decl);
- unused_but_set_errorcount = errorcount;
- }
- }
+ warning (OPT_Wunused_variable, "unused variable %q+D", decl);
/* Remove declarations for all the DECLs in this level. */
for (link = decls; link; link = TREE_CHAIN (link))
TREE_USED (newdecl) = 1;
else if (TREE_USED (newdecl))
TREE_USED (olddecl) = 1;
- if (TREE_CODE (newdecl) == VAR_DECL)
- {
- if (DECL_READ_P (olddecl))
- DECL_READ_P (newdecl) = 1;
- else if (DECL_READ_P (newdecl))
- DECL_READ_P (olddecl) = 1;
- }
if (DECL_PRESERVE_P (olddecl))
DECL_PRESERVE_P (newdecl) = 1;
else if (DECL_PRESERVE_P (newdecl))
/* C++ extensions */
- unknown_type_node = make_node (LANG_TYPE);
+ unknown_type_node = make_node (UNKNOWN_TYPE);
record_unknown_type (unknown_type_node, "unknown type");
/* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */
TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
- init_list_type_node = make_node (LANG_TYPE);
+ init_list_type_node = make_node (UNKNOWN_TYPE);
record_unknown_type (init_list_type_node, "init list");
{
vtbl_type_node
= build_cplus_array_type (vtable_entry_type, NULL_TREE);
layout_type (vtbl_type_node);
- vtbl_type_node = cp_build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
+ vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
record_builtin_type (RID_MAX, NULL, vtbl_type_node);
vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
layout_type (vtbl_ptr_type_node);
push_cp_library_fn (VEC_NEW_EXPR, newtype);
global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
push_cp_library_fn (VEC_DELETE_EXPR, deltype);
-
- nullptr_type_node = make_node (LANG_TYPE);
- TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
- 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);
- record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
- nullptr_node = make_node (INTEGER_CST);
- TREE_TYPE (nullptr_node) = nullptr_type_node;
}
abort_fndecl
init = build_string (length + 1, name);
}
- type = cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST);
+ type = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
type = build_cplus_array_type (type, domain);
*type_p = type;
/* This is a const variable with implicit 'static'. Set
DECL_THIS_STATIC so we can tell it from variables that are
!TREE_PUBLIC because of the anonymous namespace. */
- gcc_assert (CP_TYPE_CONST_P (TREE_TYPE (decl)));
+ gcc_assert (cp_type_readonly (TREE_TYPE (decl)));
DECL_THIS_STATIC (decl) = 1;
}
{
tree type = TREE_TYPE (decl);
tree init_code = NULL;
- tree core_type;
/* Things that are going to be initialized need to have complete
type. */
check_for_uninitialized_const_var (decl);
return build_aggr_init_full_exprs (decl, init, flags);
}
- else if (MAYBE_CLASS_TYPE_P (core_type = strip_array_types (type)))
+ else if (MAYBE_CLASS_TYPE_P (type))
{
- if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
- || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))
- diagnose_uninitialized_cst_or_ref_member (core_type, /*using_new=*/false,
- /*complain=*/true);
+ tree core_type = strip_array_types (type);
+
+ if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type))
+ error ("structure %qD with uninitialized const members", decl);
+ if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))
+ error ("structure %qD with uninitialized reference members", decl);
check_for_uninitialized_const_var (decl);
}
if (was_readonly)
TREE_READONLY (decl) = 1;
+
+ /* If this was marked 'used', be sure it will be output. */
+ if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+ mark_decl_referenced (decl);
}
/* Returns a declaration for a VAR_DECL as if:
parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node);
DECL_CONTEXT (parmdecl) = fndecl;
TREE_USED (parmdecl) = 1;
- DECL_READ_P (parmdecl) = 1;
DECL_ARGUMENTS (fndecl) = parmdecl;
}
{
if (TREE_CODE (member_type) == METHOD_TYPE)
{
- cp_cv_quals quals = type_memfn_quals (member_type);
+ tree arg_types = TYPE_ARG_TYPES (member_type);
+ cp_cv_quals quals = cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types)));
member_type = build_memfn_type (member_type, class_type, quals);
return build_ptrmemfunc_type (build_pointer_type (member_type));
}
/* The size might be the result of a cast. */
STRIP_TYPE_NOPS (size);
- size = mark_rvalue_use (size);
-
/* It might be a const variable or enumeration constant. */
size = integral_constant_value (size);
if (error_operand_p (size))
if (long_p && !longlong && TYPE_MAIN_VARIANT (type) == double_type_node)
{
long_p = false;
- type = cp_build_qualified_type (long_double_type_node,
- cp_type_quals (type));
+ type = build_qualified_type (long_double_type_node,
+ cp_type_quals (type));
}
/* Check all other uses of type modifiers. */
error ("qualifiers are not allowed on declaration of %<operator %T%>",
ctor_return_type);
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ && type_quals != TYPE_UNQUALIFIED)
+ {
+ /* This was an error in C++98 (cv-qualifiers cannot be added to
+ a function type), but DR 295 makes the code well-formed by
+ dropping the extra qualifiers. */
+ if (pedantic && cxx_dialect == cxx98)
+ {
+ tree bad_type = build_qualified_type (type, type_quals);
+ pedwarn (input_location, OPT_pedantic,
+ "ignoring %qV qualifiers added to function type %qT",
+ bad_type, type);
+ }
+ type_quals = TYPE_UNQUALIFIED;
+ }
type_quals |= cp_type_quals (type);
type = cp_build_qualified_type_real
(type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
&& (TREE_CODE (type) == FUNCTION_TYPE
|| (memfn_quals && TREE_CODE (type) == METHOD_TYPE)))
{
- memfn_quals |= type_memfn_quals (type);
+ memfn_quals |= cp_type_quals (type);
type = build_memfn_type (type,
declarator->u.pointer.class_type,
memfn_quals);
}
if (TREE_CODE (type) == FUNCTION_TYPE
- && type_memfn_quals (type) != TYPE_UNQUALIFIED)
+ && cp_type_quals (type) != TYPE_UNQUALIFIED)
error (declarator->kind == cdk_reference
? G_("cannot declare reference to qualified function type %qT")
: G_("cannot declare pointer to qualified function type %qT"),
function type. */
if (memfn_quals && TREE_CODE (type) == FUNCTION_TYPE)
{
- type = apply_memfn_quals (type, memfn_quals);
+ type = cp_build_qualified_type (type, memfn_quals);
/* We have now dealt with these qualifiers. */
memfn_quals = TYPE_UNQUALIFIED;
{
/* 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
+ if (cp_type_quals (type) != TYPE_UNQUALIFIED
&& (current_class_type == NULL_TREE || staticp) )
{
error (staticp
/* The qualifiers on the function type become the qualifiers on
the non-static member function. */
- memfn_quals |= type_memfn_quals (type);
+ memfn_quals |= cp_type_quals (type);
type_quals = TYPE_UNQUALIFIED;
}
}
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 = cp_build_qualified_type (type, memfn_quals);
else
error ("invalid qualifiers on non-member function type");
}
/* The binfo slot should be empty, unless this is an (ill-formed)
redefinition. */
- if (TYPE_BINFO (ref) && !TYPE_SIZE (ref))
- {
- error ("redefinition of %q#T", ref);
- return false;
- }
-
+ gcc_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref));
gcc_assert (TYPE_MAIN_VARIANT (ref) == ref);
binfo = make_tree_binfo (max_bases);
tree maxnode;
tree value;
tree t;
+ bool unsignedp;
+ bool use_short_enum;
+ int lowprec;
+ int highprec;
+ int precision;
+ unsigned int itk;
tree underlying_type = NULL_TREE;
bool fixed_underlying_type_p
= ENUM_UNDERLYING_TYPE (enumtype) != NULL_TREE;
the enumeration had a single enumerator with value 0. */
minnode = maxnode = integer_zero_node;
+ /* Compute the number of bits require to represent all values of the
+ enumeration. We must do this before the type of MINNODE and
+ MAXNODE are transformed, since tree_int_cst_min_precision relies
+ on the TREE_TYPE of the value it is passed. */
+ unsignedp = tree_int_cst_sgn (minnode) >= 0;
+ lowprec = tree_int_cst_min_precision (minnode, unsignedp);
+ highprec = tree_int_cst_min_precision (maxnode, unsignedp);
+ precision = MAX (lowprec, highprec);
+
if (!fixed_underlying_type_p)
{
- /* Compute the number of bits require to represent all values of the
- enumeration. We must do this before the type of MINNODE and
- MAXNODE are transformed, since tree_int_cst_min_precision relies
- on the TREE_TYPE of the value it is passed. */
- bool unsignedp = tree_int_cst_sgn (minnode) >= 0;
- int lowprec = tree_int_cst_min_precision (minnode, unsignedp);
- int highprec = tree_int_cst_min_precision (maxnode, unsignedp);
- int precision = MAX (lowprec, highprec);
- unsigned int itk;
- bool use_short_enum;
-
/* Determine the underlying type of the enumeration.
[dcl.enum]
The value of sizeof() applied to an enumeration type, an object
of an enumeration type, or an enumerator, is the value of sizeof()
applied to the underlying type. */
- TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (underlying_type);
- TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (underlying_type);
TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type);
TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type);
SET_TYPE_MODE (enumtype, TYPE_MODE (underlying_type));
- TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
- /* Compute the minimum and maximum values for the type.
-
- [dcl.enum]
-
- For an enumeration where emin is the smallest enumerator and emax
- is the largest, the values of the enumeration are the values of the
- underlying type in the range bmin to bmax, where bmin and bmax are,
- respectively, the smallest and largest values of the smallest bit-
- field that can store emin and emax. */
-
- /* The middle-end currently assumes that types with TYPE_PRECISION
- narrower than their underlying type are suitably zero or sign
- extended to fill their mode. Similarly, it assumes that the front
- end assures that a value of a particular type must be within
- TYPE_MIN_VALUE and TYPE_MAX_VALUE.
-
- We used to set these fields based on bmin and bmax, but that led
- to invalid assumptions like optimizing away bounds checking. So
- now we just set the TYPE_PRECISION, TYPE_MIN_VALUE, and
- TYPE_MAX_VALUE to the values for the mode above and only restrict
- the ENUM_UNDERLYING_TYPE for the benefit of diagnostics. */
+ /* Set the underlying type of the enumeration type to the
+ computed enumeration type, restricted to the enumerator
+ values. */
ENUM_UNDERLYING_TYPE (enumtype)
= build_distinct_type_copy (underlying_type);
- TYPE_PRECISION (ENUM_UNDERLYING_TYPE (enumtype)) = precision;
- set_min_and_max_values_for_integral_type
+ set_min_and_max_values_for_integral_type
(ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
-
- /* If -fstrict-enums, still constrain TYPE_MIN/MAX_VALUE. */
- if (flag_strict_enums)
- set_min_and_max_values_for_integral_type (enumtype, precision,
- unsignedp);
}
else
underlying_type = ENUM_UNDERLYING_TYPE (enumtype);
+ /* Compute the minimum and maximum values for the type.
+
+ [dcl.enum]
+
+ For an enumeration where emin is the smallest enumerator and emax
+ is the largest, the values of the enumeration are the values of the
+ underlying type in the range bmin to bmax, where bmin and bmax are,
+ respectively, the smallest and largest values of the smallest bit-
+ field that can store emin and emax. */
+
+ /* The middle-end currently assumes that types with TYPE_PRECISION
+ narrower than their underlying type are suitably zero or sign
+ extended to fill their mode. g++ doesn't make these guarantees.
+ Until the middle-end can represent such paradoxical types, we
+ set the TYPE_PRECISION to the width of the underlying type. */
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
+
+ set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp);
+
/* Convert each of the enumerators to the type of the underlying
type of the enumeration. */
for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
info for the epilogue. */
cfun->function_end_locus = input_location;
- /* Complain about parameters that are only set, but never otherwise used. */
- if (warn_unused_but_set_parameter
- && !processing_template_decl
- && errorcount == unused_but_set_errorcount
- && !DECL_CLONED_FUNCTION_P (fndecl))
- {
- tree decl;
-
- for (decl = DECL_ARGUMENTS (fndecl);
- decl;
- decl = TREE_CHAIN (decl))
- if (TREE_USED (decl)
- && TREE_CODE (decl) == PARM_DECL
- && !DECL_READ_P (decl)
- && DECL_NAME (decl)
- && !DECL_ARTIFICIAL (decl)
- && !TREE_NO_WARNING (decl)
- && !DECL_IN_SYSTEM_HEADER (decl)
- && TREE_TYPE (decl) != error_mark_node
- && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
- && (!CLASS_TYPE_P (TREE_TYPE (decl))
- || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
- warning (OPT_Wunused_but_set_parameter,
- "parameter %q+D set but not used", decl);
- unused_but_set_errorcount = errorcount;
- }
-
/* Genericize before inlining. */
if (!processing_template_decl)
{
{
tree fntype;
tree args;
+ int quals;
if (TYPE_PTRMEMFUNC_P (memfntype))
memfntype = TYPE_PTRMEMFUNC_FN_TYPE (memfntype);
gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE);
args = TYPE_ARG_TYPES (memfntype);
fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args));
- fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype));
+ quals = cp_type_quals (TREE_TYPE (TREE_VALUE (args)));
+ fntype = build_qualified_type (fntype, quals);
fntype = (cp_build_type_attribute_variant
(fntype, TYPE_ATTRIBUTES (memfntype)));
fntype = (build_exception_variant