public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-contracts] c++: more tidying
@ 2022-11-01 11:43 Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2022-11-01 11:43 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:2031dff9d921dbec9065c5b7d3ef3ac97adf18b2
commit 2031dff9d921dbec9065c5b7d3ef3ac97adf18b2
Author: Jason Merrill <jason@redhat.com>
Date: Mon Oct 31 11:36:05 2022 -0400
c++: more tidying
gcc/cp/ChangeLog:
* contracts.h: Move lots of decls from...
* cp-tree.h: ...here.
* contracts.cc (cp_contract_assertion_p): Move from parser.cc.
(inherit_base_contracts): Move from search.cc.
* decl.cc (grokdeclarator): Don't use function_declarator_p.
* decl2.cc (cp_tree_defined_p_r)
(cp_tree_defined_p): Remove.
* module.cc (trees_out::fn_parms_init): Tweak comment.
* parser.cc (cp_contract_assertion_p): Moved.
(find_innermost_function_declarator)
(function_declarator_p): Revert.
(cp_parser_function_definition_after_declarator): Remove dead assignment.
(cp_parser_save_default_args): Tweak formatting.
* search.cc (inherit_base_contracts): Moved.
gcc/ChangeLog:
* input.cc (get_source): Tweak comments.
Diff:
---
gcc/cp/contracts.h | 94 ++++++++++++++++++++++++++++++++++-
gcc/cp/cp-tree.h | 140 +++++++++-------------------------------------------
gcc/cp/contracts.cc | 43 ++++++++++++++++
gcc/cp/decl.cc | 10 ++--
gcc/cp/decl2.cc | 22 ---------
gcc/cp/module.cc | 2 +-
gcc/cp/parser.cc | 48 +++++-------------
gcc/cp/search.cc | 32 ------------
gcc/input.cc | 6 +--
9 files changed, 180 insertions(+), 217 deletions(-)
diff --git a/gcc/cp/contracts.h b/gcc/cp/contracts.h
index 81b528397bc..ec48a04da36 100644
--- a/gcc/cp/contracts.h
+++ b/gcc/cp/contracts.h
@@ -1,6 +1,6 @@
/* Definitions for C++ contract levels. Implements functionality described in
the N4820 working draft version of contracts, P1290, P1332, and P1429.
- Copyright (C) 2020 Free Software Foundation, Inc.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
Contributed by Jeff Chapman II (jchapman@lock3software.com)
This file is part of GCC.
@@ -147,6 +147,7 @@ extern contract_level map_contract_level (const char *);
/* Check if an attribute is a cxx contract attribute. */
extern bool cxx_contract_attribute_p (const_tree);
+extern bool cp_contract_assertion_p (const_tree);
/* Returns the default role. */
@@ -163,4 +164,95 @@ extern void handle_OPT_fcontract_continuation_mode_ (const char *);
extern void handle_OPT_fcontract_role_ (const char *);
extern void handle_OPT_fcontract_semantic_ (const char *);
+enum contract_matching_context
+{
+ cmc_declaration,
+ cmc_override
+};
+
+/* True iff the FUNCTION_DECL NODE currently has any contracts. */
+#define DECL_HAS_CONTRACTS_P(NODE) \
+ (DECL_CONTRACTS (NODE) != NULL_TREE)
+
+/* For a FUNCTION_DECL of a guarded function, this points to a list of the pre
+ and post contracts of the first decl of NODE in original order. */
+#define DECL_CONTRACTS(NODE) \
+ (find_contract (DECL_ATTRIBUTES (NODE)))
+
+/* The next contract (if any) after this one in an attribute list. */
+#define CONTRACT_CHAIN(NODE) \
+ (find_contract (TREE_CHAIN (NODE)))
+
+/* The wrapper of the original source location of a list of contracts. */
+#define CONTRACT_SOURCE_LOCATION_WRAPPER(NODE) \
+ (TREE_PURPOSE (TREE_VALUE (NODE)))
+
+/* The original source location of a list of contracts. */
+#define CONTRACT_SOURCE_LOCATION(NODE) \
+ (EXPR_LOCATION (CONTRACT_SOURCE_LOCATION_WRAPPER (NODE)))
+
+/* The actual code _STMT for a contract attribute. */
+#define CONTRACT_STATEMENT(NODE) \
+ (TREE_VALUE (TREE_VALUE (NODE)))
+
+/* For a FUNCTION_DECL of a guarded function, this holds the function decl
+ where pre contract checks are emitted. */
+#define DECL_PRE_FN(NODE) \
+ (get_precondition_function ((NODE)))
+
+/* For a FUNCTION_DECL of a guarded function, this holds the function decl
+ where post contract checks are emitted. */
+#define DECL_POST_FN(NODE) \
+ (get_postcondition_function ((NODE)))
+
+/* For a FUNCTION_DECL of a pre/post function, this points back to the
+ original guarded function. */
+#define DECL_ORIGINAL_FN(NODE) \
+ (DECL_ABSTRACT_ORIGIN (NODE))
+
+/* True iff the FUNCTION_DECL is the pre function for a guarded function. */
+#define DECL_IS_PRE_FN_P(NODE) \
+ (DECL_ORIGINAL_FN (NODE) && DECL_PRE_FN (DECL_ORIGINAL_FN (NODE)) == NODE)
+
+/* True iff the FUNCTION_DECL is the post function for a guarded function. */
+#define DECL_IS_POST_FN_P(NODE) \
+ (DECL_ORIGINAL_FN (NODE) && DECL_POST_FN (DECL_ORIGINAL_FN (NODE)) == NODE)
+
+extern tree invalidate_contract (tree);
+extern tree finish_contract_attribute (tree, tree);
+extern void update_late_contract (tree, tree, tree);
+extern void remove_contract_attributes (tree);
+extern void copy_contract_attributes (tree, tree);
+extern tree splice_out_contracts (tree);
+extern bool check_postcondition_result (tree, tree, location_t);
+extern void rebuild_postconditions (tree);
+extern bool match_contract_conditions (location_t, tree, location_t, tree, contract_matching_context);
+extern void defer_guarded_contract_match (tree, tree, tree);
+extern void match_deferred_contracts (tree);
+extern void remap_contract (tree, tree, tree, bool);
+extern void remap_contracts (tree, tree, tree, bool);
+extern void remap_dummy_this (tree, tree *);
+extern bool contract_active_p (tree);
+extern bool contract_any_active_p (tree);
+extern bool contract_any_deferred_p (tree);
+extern bool all_attributes_are_contracts_p (tree);
+extern void build_contract_function_decls (tree);
+extern void set_contract_functions (tree, tree, tree);
+extern tree start_postcondition_statement ();
+extern void finish_postcondition_statement (tree);
+extern tree build_contract_check (tree);
+extern tree get_postcondition_result_parameter (tree);
+extern tree get_precondition_function (tree);
+extern tree get_postcondition_function (tree);
+extern tree get_contracts_original_fn (tree);
+extern void emit_assertion (tree);
+extern void emit_preconditions (tree);
+extern void emit_postconditions_cleanup (tree);
+extern void maybe_update_postconditions (tree);
+extern void start_function_contracts (tree);
+extern void finish_function_contracts (tree);
+extern tree apply_postcondition_to_return (tree);
+extern void duplicate_contracts (tree, tree);
+extern void inherit_base_contracts (tree, tree);
+
#endif /* ! GCC_CP_CONTRACT_H */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a212aa2659d..4b5d14f6a29 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3747,64 +3747,6 @@ struct GTY(()) lang_decl {
#define DECL_PENDING_INLINE_INFO(NODE) \
(LANG_DECL_FN_CHECK (NODE)->u.pending_inline_info)
-/* Return the first contract in ATTRS, or NULL_TREE if there are none. */
-
-inline tree
-find_contract (tree attrs)
-{
- while (attrs && !cxx_contract_attribute_p (attrs))
- attrs = TREE_CHAIN (attrs);
- return attrs;
-}
-
-/* True iff the FUNCTION_DECL NODE currently has any contracts. */
-#define DECL_HAS_CONTRACTS_P(NODE) \
- (DECL_CONTRACTS (NODE) != NULL_TREE)
-
-/* For a FUNCTION_DECL of a guarded function, this points to a list of the pre
- and post contracts of the first decl of NODE in original order. */
-#define DECL_CONTRACTS(NODE) \
- (find_contract (DECL_ATTRIBUTES (NODE)))
-
-/* The next contract (if any) after this one in an attribute list. */
-#define CONTRACT_CHAIN(NODE) \
- (find_contract (TREE_CHAIN (NODE)))
-
-/* The wrapper of the original source location of a list of contracts. */
-#define CONTRACT_SOURCE_LOCATION_WRAPPER(NODE) \
- (TREE_PURPOSE (TREE_VALUE (NODE)))
-
-/* The original source location of a list of contracts. */
-#define CONTRACT_SOURCE_LOCATION(NODE) \
- (EXPR_LOCATION (CONTRACT_SOURCE_LOCATION_WRAPPER (NODE)))
-
-/* The actual code _STMT for a contract attribute. */
-#define CONTRACT_STATEMENT(NODE) \
- (TREE_VALUE (TREE_VALUE (NODE)))
-
-/* For a FUNCTION_DECL of a guarded function, this holds the function decl
- where pre contract checks are emitted. */
-#define DECL_PRE_FN(NODE) \
- (get_precondition_function ((NODE)))
-
-/* For a FUNCTION_DECL of a guarded function, this holds the function decl
- where post contract checks are emitted. */
-#define DECL_POST_FN(NODE) \
- (get_postcondition_function ((NODE)))
-
-/* For a FUNCTION_DECL of a pre/post function, this points back to the
- original guarded function. */
-#define DECL_ORIGINAL_FN(NODE) \
- (DECL_ABSTRACT_ORIGIN (NODE))
-
-/* True iff the FUNCTION_DECL is the pre function for a guarded function. */
-#define DECL_IS_PRE_FN_P(NODE) \
- (DECL_ORIGINAL_FN (NODE) && DECL_PRE_FN (DECL_ORIGINAL_FN (NODE)) == NODE)
-
-/* True iff the FUNCTION_DECL is the post function for a guarded function. */
-#define DECL_IS_POST_FN_P(NODE) \
- (DECL_ORIGINAL_FN (NODE) && DECL_POST_FN (DECL_ORIGINAL_FN (NODE)) == NODE)
-
/* Nonzero for TYPE_DECL means that it was written 'using name = type'. */
#define TYPE_DECL_ALIAS_P(NODE) \
DECL_LANG_FLAG_6 (TYPE_DECL_CHECK (NODE))
@@ -7146,7 +7088,6 @@ extern void import_export_decl (tree);
extern tree build_cleanup (tree);
extern tree build_offset_ref_call_from_tree (tree, vec<tree, va_gc> **,
tsubst_flags_t);
-extern bool cp_tree_defined_p (tree);
extern bool decl_defined_p (tree);
extern bool decl_constant_var_p (tree);
extern bool decl_maybe_constant_var_p (tree);
@@ -7458,8 +7399,6 @@ extern location_t defparse_location (tree);
extern void maybe_show_extern_c_location (void);
extern bool literal_integer_zerop (const_tree);
extern tree attr_chainon (tree, tree);
-extern bool function_declarator_p (const cp_declarator *);
-extern const cp_declarator *find_innermost_function_declarator (const cp_declarator *);
/* in pt.cc */
extern tree canonical_type_parameter (tree);
@@ -7741,62 +7680,6 @@ extern bool perform_or_defer_access_check (tree, tree, tree,
tsubst_flags_t,
access_failure_info *afi = NULL);
-/* contracts.cc */
-enum contract_matching_context
-{
- cmc_declaration,
- cmc_override
-};
-
-extern void init_contract_processing ();
-extern tree invalidate_contract (tree);
-extern tree make_postcondition_variable (cp_expr);
-extern tree make_postcondition_variable (cp_expr, tree);
-extern bool check_postcondition_result (tree, tree, location_t);
-extern void rebuild_postconditions (tree);
-extern tree grok_contract (tree, tree, tree, cp_expr, location_t);
-extern tree finish_contract_attribute (tree, tree);
-extern void update_late_contract (tree, tree, tree);
-extern tree finish_contract_condition (cp_expr);
-extern void remove_contract_attributes (tree);
-extern void copy_contract_attributes (tree, tree);
-extern tree splice_out_contracts (tree);
-extern bool match_contract_conditions (location_t, tree, location_t, tree, contract_matching_context);
-extern void defer_guarded_contract_match (tree, tree, tree);
-extern void match_deferred_contracts (tree);
-extern void remap_contract (tree, tree, tree, bool);
-extern void remap_contracts (tree, tree, tree, bool);
-extern void remap_dummy_this (tree, tree *);
-extern bool contract_active_p (tree);
-extern bool contract_any_active_p (tree);
-extern bool contract_any_deferred_p (tree);
-extern bool all_attributes_are_contracts_p (tree);
-extern void build_contract_function_decls (tree);
-extern void set_contract_functions (tree, tree, tree);
-extern tree start_postcondition_statement ();
-extern void finish_postcondition_statement (tree);
-extern tree build_contract_check (tree);
-extern tree get_postcondition_result_parameter (tree);
-extern tree get_precondition_function (tree);
-extern tree get_postcondition_function (tree);
-extern tree get_contracts_original_fn (tree);
-
-extern void emit_assertion (tree);
-extern void emit_preconditions (tree);
-extern void emit_postconditions_cleanup (tree);
-extern void maybe_update_postconditions (tree);
-extern void start_function_contracts (tree);
-extern void finish_function_contracts (tree);
-extern tree apply_postcondition_to_return (tree);
-extern void duplicate_contracts (tree, tree);
-
-inline void
-set_decl_contracts (tree decl, tree contract_attrs)
-{
- remove_contract_attributes (decl);
- DECL_ATTRIBUTES (decl) = chainon (DECL_ATTRIBUTES (decl), contract_attrs);
-}
-
/* RAII sentinel to ensures that deferred access checks are popped before
a function returns. */
@@ -8765,6 +8648,29 @@ extern tree coro_get_actor_function (tree);
extern tree coro_get_destroy_function (tree);
extern tree coro_get_ramp_function (tree);
+/* contracts.cc */
+extern tree make_postcondition_variable (cp_expr);
+extern tree make_postcondition_variable (cp_expr, tree);
+extern tree grok_contract (tree, tree, tree, cp_expr, location_t);
+extern tree finish_contract_condition (cp_expr);
+
+/* Return the first contract in ATTRS, or NULL_TREE if there are none. */
+
+inline tree
+find_contract (tree attrs)
+{
+ while (attrs && !cxx_contract_attribute_p (attrs))
+ attrs = TREE_CHAIN (attrs);
+ return attrs;
+}
+
+inline void
+set_decl_contracts (tree decl, tree contract_attrs)
+{
+ remove_contract_attributes (decl);
+ DECL_ATTRIBUTES (decl) = chainon (DECL_ATTRIBUTES (decl), contract_attrs);
+}
+
/* Inline bodies. */
inline tree
diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
index 272448d07d8..6732b761183 100644
--- a/gcc/cp/contracts.cc
+++ b/gcc/cp/contracts.cc
@@ -848,6 +848,17 @@ cxx_contract_attribute_p (const_tree attr)
|| TREE_CODE (TREE_VALUE (TREE_VALUE (attr))) == ASSERTION_STMT);
}
+/* True if ATTR is an assertion. */
+
+bool
+cp_contract_assertion_p (const_tree attr)
+{
+ /* This is only an assertion if it is a valid cxx contract attribute and the
+ statement is an ASSERTION_STMT. */
+ return cxx_contract_attribute_p (attr)
+ && TREE_CODE (CONTRACT_STATEMENT (attr)) == ASSERTION_STMT;
+}
+
/* Remove all c++2a style contract attributes from the DECL_ATTRIBUTEs of the
FUNCTION_DECL FNDECL. */
@@ -2188,4 +2199,36 @@ duplicate_contracts (tree newdecl, tree olddecl)
}
}
+/* Replace the any contract attributes on OVERRIDER with a copy where any
+ references to BASEFN's PARM_DECLs have been rewritten to the corresponding
+ PARM_DECL in OVERRIDER. */
+
+void
+inherit_base_contracts (tree overrider, tree basefn)
+{
+ tree last = NULL_TREE, contract_attrs = NULL_TREE;
+ for (tree a = DECL_CONTRACTS (basefn);
+ a != NULL_TREE;
+ a = CONTRACT_CHAIN (a))
+ {
+ tree c = copy_node (a);
+ TREE_VALUE (c) = build_tree_list (TREE_PURPOSE (TREE_VALUE (c)),
+ copy_node (CONTRACT_STATEMENT (c)));
+
+ tree src = basefn;
+ tree dst = overrider;
+ remap_contract (src, dst, CONTRACT_STATEMENT (c), /*duplicate_p=*/true);
+
+ CONTRACT_COMMENT (CONTRACT_STATEMENT (c)) =
+ copy_node (CONTRACT_COMMENT (CONTRACT_STATEMENT (c)));
+
+ chainon (last, c);
+ last = c;
+ if (!contract_attrs)
+ contract_attrs = c;
+ }
+
+ set_decl_contracts (overrider, contract_attrs);
+}
+
#include "gt-cp-contracts.h"
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index d6eb50a260b..4a85c858686 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -12858,9 +12858,10 @@ grokdeclarator (const cp_declarator *declarator,
inner_declarator = declarator->declarator;
/* Check that contracts aren't misapplied. */
- tree contract_attr = find_contract (declarator->std_attributes);
- if (contract_attr && !function_declarator_p (declarator))
- diagnose_misapplied_contracts (contract_attr);
+ if (tree contract_attr = find_contract (declarator->std_attributes))
+ if (declarator->kind != cdk_function
+ || innermost_code != cdk_function)
+ diagnose_misapplied_contracts (contract_attr);
/* We don't want to warn in parameter context because we don't
yet know if the parse will succeed, and this might turn out
@@ -13256,8 +13257,7 @@ grokdeclarator (const cp_declarator *declarator,
}
/* Contract attributes appertain to the declaration. */
- tree *p;
- for (p = &attrs; *p;)
+ for (tree *p = &attrs; *p;)
{
tree l = *p;
if (cxx_contract_attribute_p (l))
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 6fc6f289990..a39bcd14015 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -4423,28 +4423,6 @@ collect_ada_namespace (tree namespc, const char *source_file)
collect_ada_namespace (decl, source_file);
}
-/* cp_tree_defined_p helper -- returns TP if TP is undefined. */
-
-static tree
-cp_tree_defined_p_r (tree *tp, int *, void *)
-{
- enum tree_code code = TREE_CODE (*tp);
- if ((code == FUNCTION_DECL || code == VAR_DECL)
- && !decl_defined_p (*tp))
- return *tp;
- return NULL_TREE;
-}
-
-/* Returns true iff there is a definition for all entities referenced in the
- tree TP. */
-
-bool
-cp_tree_defined_p (tree tp)
-{
- tree undefined_t = walk_tree (&tp, cp_tree_defined_p_r, NULL, NULL);
- return !undefined_t;
-}
-
/* Returns true iff there is a definition available for variable or
function DECL. */
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index c218dbcd95f..1ceac77e662 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -10178,7 +10178,7 @@ trees_out::fn_parms_init (tree fn)
tree_node (contract);
}
- /* Write a reference to contracts pre/post functions, if any to avoid
+ /* Write a reference to contracts pre/post functions, if any, to avoid
regenerating them in importers. */
tree_node (DECL_PRE_FN (fn));
tree_node (DECL_POST_FN (fn));
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 0f707b57c4c..a0a1988f76e 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -1588,17 +1588,6 @@ cp_ensure_no_oacc_routine (cp_parser *parser)
parser->oacc_routine = NULL;
}
}
-
-/* True if ATTR is an assertion. */
-
-bool
-cp_contract_assertion_p (const_tree attr)
-{
- /* This is only an assertion if it is a valid cxx contract attribute and the
- statement is an ASSERTION_STMT. */
- return cxx_contract_attribute_p (attr)
- && TREE_CODE (CONTRACT_STATEMENT (attr)) == ASSERTION_STMT;
-}
\f
/* Decl-specifiers. */
@@ -1923,32 +1912,23 @@ make_parameter_declarator (cp_decl_specifier_seq *decl_specifiers,
return parameter;
}
-/* Returns a pointer to the function declarator iff DECLARATOR is a
- declaration for a function. Returns NULL otherwise. */
+/* Returns true iff DECLARATOR is a declaration for a function. */
-const cp_declarator *
-find_innermost_function_declarator (const cp_declarator *declarator)
+static bool
+function_declarator_p (const cp_declarator *declarator)
{
while (declarator)
{
if (declarator->kind == cdk_function
&& declarator->declarator->kind == cdk_id)
- return declarator;
+ return true;
if (declarator->kind == cdk_id
|| declarator->kind == cdk_decomp
|| declarator->kind == cdk_error)
- return NULL;
+ return false;
declarator = declarator->declarator;
}
- return NULL;
-}
-
-/* Returns true iff DECLARATOR is a declaration for a function. */
-
-bool
-function_declarator_p (const cp_declarator *declarator)
-{
- return find_innermost_function_declarator (declarator) != NULL;
+ return false;
}
/* The parser. */
@@ -31912,8 +31892,6 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
cp_parser_ctor_initializer_opt_and_function_body
(parser, /*in_function_try_block=*/false);
- fn = current_function_decl;
-
/* Finish the function. */
fn = finish_function (inline_p);
@@ -32919,15 +32897,13 @@ cp_parser_save_default_args (cp_parser* parser, tree decl)
if (UNPARSED_NOEXCEPT_SPEC_P (spec))
vec_safe_push (unparsed_noexcepts, decl);
- /* If a member function has attributes, they are all deferred. */
+ /* Contracts are deferred. */
for (tree attr = DECL_ATTRIBUTES (decl); attr; attr = TREE_CHAIN (attr))
- {
- if (cxx_contract_attribute_p (attr))
- {
- vec_safe_push (unparsed_contracts, decl);
- break;
- }
- }
+ if (cxx_contract_attribute_p (attr))
+ {
+ vec_safe_push (unparsed_contracts, decl);
+ break;
+ }
}
/* DEFAULT_ARG contains the saved tokens for the initializer of DECL,
diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc
index b9931a6628b..0dbb3be1ee7 100644
--- a/gcc/cp/search.cc
+++ b/gcc/cp/search.cc
@@ -1918,38 +1918,6 @@ maybe_check_overriding_exception_spec (tree overrider, tree basefn)
return true;
}
-/* Replace the any contract attributes on OVERRIDER with a copy where any
- references to BASEFN's PARM_DECLs have been rewritten to the corresponding
- PARM_DECL in OVERRIDER. */
-
-static void
-inherit_base_contracts (tree overrider, tree basefn)
-{
- tree last = NULL_TREE, contract_attrs = NULL_TREE;
- for (tree a = DECL_CONTRACTS (basefn);
- a != NULL_TREE;
- a = CONTRACT_CHAIN (a))
- {
- tree c = copy_node (a);
- TREE_VALUE (c) = build_tree_list (TREE_PURPOSE (TREE_VALUE (c)),
- copy_node (CONTRACT_STATEMENT (c)));
-
- tree src = basefn;
- tree dst = overrider;
- remap_contract (src, dst, CONTRACT_STATEMENT (c), /*duplicate_p=*/true);
-
- CONTRACT_COMMENT (CONTRACT_STATEMENT (c)) =
- copy_node (CONTRACT_COMMENT (CONTRACT_STATEMENT (c)));
-
- chainon (last, c);
- last = c;
- if (!contract_attrs)
- contract_attrs = c;
- }
-
- set_decl_contracts (overrider, contract_attrs);
-}
-
/* Check that virtual overrider OVERRIDER is acceptable for base function
BASEFN. Issue diagnostic, and return zero, if unacceptable. */
diff --git a/gcc/input.cc b/gcc/input.cc
index 8baca776f80..7166c810892 100644
--- a/gcc/input.cc
+++ b/gcc/input.cc
@@ -995,7 +995,7 @@ get_source (location_t start, location_t end)
if (line.length () < 1 && (l != expstart.line && l != expend.line))
continue;
- /* for the first line in the range, only start at expstart.column */
+ /* For the first line in the range, only start at expstart.column */
if (l == expstart.line)
{
if (expstart.column == 0)
@@ -1005,7 +1005,7 @@ get_source (location_t start, location_t end)
line = line.subspan (expstart.column - 1,
line.length() - expstart.column + 1);
}
- /* for the last line, don't go past expstart.column */
+ /* For the last line, don't go past expend.column */
else if (l == expend.line)
{
if (line.length () < (size_t)expend.column)
@@ -1016,7 +1016,7 @@ get_source (location_t start, location_t end)
obstack_grow (&buf_obstack, line.get_buffer (), line.length ());
}
- /* Null terminate and finish the buf obstack. */
+ /* NUL-terminate and finish the buf obstack. */
obstack_1grow (&buf_obstack, 0);
const char *buf = (const char *) obstack_finish (&buf_obstack);
^ permalink raw reply [flat|nested] 2+ messages in thread
* [gcc/devel/c++-contracts] c++: more tidying
@ 2022-11-02 18:44 Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2022-11-02 18:44 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:43334477200de54ea246f714a55594c12b8a4d06
commit 43334477200de54ea246f714a55594c12b8a4d06
Author: Jason Merrill <jason@redhat.com>
Date: Tue Nov 1 09:45:00 2022 -0400
c++: more tidying
Move more macros to contracts.h, remove unnecessary extern decls, tweak
comments, remove DECL_ORIGINAL_FN.
Diff:
---
gcc/cp/contracts.h | 120 ++++++++++++++++++++++++++++++++++++----------------
gcc/cp/cp-tree.h | 105 +++++++++------------------------------------
gcc/cp/parser.h | 2 +-
gcc/cp/constexpr.cc | 4 +-
gcc/cp/contracts.cc | 41 +++++-------------
gcc/cp/decl.cc | 5 +--
gcc/cp/module.cc | 2 +-
7 files changed, 120 insertions(+), 159 deletions(-)
diff --git a/gcc/cp/contracts.h b/gcc/cp/contracts.h
index ec48a04da36..ad382cf187b 100644
--- a/gcc/cp/contracts.h
+++ b/gcc/cp/contracts.h
@@ -170,6 +170,28 @@ enum contract_matching_context
cmc_override
};
+/* True if NODE is any kind of contract. */
+#define CONTRACT_P(NODE) \
+ (TREE_CODE (NODE) == ASSERTION_STMT \
+ || TREE_CODE (NODE) == PRECONDITION_STMT \
+ || TREE_CODE (NODE) == POSTCONDITION_STMT)
+
+/* True if NODE is a contract condition. */
+#define CONTRACT_CONDITION_P(NODE) \
+ (TREE_CODE (NODE) == PRECONDITION_STMT \
+ || TREE_CODE (NODE) == POSTCONDITION_STMT)
+
+/* True if NODE is a precondition. */
+#define PRECONDITION_P(NODE) \
+ (TREE_CODE (NODE) == PRECONDITION_STMT)
+
+/* True if NODE is a postcondition. */
+#define POSTCONDITION_P(NODE) \
+ (TREE_CODE (NODE) == POSTCONDITION_STMT)
+
+#define CONTRACT_CHECK(NODE) \
+ (TREE_CHECK3 (NODE, ASSERTION_STMT, PRECONDITION_STMT, POSTCONDITION_STMT))
+
/* True iff the FUNCTION_DECL NODE currently has any contracts. */
#define DECL_HAS_CONTRACTS_P(NODE) \
(DECL_CONTRACTS (NODE) != NULL_TREE)
@@ -195,6 +217,48 @@ enum contract_matching_context
#define CONTRACT_STATEMENT(NODE) \
(TREE_VALUE (TREE_VALUE (NODE)))
+/* True if the contract semantic was specified literally. If true, the
+ contract mode is an identifier containing the semantic. Otherwise,
+ it is a TREE_LIST whose TREE_VALUE is the level and whose TREE_PURPOSE
+ is the role. */
+#define CONTRACT_LITERAL_MODE_P(NODE) \
+ (CONTRACT_MODE (NODE) != NULL_TREE \
+ && TREE_CODE (CONTRACT_MODE (NODE)) == IDENTIFIER_NODE)
+
+/* The identifier denoting the literal semantic of the contract. */
+#define CONTRACT_LITERAL_SEMANTIC(NODE) \
+ (TREE_OPERAND (NODE, 0))
+
+/* The written "mode" of the contract. Either an IDENTIFIER with the
+ literal semantic or a TREE_LIST containing the level and role. */
+#define CONTRACT_MODE(NODE) \
+ (TREE_OPERAND (CONTRACT_CHECK (NODE), 0))
+
+/* The identifier denoting the build level of the contract. */
+#define CONTRACT_LEVEL(NODE) \
+ (TREE_VALUE (CONTRACT_MODE (NODE)))
+
+/* The identifier denoting the role of the contract */
+#define CONTRACT_ROLE(NODE) \
+ (TREE_PURPOSE (CONTRACT_MODE (NODE)))
+
+/* The parsed condition of the contract. */
+#define CONTRACT_CONDITION(NODE) \
+ (TREE_OPERAND (CONTRACT_CHECK (NODE), 1))
+
+/* True iff the condition of the contract NODE is not yet parsed. */
+#define CONTRACT_CONDITION_DEFERRED_P(NODE) \
+ (TREE_CODE (CONTRACT_CONDITION (NODE)) == DEFERRED_PARSE)
+
+/* The raw comment of the contract. */
+#define CONTRACT_COMMENT(NODE) \
+ (TREE_OPERAND (CONTRACT_CHECK (NODE), 2))
+
+/* The VAR_DECL of a postcondition result. For deferred contracts, this
+ is an IDENTIFIER. */
+#define POSTCONDITION_IDENTIFIER(NODE) \
+ (TREE_OPERAND (POSTCONDITION_STMT_CHECK (NODE), 3))
+
/* For a FUNCTION_DECL of a guarded function, this holds the function decl
where pre contract checks are emitted. */
#define DECL_PRE_FN(NODE) \
@@ -205,54 +269,38 @@ enum contract_matching_context
#define DECL_POST_FN(NODE) \
(get_postcondition_function ((NODE)))
-/* For a FUNCTION_DECL of a pre/post function, this points back to the
- original guarded function. */
-#define DECL_ORIGINAL_FN(NODE) \
- (DECL_ABSTRACT_ORIGIN (NODE))
-
/* True iff the FUNCTION_DECL is the pre function for a guarded function. */
#define DECL_IS_PRE_FN_P(NODE) \
- (DECL_ORIGINAL_FN (NODE) && DECL_PRE_FN (DECL_ORIGINAL_FN (NODE)) == NODE)
+ (DECL_ABSTRACT_ORIGIN (NODE) && DECL_PRE_FN (DECL_ABSTRACT_ORIGIN (NODE)) == NODE)
/* True iff the FUNCTION_DECL is the post function for a guarded function. */
#define DECL_IS_POST_FN_P(NODE) \
- (DECL_ORIGINAL_FN (NODE) && DECL_POST_FN (DECL_ORIGINAL_FN (NODE)) == NODE)
+ (DECL_ABSTRACT_ORIGIN (NODE) && DECL_POST_FN (DECL_ABSTRACT_ORIGIN (NODE)) == NODE)
-extern tree invalidate_contract (tree);
-extern tree finish_contract_attribute (tree, tree);
-extern void update_late_contract (tree, tree, tree);
extern void remove_contract_attributes (tree);
extern void copy_contract_attributes (tree, tree);
-extern tree splice_out_contracts (tree);
-extern bool check_postcondition_result (tree, tree, location_t);
-extern void rebuild_postconditions (tree);
-extern bool match_contract_conditions (location_t, tree, location_t, tree, contract_matching_context);
-extern void defer_guarded_contract_match (tree, tree, tree);
-extern void match_deferred_contracts (tree);
-extern void remap_contract (tree, tree, tree, bool);
extern void remap_contracts (tree, tree, tree, bool);
-extern void remap_dummy_this (tree, tree *);
-extern bool contract_active_p (tree);
-extern bool contract_any_active_p (tree);
-extern bool contract_any_deferred_p (tree);
-extern bool all_attributes_are_contracts_p (tree);
-extern void build_contract_function_decls (tree);
-extern void set_contract_functions (tree, tree, tree);
-extern tree start_postcondition_statement ();
-extern void finish_postcondition_statement (tree);
-extern tree build_contract_check (tree);
-extern tree get_postcondition_result_parameter (tree);
+extern void maybe_update_postconditions (tree);
+extern void rebuild_postconditions (tree);
+extern bool check_postcondition_result (tree, tree, location_t);
extern tree get_precondition_function (tree);
extern tree get_postcondition_function (tree);
-extern tree get_contracts_original_fn (tree);
-extern void emit_assertion (tree);
-extern void emit_preconditions (tree);
-extern void emit_postconditions_cleanup (tree);
-extern void maybe_update_postconditions (tree);
+extern void duplicate_contracts (tree, tree);
+extern bool match_contract_conditions (location_t, tree, location_t, tree, contract_matching_context);
+extern void match_deferred_contracts (tree);
+extern void defer_guarded_contract_match (tree, tree, tree);
+extern bool diagnose_misapplied_contracts (tree);
+extern tree finish_contract_attribute (tree, tree);
+extern tree invalidate_contract (tree);
+extern void update_late_contract (tree, tree, tree);
+extern tree splice_out_contracts (tree);
+extern bool all_attributes_are_contracts_p (tree);
+extern void inherit_base_contracts (tree, tree);
+extern tree apply_postcondition_to_return (tree);
extern void start_function_contracts (tree);
extern void finish_function_contracts (tree);
-extern tree apply_postcondition_to_return (tree);
-extern void duplicate_contracts (tree, tree);
-extern void inherit_base_contracts (tree, tree);
+extern void set_contract_functions (tree, tree, tree);
+extern tree build_contract_check (tree);
+extern void emit_assertion (tree);
#endif /* ! GCC_CP_CONTRACT_H */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f4104c8751d..c9f176759eb 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1380,90 +1380,6 @@ struct GTY (()) tree_static_assert {
location_t location;
};
-/* True if NODE is any kind of contract. */
-#define CONTRACT_P(NODE) \
- (TREE_CODE (NODE) == ASSERTION_STMT \
- || TREE_CODE (NODE) == PRECONDITION_STMT \
- || TREE_CODE (NODE) == POSTCONDITION_STMT)
-
-/* True if NODE is a contract condition. */
-#define CONTRACT_CONDITION_P(NODE) \
- (TREE_CODE (NODE) == PRECONDITION_STMT \
- || TREE_CODE (NODE) == POSTCONDITION_STMT)
-
-/* True if NODE is a precondition. */
-#define PRECONDITION_P(NODE) \
- (TREE_CODE (NODE) == PRECONDITION_STMT)
-
-/* True if NODE is a postcondition. */
-#define POSTCONDITION_P(NODE) \
- (TREE_CODE (NODE) == POSTCONDITION_STMT)
-
-#define CONTRACT_CHECK(NODE) \
- (TREE_CHECK3 (NODE, ASSERTION_STMT, PRECONDITION_STMT, POSTCONDITION_STMT))
-
-/* Returns the computed semantic of the node. */
-
-inline contract_semantic
-get_contract_semantic (const_tree t)
-{
- return (contract_semantic) (TREE_LANG_FLAG_3 (CONTRACT_CHECK (t))
- | (TREE_LANG_FLAG_2 (t) << 1)
- | (TREE_LANG_FLAG_0 ((t)) << 2));
-}
-
-/* Sets the computed semantic of the node. */
-
-inline void
-set_contract_semantic (tree t, contract_semantic semantic)
-{
- TREE_LANG_FLAG_3 (CONTRACT_CHECK (t)) = semantic & 0x01;
- TREE_LANG_FLAG_2 (t) = (semantic & 0x02) >> 1;
- TREE_LANG_FLAG_0 (t) = (semantic & 0x04) >> 2;
-}
-
-/* True if the contract semantic was specified literally. If true, the
- contract mode is an identifier containing the semantic. Otherwise,
- it is a TREE_LIST whose TREE_VALUE is the level and whose TREE_PURPOSE
- is the role. */
-#define CONTRACT_LITERAL_MODE_P(NODE) \
- (CONTRACT_MODE (NODE) != NULL_TREE \
- && TREE_CODE (CONTRACT_MODE (NODE)) == IDENTIFIER_NODE)
-
-/* The identifier denoting the literal semantic of the contract. */
-#define CONTRACT_LITERAL_SEMANTIC(NODE) \
- (TREE_OPERAND (NODE, 0))
-
-/* The written "mode" of the contract. Either an IDENTIFIER with the
- literal semantic or a TREE_LIST containing the level and role. */
-#define CONTRACT_MODE(NODE) \
- (TREE_OPERAND (CONTRACT_CHECK (NODE), 0))
-
-/* The identifier denoting the build level of the contract. */
-#define CONTRACT_LEVEL(NODE) \
- (TREE_VALUE (CONTRACT_MODE (NODE)))
-
-/* The identifier denoting the role of the contract */
-#define CONTRACT_ROLE(NODE) \
- (TREE_PURPOSE (CONTRACT_MODE (NODE)))
-
-/* The parsed condition of the contract. */
-#define CONTRACT_CONDITION(NODE) \
- (TREE_OPERAND (CONTRACT_CHECK (NODE), 1))
-
-/* True iff the condition of the contract NODE is not yet parsed. */
-#define CONTRACT_CONDITION_DEFERRED_P(NODE) \
- (TREE_CODE (CONTRACT_CONDITION (NODE)) == DEFERRED_PARSE)
-
-/* The raw comment of the contract. */
-#define CONTRACT_COMMENT(NODE) \
- (TREE_OPERAND (CONTRACT_CHECK (NODE), 2))
-
-/* The VAR_DECL of a postcondition result. For deferred contracts, this
- is an IDENTIFIER. */
-#define POSTCONDITION_IDENTIFIER(NODE) \
- (TREE_OPERAND (POSTCONDITION_STMT_CHECK (NODE), 3))
-
struct GTY (()) tree_argument_pack_select {
struct tree_common common;
tree argument_pack;
@@ -6941,7 +6857,6 @@ extern tree push_library_fn (tree, tree, tree, int);
extern tree push_throw_library_fn (tree, tree);
extern void warn_misplaced_attr_for_class_type (location_t location,
tree class_type);
-extern bool diagnose_misapplied_contracts (tree);
extern tree check_tag_decl (cp_decl_specifier_seq *, bool);
extern tree shadow_tag (cp_decl_specifier_seq *);
extern tree groktypename (cp_decl_specifier_seq *, const cp_declarator *, bool);
@@ -8649,6 +8564,26 @@ set_decl_contracts (tree decl, tree contract_attrs)
DECL_ATTRIBUTES (decl) = chainon (DECL_ATTRIBUTES (decl), contract_attrs);
}
+/* Returns the computed semantic of the node. */
+
+inline contract_semantic
+get_contract_semantic (const_tree t)
+{
+ return (contract_semantic) (TREE_LANG_FLAG_3 (CONTRACT_CHECK (t))
+ | (TREE_LANG_FLAG_2 (t) << 1)
+ | (TREE_LANG_FLAG_0 ((t)) << 2));
+}
+
+/* Sets the computed semantic of the node. */
+
+inline void
+set_contract_semantic (tree t, contract_semantic semantic)
+{
+ TREE_LANG_FLAG_3 (CONTRACT_CHECK (t)) = semantic & 0x01;
+ TREE_LANG_FLAG_2 (t) = (semantic & 0x02) >> 1;
+ TREE_LANG_FLAG_0 (t) = (semantic & 0x04) >> 2;
+}
+
/* Inline bodies. */
inline tree
diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h
index 1b6c359a4c0..f695f4566b4 100644
--- a/gcc/cp/parser.h
+++ b/gcc/cp/parser.h
@@ -318,7 +318,7 @@ struct GTY(()) cp_parser {
/* TRUE if the decl-specifier-seq preceding a declarator includes
the 'friend' specifier. This prevents attributes on friend function
declarations from being parsed in the complete class context. */
- /* ??? Maybe use defer_guarded_contract_match instead? */
+ /* ??? But they should be; maybe use defer_guarded_contract_match? */
bool declaring_friend_p;
/* TRUE if we are presently parsing a template-argument-list. */
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index b3041d9c3d3..8a858be99f7 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -9868,9 +9868,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case POSTCONDITION_STMT:
if (!checked_contract_p (get_contract_semantic (t)))
return true;
- if (!RECUR (CONTRACT_CONDITION (t), rval))
- return false;
- return true;
+ return RECUR (CONTRACT_CONDITION (t), rval);
case LABEL_EXPR:
t = LABEL_EXPR_LABEL (t);
diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
index dc0df471dfc..6db3b750fda 100644
--- a/gcc/cp/contracts.cc
+++ b/gcc/cp/contracts.cc
@@ -138,14 +138,14 @@ along with GCC; see the file COPYING3. If not see
For cdtors a post contract is implemented using a CLEANUP_STMT.
- FIXME the compiler already handles sharing cleanup code on multiple exit
- paths properly, so this outlining seems unnecessary if we represent the
- postcondition as a cleanup for all functions.
+ FIXME the compiler already shores cleanup code on multiple exit paths, so
+ this outlining seems unnecessary if we represent the postcondition as a
+ cleanup for all functions.
More helpful for optimization might be to make the contracts a wrapper
function (for non-variadic functions), that could be inlined into a
caller while preserving the call to the actual function? Either that or
- turn a never-continue post contract into an assume in the caller. */
+ mirror a never-continue post contract with an assume in the caller. */
#include "config.h"
#include "system.h"
@@ -942,7 +942,7 @@ void copy_contract_attributes (tree olddecl, tree newdecl)
/* Returns the parameter corresponding to the return value of a guarded
function D. Returns NULL_TREE if D has no postconditions or is void. */
-tree
+static tree
get_postcondition_result_parameter (tree d)
{
if (!d || d == error_mark_node)
@@ -994,7 +994,7 @@ retain_decl (tree decl, copy_body_data *)
This is also used to reuse a parent type's contracts on virtual methods. */
-void
+static void
remap_contract (tree src, tree dst, tree contract, bool duplicate_p)
{
copy_body_data id;
@@ -1101,7 +1101,7 @@ remap_dummy_this_1 (tree *tp, int *, void *data)
/* Replace all references to dummy this parameters in EXPR with references to
the first argument of the FUNCTION_DECL FN. */
-void
+static void
remap_dummy_this (tree fn, tree *expr)
{
walk_tree (expr, remap_dummy_this_1, fn, NULL);
@@ -1536,7 +1536,7 @@ handle_contracts_p (tree decl1)
{
return (flag_contracts
&& !processing_template_decl
- && DECL_ORIGINAL_FN (decl1) == NULL_TREE
+ && DECL_ABSTRACT_ORIGIN (decl1) == NULL_TREE
&& contract_any_active_p (DECL_CONTRACTS (decl1)));
}
@@ -1579,7 +1579,7 @@ build_postcondition_function (tree d)
return build_contract_condition_function (d, /*pre=*/false);
}
-void
+static void
build_contract_function_decls (tree d)
{
/* Constructors and destructors have their contracts inserted inline. */
@@ -1592,25 +1592,6 @@ build_contract_function_decls (tree d)
set_contract_functions (d, pre, post);
}
-/* Begin a new scope for the postcondition. */
-
-tree
-start_postcondition_statement ()
-{
- tree list = push_stmt_list ();
- tree stmt = begin_compound_stmt (BCS_NORMAL);
- return build_tree_list (list, stmt);
-}
-
-/* Finish the block containing the postcondition check. */
-
-void
-finish_postcondition_statement (tree stmt)
-{
- finish_compound_stmt (TREE_VALUE (stmt));
- pop_stmt_list (TREE_PURPOSE (stmt));
-}
-
static const char *
get_contract_level_name (tree contract)
{
@@ -1887,7 +1868,7 @@ emit_assertion (tree attr)
/* Emit statements for precondition attributes. */
-void
+static void
emit_preconditions (tree attr)
{
return emit_contract_conditions (attr, PRECONDITION_STMT);
@@ -1895,7 +1876,7 @@ emit_preconditions (tree attr)
/* Emit statements for postcondition attributes. */
-void
+static void
emit_postconditions_cleanup (tree contracts)
{
tree stmts = push_stmt_list ();
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index c845c3d7e8c..9e591d592cf 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -13256,14 +13256,14 @@ grokdeclarator (const cp_declarator *declarator,
returned_attrs = attr_chainon (returned_attrs, att);
}
- /* Contract attributes appertain to the declaration. */
+ /* Actually apply the contract attributes to the declaration. */
for (tree *p = &attrs; *p;)
{
tree l = *p;
if (cxx_contract_attribute_p (l))
{
*p = TREE_CHAIN (l);
- /* Intentially reverse order of contracts so they're
+ /* Intentionally reverse order of contracts so they're
reversed back into their lexical order. */
TREE_CHAIN (l) = NULL_TREE;
returned_attrs = chainon (l, returned_attrs);
@@ -18244,7 +18244,6 @@ finish_function (bool inline_p)
return fndecl;
}
-
\f
/* Create the FUNCTION_DECL for a function definition.
DECLSPECS and DECLARATOR are the parts of the declaration;
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 90f945a615b..fdf85c365db 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -10825,7 +10825,7 @@ check_mergeable_decl (merge_kind mk, tree decl, tree ovl, merge_key const &key)
&& (!DECL_IS_UNDECLARED_BUILTIN (m_inner)
|| !DECL_EXTERN_C_P (m_inner)
|| DECL_EXTERN_C_P (d_inner))
- /* Reject if one is they're different member of a
+ /* Reject if one is a different member of a
guarded/pre/post fn set. */
&& (!flag_contracts
|| (DECL_IS_PRE_FN_P (d_inner)
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-11-02 18:44 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-01 11:43 [gcc/devel/c++-contracts] c++: more tidying Jason Merrill
2022-11-02 18:44 Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).