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. */
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
"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;