2015-02-12 Jakub Jelinek <jakub@redhat.com>
+ PR debug/55541
+ * cp-tree.h (BLOCK_OUTER_CURLY_BRACE_P): Define.
+ * decl.c (poplevel): If functionbody, try not to create an extra
+ BLOCK for function body and use subblocks as that, if it is non-NULL
+ and doesn't have siblings. Set BLOCK_OUTER_CURLY_BRACE_P flag.
+ (outer_curly_brace_block): Use BLOCK_OUTER_CURLY_BRACE_P flag.
+
PR sanitizer/64984
* except.c (check_noexcept_r): Return NULL for internal
calls.
PACK_EXPANSION_LOCAL_P (in *_PACK_EXPANSION)
TINFO_HAS_ACCESS_ERRORS (in TEMPLATE_INFO)
SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR)
+ BLOCK_OUTER_CURLY_BRACE_P (in BLOCK)
1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
#define STATEMENT_LIST_TRY_BLOCK(NODE) \
TREE_LANG_FLAG_2 (STATEMENT_LIST_CHECK (NODE))
+/* Mark the outer curly brace BLOCK. */
+#define BLOCK_OUTER_CURLY_BRACE_P(NODE) TREE_LANG_FLAG_0 (BLOCK_CHECK (NODE))
+
/* Nonzero if this statement should be considered a full-expression,
i.e., if temporaries created during this statement should have
their destructors run at the end of this statement. */
or if this level is a function body,
create a BLOCK to record them for the life of this function. */
block = NULL_TREE;
- if (keep == 1 || functionbody)
+ /* Avoid function body block if possible. */
+ if (functionbody && subblocks && BLOCK_CHAIN (subblocks) == NULL_TREE)
+ keep = 0;
+ else if (keep == 1 || functionbody)
block = make_node (BLOCK);
if (block != NULL_TREE)
{
check over all the labels. */
if (functionbody)
{
- /* Since this is the top level block of a function, the vars are
- the function's parameters. Don't leave them in the BLOCK
- because they are found in the FUNCTION_DECL instead. */
- BLOCK_VARS (block) = 0;
- pop_labels (block);
+ if (block)
+ {
+ /* Since this is the top level block of a function, the vars are
+ the function's parameters. Don't leave them in the BLOCK
+ because they are found in the FUNCTION_DECL instead. */
+ BLOCK_VARS (block) = 0;
+ pop_labels (block);
+ }
+ else
+ pop_labels (subblocks);
}
kind = current_binding_level->kind;
/* The current function is being defined, so its DECL_INITIAL
should be error_mark_node. */
gcc_assert (DECL_INITIAL (current_function_decl) == error_mark_node);
- DECL_INITIAL (current_function_decl) = block;
+ DECL_INITIAL (current_function_decl) = block ? block : subblocks;
+ if (subblocks)
+ {
+ if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
+ {
+ if (BLOCK_SUBBLOCKS (subblocks))
+ BLOCK_OUTER_CURLY_BRACE_P (BLOCK_SUBBLOCKS (subblocks)) = 1;
+ }
+ else
+ BLOCK_OUTER_CURLY_BRACE_P (subblocks) = 1;
+ }
}
else if (block)
current_binding_level->blocks
tree
outer_curly_brace_block (tree fndecl)
{
- tree block = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl));
- if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
- /* Skip the artificial function body block. */
- block = BLOCK_SUBBLOCKS (block);
+ tree block = DECL_INITIAL (fndecl);
+ if (BLOCK_OUTER_CURLY_BRACE_P (block))
+ return block;
+ block = BLOCK_SUBBLOCKS (block);
+ if (BLOCK_OUTER_CURLY_BRACE_P (block))
+ return block;
+ block = BLOCK_SUBBLOCKS (block);
+ gcc_assert (BLOCK_OUTER_CURLY_BRACE_P (block));
return block;
}