#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
-#include "alias.h"
-#include "tree.h"
-#include "tree-hasher.h"
+#include "target.h"
+#include "c-family/c-target.h"
+#include "cp-tree.h"
+#include "timevar.h"
#include "stringpool.h"
+#include "cgraph.h"
#include "stor-layout.h"
#include "varasm.h"
#include "attribs.h"
-#include "calls.h"
#include "flags.h"
-#include "cp-tree.h"
#include "tree-iterator.h"
-#include "tree-inline.h"
#include "decl.h"
#include "intl.h"
#include "toplev.h"
-#include "tm_p.h"
-#include "target.h"
-#include "c-family/c-common.h"
#include "c-family/c-objc.h"
#include "c-family/c-pragma.h"
-#include "c-family/c-target.h"
#include "c-family/c-ubsan.h"
-#include "diagnostic.h"
-#include "intl.h"
#include "debug.h"
-#include "timevar.h"
-#include "splay-tree.h"
#include "plugin.h"
-#include "hard-reg-set.h"
-#include "function.h"
-#include "cgraph.h"
#include "cilk.h"
#include "builtins.h"
/* For typedefs use the old type, as the new type's DECL_NAME points
at newdecl, which will be ggc_freed. */
if (TREE_CODE (newdecl) == TYPE_DECL)
- newtype = oldtype;
+ {
+ newtype = oldtype;
+
+ /* And remove the new type from the variants list. */
+ if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl)
+ {
+ tree remove = TREE_TYPE (newdecl);
+ for (tree t = TYPE_MAIN_VARIANT (remove); ;
+ t = TYPE_NEXT_VARIANT (t))
+ if (TYPE_NEXT_VARIANT (t) == remove)
+ {
+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove);
+ break;
+ }
+ }
+ }
else
/* Merge the data types specified in the two decls. */
newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
return 0;
}
-/* A subroutine of check_previous_goto_1 to identify a branch to the user. */
+/* A subroutine of check_previous_goto_1 and check_goto to identify a branch
+ to the user. */
static bool
-identify_goto (tree decl, const location_t *locus)
+identify_goto (tree decl, location_t loc, const location_t *locus,
+ diagnostic_t diag_kind)
{
- bool complained = (decl
- ? permerror (input_location, "jump to label %qD", decl)
- : permerror (input_location, "jump to case label"));
+ bool complained
+ = (decl ? emit_diagnostic (diag_kind, loc, 0, "jump to label %qD", decl)
+ : emit_diagnostic (diag_kind, loc, 0, "jump to case label"));
if (complained && locus)
inform (*locus, " from here");
return complained;
bool exited_omp, const location_t *locus)
{
cp_binding_level *b;
- bool identified = false, complained = false;
+ bool complained = false;
+ int identified = 0;
bool saw_eh = false, saw_omp = false, saw_tm = false;
if (exited_omp)
{
- complained = identify_goto (decl, locus);
+ complained = identify_goto (decl, input_location, locus, DK_ERROR);
if (complained)
inform (input_location, " exits OpenMP structured block");
- identified = saw_omp = true;
+ saw_omp = true;
+ identified = 2;
}
for (b = current_binding_level; b ; b = b->level_chain)
if (!identified)
{
- complained = identify_goto (decl, locus);
- identified = true;
+ complained = identify_goto (decl, input_location, locus,
+ DK_PERMERROR);
+ identified = 1;
}
if (complained)
{
break;
if ((b->kind == sk_try || b->kind == sk_catch) && !saw_eh)
{
- if (!identified)
+ if (identified < 2)
{
- complained = identify_goto (decl, locus);
- identified = true;
+ complained = identify_goto (decl, input_location, locus,
+ DK_ERROR);
+ identified = 2;
}
if (complained)
{
}
if (b->kind == sk_omp && !saw_omp)
{
- if (!identified)
+ if (identified < 2)
{
- complained = identify_goto (decl, locus);
- identified = true;
+ complained = identify_goto (decl, input_location, locus,
+ DK_ERROR);
+ identified = 2;
}
if (complained)
inform (input_location, " enters OpenMP structured block");
}
if (b->kind == sk_transaction && !saw_tm)
{
- if (!identified)
+ if (identified < 2)
{
- complained = identify_goto (decl, locus);
- identified = true;
+ complained = identify_goto (decl, input_location, locus,
+ DK_ERROR);
+ identified = 2;
}
if (complained)
inform (input_location,
check_goto (tree decl)
{
struct named_label_entry *ent, dummy;
- bool saw_catch = false, identified = false, complained = false;
+ bool saw_catch = false, complained = false;
+ int identified = 0;
tree bad;
unsigned ix;
if (ent->in_try_scope || ent->in_catch_scope || ent->in_transaction_scope
|| ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls))
{
- complained = permerror (DECL_SOURCE_LOCATION (decl),
- "jump to label %qD", decl);
- if (complained)
- inform (input_location, " from here");
- identified = true;
+ diagnostic_t diag_kind = DK_PERMERROR;
+ if (ent->in_try_scope || ent->in_catch_scope
+ || ent->in_transaction_scope || ent->in_omp_scope)
+ diag_kind = DK_ERROR;
+ complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl),
+ &input_location, diag_kind);
+ identified = 1 + (diag_kind == DK_ERROR);
}
FOR_EACH_VEC_SAFE_ELT (ent->bad_decls, ix, bad)
if (u > 1 && DECL_ARTIFICIAL (bad))
{
/* Can't skip init of __exception_info. */
+ if (identified == 1)
+ {
+ complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl),
+ &input_location, DK_ERROR);
+ identified = 2;
+ }
if (complained)
inform (DECL_SOURCE_LOCATION (bad), " enters catch block");
saw_catch = true;
break;
if (b->kind == sk_omp)
{
- if (!identified)
+ if (identified < 2)
{
- complained = permerror (DECL_SOURCE_LOCATION (decl),
- "jump to label %qD", decl);
- if (complained)
- inform (input_location, " from here");
- identified = true;
+ complained = identify_goto (decl,
+ DECL_SOURCE_LOCATION (decl),
+ &input_location, DK_ERROR);
+ identified = 2;
}
if (complained)
inform (input_location, " exits OpenMP structured block");
permerror (input_location, "declaration does not declare anything");
else if (declared_type != NULL_TREE && type_uses_auto (declared_type))
{
- error ("%<auto%> can only be specified for variables "
- "or function declarations");
+ error_at (declspecs->locations[ds_type_spec],
+ "%<auto%> can only be specified for variables "
+ "or function declarations");
return error_mark_node;
}
/* Check for an anonymous union. */
to put statics on the list so we can deal with the label
address extension. FIXME. */
add_local_decl (cfun, decl);
+ /* And make sure it's in the symbol table for
+ c_parse_final_cleanups to find. */
+ varpool_node::get_create (decl);
}
/* Convert the initializer to the type of DECL, if we have not
parm = build_this_parm (type, quals);
DECL_CHAIN (parm) = parms;
parms = parm;
+
+ /* Allocate space to hold the vptr bit if needed. */
+ DECL_ALIGN (decl) = MINIMUM_METHOD_BOUNDARY;
}
DECL_ARGUMENTS (decl) = parms;
for (t = parms; t; t = DECL_CHAIN (t))
break;
}
- /* If pointers to member functions use the least significant bit to
- indicate whether a function is virtual, ensure a pointer
- to this function will have that bit clear. */
- if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
- && TREE_CODE (type) == METHOD_TYPE
- && DECL_ALIGN (decl) < 2 * BITS_PER_UNIT)
- DECL_ALIGN (decl) = 2 * BITS_PER_UNIT;
-
if (friendp
&& TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
{
DECL_EXTERNAL (decl) = 1;
if (TREE_CODE (type) == FUNCTION_TYPE)
{
+ if (quals || rqual)
+ TREE_TYPE (decl) = apply_memfn_quals (TREE_TYPE (decl),
+ TYPE_UNQUALIFIED,
+ REF_QUAL_NONE);
+
if (quals)
{
error (ctype
cp_walk_tree (&size, stabilize_save_expr_r, &pset, &pset);
}
-/* Helper function for compute_array_index_type. Look for SIZEOF_EXPR
- not inside of SAVE_EXPR and fold them. */
+/* Reduce a SIZEOF_EXPR to its value. */
-static tree
-fold_sizeof_expr_r (tree *expr_p, int *walk_subtrees, void *data)
-{
- tree expr = *expr_p;
- if (TREE_CODE (expr) == SAVE_EXPR || TYPE_P (expr))
- *walk_subtrees = 0;
- else if (TREE_CODE (expr) == SIZEOF_EXPR)
- {
- *(bool *)data = true;
- if (SIZEOF_EXPR_TYPE_P (expr))
- expr = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (expr, 0)),
- SIZEOF_EXPR, false);
- else if (TYPE_P (TREE_OPERAND (expr, 0)))
- expr = cxx_sizeof_or_alignof_type (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
- false);
- else
- expr = cxx_sizeof_or_alignof_expr (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
- false);
- if (expr == error_mark_node)
- expr = size_one_node;
- *expr_p = expr;
- *walk_subtrees = 0;
- }
- return NULL;
+tree
+fold_sizeof_expr (tree t)
+{
+ tree r;
+ if (SIZEOF_EXPR_TYPE_P (t))
+ r = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (t, 0)),
+ SIZEOF_EXPR, false);
+ else if (TYPE_P (TREE_OPERAND (t, 0)))
+ r = cxx_sizeof_or_alignof_type (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+ false);
+ else
+ r = cxx_sizeof_or_alignof_expr (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+ false);
+ if (r == error_mark_node)
+ r = size_one_node;
+ return r;
}
/* Given the SIZE (i.e., number of elements) in an array, compute an
SET_TYPE_STRUCTURAL_EQUALITY (itype);
return itype;
}
-
+
+ if (TREE_CODE (size) != INTEGER_CST)
+ {
+ tree folded = cp_fully_fold (size);
+ if (TREE_CODE (folded) == INTEGER_CST)
+ pedwarn (location_of (size), OPT_Wpedantic,
+ "size of array is not an integral constant-expression");
+ /* Use the folded result for VLAs, too; it will have resolved
+ SIZEOF_EXPR. */
+ size = folded;
+ }
+
/* Normally, the array-bound will be a constant. */
if (TREE_CODE (size) == INTEGER_CST)
{
cp_convert (ssizetype, integer_one_node,
complain),
complain);
- itype = fold (itype);
+ itype = maybe_constant_value (itype);
processing_template_decl = saved_processing_template_decl;
if (!TREE_CONSTANT (itype))
/* A variable sized array. */
itype = variable_size (itype);
- if (TREE_CODE (itype) != SAVE_EXPR)
- {
- /* Look for SIZEOF_EXPRs in itype and fold them, otherwise
- they might survive till gimplification. */
- tree newitype = itype;
- bool found = false;
- cp_walk_tree_without_duplicates (&newitype,
- fold_sizeof_expr_r, &found);
- if (found)
- itype = variable_size (fold (newitype));
- }
-
stabilize_vla_size (itype);
if (flag_sanitize & SANITIZE_VLA
case cdk_array:
type = create_array_type_for_decl (dname, type,
declarator->u.array.bounds);
+ if (!valid_array_size_p (input_location, type, dname))
+ type = error_mark_node;
+
if (declarator->std_attributes)
/* [dcl.array]/1:
error ("non-parameter %qs cannot be a parameter pack", name);
}
- /* Did array size calculations overflow or does the array cover more
- than half of the address-space? */
- if (TREE_CODE (type) == ARRAY_TYPE
- && COMPLETE_TYPE_P (type)
- && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
- && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
- {
- error ("size of array %qs is too large", name);
- /* If we proceed with the array type as it is, we'll eventually
- crash in tree_to_[su]hwi(). */
- type = error_mark_node;
- }
-
if ((decl_context == FIELD || decl_context == PARM)
&& !processing_template_decl
&& variably_modified_type_p (type, NULL_TREE))
"type %<%T%>", value, ENUM_UNDERLYING_TYPE (enumtype));
/* Convert the value to the appropriate type. */
- value = convert (ENUM_UNDERLYING_TYPE (enumtype), value);
+ value = fold_convert (ENUM_UNDERLYING_TYPE (enumtype), value);
}
}
the NRV transformation. */
maybe_save_function_definition (fndecl);
+ /* Invoke the pre-genericize plugin before we start munging things. */
+ if (!processing_template_decl)
+ invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
+
+ /* Perform delayed folding before NRV transformation. */
+ if (!processing_template_decl)
+ cp_fold_function (fndecl);
+
/* Set up the named return value optimization, if we can. Candidate
variables are selected in check_return_expr. */
if (current_function_return_value)
if (!processing_template_decl)
{
struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl);
- invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
cp_genericize (fndecl);
/* Clear out the bits we don't need. */
f->x_current_class_ptr = NULL;
cp_apply_type_quals_to_decl (cp_type_quals (type), var);
}
- if (DECL_INITIAL (var)
- && decl_constant_var_p (var))
- DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var));
-
/* Remove this entry from the list. */
incomplete_vars->unordered_remove (ix);
}