Home | History | Annotate | Line # | Download | only in cp
      1 /* Definitions for C++ contract levels
      2    Copyright (C) 2020-2024 Free Software Foundation, Inc.
      3    Contributed by Jeff Chapman II (jchapman (at) lock3software.com)
      4 
      5 This file is part of GCC.
      6 
      7 GCC is free software; you can redistribute it and/or modify
      8 it under the terms of the GNU General Public License as published by
      9 the Free Software Foundation; either version 3, or (at your option)
     10 any later version.
     11 
     12 GCC is distributed in the hope that it will be useful,
     13 but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with GCC; see the file COPYING3.  If not see
     19 <http://www.gnu.org/licenses/>.  */
     20 
     21 /* Design Notes
     22 
     23    A function is called a "guarded" function if it has pre or post contract
     24    attributes. A contract is considered an "active" contract if runtime code is
     25    needed for the contract under the current contract configuration.
     26 
     27    pre and post contract attributes are parsed and stored in DECL_ATTRIBUTES.
     28    assert contracts are parsed and wrapped in statements. When genericizing, all
     29    active and assumed contracts are transformed into an if block. An observed
     30    contract:
     31 
     32      [[ pre: v > 0 ]]
     33 
     34    is transformed into:
     35 
     36      if (!(v > 0)) {
     37        handle_contract_violation(__pseudo_contract_violation{
     38 	 5, // line_number,
     39 	 "main.cpp", // file_name,
     40 	 "fun", // function_name,
     41 	 "v > 0", // comment,
     42 	 "default", // assertion_level,
     43 	 "default", // assertion_role,
     44 	 maybe_continue, // continuation_mode
     45        });
     46        terminate (); // if never_continue
     47      }
     48 
     49    We use an internal type with the same layout as contract_violation rather
     50    than try to define the latter internally and somehow deal with its actual
     51    definition in a TU that includes <contract>.
     52 
     53    ??? is it worth factoring out the calls to handle_contract_violation and
     54    terminate into a local function?
     55 
     56    Assumed contracts use the same implementation as C++23 [[assume]].
     57 
     58    Parsing of pre and post contract conditions need to be deferred when the
     59    contracts are attached to a member function. The postcondition identifier
     60    cannot be used before the deduced return type of an auto function is used,
     61    except when used in a defining declaration in which case they conditions are
     62    fully parsed once the body is finished (see cpp2a/contracts-deduced{1,2}.C).
     63 
     64    A list of pre and post contracts can either be repeated in their entirety or
     65    completely absent in subsequent declarations. If contract lists appear on two
     66    matching declarations, their contracts have to be equivalent. In general this
     67    means that anything before the colon have to be token equivalent and the
     68    condition must be cp_tree_equal (primarily to allow for parameter renaming).
     69 
     70    Contracts on overrides must match those present on (all of) the overridee(s).
     71 
     72    Template specializations may have their own contracts. If no contracts are
     73    specified on the initial specialization they're assumed to be the same as
     74    the primary template. Specialization redeclarations must then match either
     75    the primary template (if they were unspecified originally), or those
     76    specified on the specialization.
     77 
     78 
     79    For non-cdtors two functions are generated for ease of implementation and to
     80    avoid some cases where code bloat may occurr. These are the DECL_PRE_FN and
     81    DECL_POST_FN. Each handles checking either the set of pre or post contracts
     82    of a guarded function.
     83 
     84      int fun(int v)
     85        [[ pre: v > 0 ]]
     86        [[ post r: r < 0 ]]
     87      {
     88        return -v;
     89      }
     90 
     91    We implement the checking as follows:
     92 
     93    For functions with no post-conditions we wrap the original function body as
     94    follows:
     95 
     96    {
     97       handle_pre_condition_checking ();
     98       original_function_body ();
     99    }
    100 
    101    This implements the intent that the preconditions are processed after the
    102    function parameters are initialised but before any other actions.
    103 
    104    For functions with post-conditions:
    105 
    106    if (preconditions_exist)
    107      handle_pre_condition_checking ();
    108    try
    109      {
    110        original_function_body ();
    111      }
    112    finally
    113      {
    114        handle_post_condition_checking ();
    115      }
    116    else [only if the function is not marked noexcept(true) ]
    117      {
    118        ;
    119      }
    120 
    121    In this, post-conditions [that might apply to the return value etc.] are
    122    evaluated on every non-exceptional edge out of the function.
    123 
    124    FIXME outlining contract checks into separate functions was motivated
    125    partly by wanting to call the postcondition function at each return
    126    statement, which we no longer do; at this point outlining doesn't seem to
    127    have any advantage over emitting the contracts directly in the function
    128    body.
    129 
    130    More helpful for optimization might be to make the contracts a wrapper
    131    function that could be inlined into the caller, the callee, or both.  */
    132 
    133 #include "config.h"
    134 #include "system.h"
    135 #include "coretypes.h"
    136 #include "cp-tree.h"
    137 #include "stringpool.h"
    138 #include "diagnostic.h"
    139 #include "options.h"
    140 #include "contracts.h"
    141 #include "tree.h"
    142 #include "tree-inline.h"
    143 #include "attribs.h"
    144 #include "tree-iterator.h"
    145 #include "print-tree.h"
    146 #include "stor-layout.h"
    147 #include "intl.h"
    148 
    149 const int max_custom_roles = 32;
    150 static contract_role contract_build_roles[max_custom_roles] = {
    151 };
    152 
    153 bool valid_configs[CCS_MAYBE + 1][CCS_MAYBE + 1] = {
    154   { 0, 0, 0, 0, 0, },
    155   { 0, 1, 0, 0, 0, },
    156   { 0, 1, 1, 1, 1, },
    157   { 0, 1, 1, 1, 1, },
    158   { 0, 1, 0, 0, 1, },
    159 };
    160 
    161 void
    162 validate_contract_role (contract_role *role)
    163 {
    164   gcc_assert (role);
    165   if (!unchecked_contract_p (role->axiom_semantic))
    166     error ("axiom contract semantic must be %<assume%> or %<ignore%>");
    167 
    168   if (!valid_configs[role->default_semantic][role->audit_semantic] )
    169     warning (0, "the %<audit%> semantic should be at least as strong as "
    170 		"the %<default%> semantic");
    171 }
    172 
    173 contract_semantic
    174 lookup_concrete_semantic (const char *name)
    175 {
    176   if (strcmp (name, "ignore") == 0)
    177     return CCS_IGNORE;
    178   if (strcmp (name, "assume") == 0)
    179     return CCS_ASSUME;
    180   if (strcmp (name, "check_never_continue") == 0
    181       || strcmp (name, "never") == 0
    182       || strcmp (name, "abort") == 0)
    183     return CCS_NEVER;
    184   if (strcmp (name, "check_maybe_continue") == 0
    185       || strcmp (name, "maybe") == 0)
    186     return CCS_MAYBE;
    187   error ("'%s' is not a valid explicit concrete semantic", name);
    188   return CCS_INVALID;
    189 }
    190 
    191 /* Compare role and name up to either the NUL terminator or the first
    192    occurrence of colon.  */
    193 
    194 static bool
    195 role_name_equal (const char *role, const char *name)
    196 {
    197   size_t role_len = strcspn (role, ":");
    198   size_t name_len = strcspn (name, ":");
    199   if (role_len != name_len)
    200     return false;
    201   return strncmp (role, name, role_len) == 0;
    202 }
    203 
    204 static bool
    205 role_name_equal (contract_role *role, const char *name)
    206 {
    207   if (role->name == NULL)
    208     return false;
    209   return role_name_equal (role->name, name);
    210 }
    211 
    212 contract_role *
    213 get_contract_role (const char *name)
    214 {
    215   for (int i = 0; i < max_custom_roles; ++i)
    216     {
    217       contract_role *potential = contract_build_roles + i;
    218       if (role_name_equal (potential, name))
    219 	return potential;
    220     }
    221   if (role_name_equal (name, "default") || role_name_equal (name, "review"))
    222     {
    223       setup_default_contract_role (false);
    224       return get_contract_role (name);
    225     }
    226   return NULL;
    227 }
    228 
    229 contract_role *
    230 add_contract_role (const char *name,
    231 		   contract_semantic des,
    232 		   contract_semantic aus,
    233 		   contract_semantic axs,
    234 		   bool update)
    235 {
    236   for (int i = 0; i < max_custom_roles; ++i)
    237     {
    238       contract_role *potential = contract_build_roles + i;
    239       if (potential->name != NULL
    240 	  && !role_name_equal (potential, name))
    241 	continue;
    242       if (potential->name != NULL && !update)
    243 	return potential;
    244       potential->name = name;
    245       potential->default_semantic = des;
    246       potential->audit_semantic = aus;
    247       potential->axiom_semantic = axs;
    248       return potential;
    249     }
    250   return NULL;
    251 }
    252 
    253 enum contract_build_level { OFF, DEFAULT, AUDIT };
    254 static bool flag_contract_continuation_mode = false;
    255 static bool flag_contract_assumption_mode = true;
    256 static int flag_contract_build_level = DEFAULT;
    257 
    258 static bool contracts_p1332_default = false, contracts_p1332_review = false,
    259   contracts_std = false, contracts_p1429 = false;
    260 
    261 static contract_semantic
    262 get_concrete_check ()
    263 {
    264   return flag_contract_continuation_mode ? CCS_MAYBE : CCS_NEVER;
    265 }
    266 
    267 static contract_semantic
    268 get_concrete_axiom_semantic ()
    269 {
    270   return flag_contract_assumption_mode ? CCS_ASSUME : CCS_IGNORE;
    271 }
    272 
    273 void
    274 setup_default_contract_role (bool update)
    275 {
    276   contract_semantic check = get_concrete_check ();
    277   contract_semantic axiom = get_concrete_axiom_semantic ();
    278   switch (flag_contract_build_level)
    279     {
    280       case OFF:
    281 	add_contract_role ("default", CCS_IGNORE, CCS_IGNORE, axiom, update);
    282 	add_contract_role ("review", CCS_IGNORE, CCS_IGNORE, CCS_IGNORE, update);
    283 	break;
    284       case DEFAULT:
    285 	add_contract_role ("default", check, CCS_IGNORE, axiom, update);
    286 	add_contract_role ("review", check, CCS_IGNORE, CCS_IGNORE, update);
    287 	break;
    288       case AUDIT:
    289 	add_contract_role ("default", check, check, axiom, update);
    290 	add_contract_role ("review", check, check, CCS_IGNORE, update);
    291 	break;
    292     }
    293 }
    294 
    295 contract_semantic
    296 map_contract_semantic (const char *ident)
    297 {
    298   if (strcmp (ident, "ignore") == 0)
    299     return CCS_IGNORE;
    300   else if (strcmp (ident, "assume") == 0)
    301     return CCS_ASSUME;
    302   else if (strcmp (ident, "check_never_continue") == 0)
    303     return CCS_NEVER;
    304   else if (strcmp (ident, "check_maybe_continue") == 0)
    305     return CCS_MAYBE;
    306   return CCS_INVALID;
    307 }
    308 
    309 contract_level
    310 map_contract_level (const char *ident)
    311 {
    312   if (strcmp (ident, "default") == 0)
    313     return CONTRACT_DEFAULT;
    314   else if (strcmp (ident, "audit") == 0)
    315     return CONTRACT_AUDIT;
    316   else if (strcmp (ident, "axiom") == 0)
    317     return CONTRACT_AXIOM;
    318   return CONTRACT_INVALID;
    319 }
    320 
    321 
    322 void
    323 handle_OPT_fcontract_build_level_ (const char *arg)
    324 {
    325   if (contracts_p1332_default || contracts_p1332_review || contracts_p1429)
    326     {
    327       error ("%<-fcontract-build-level=%> cannot be mixed with p1332/p1429");
    328       return;
    329     }
    330   else
    331     contracts_std = true;
    332 
    333   if (strcmp (arg, "off") == 0)
    334     flag_contract_build_level = OFF;
    335   else if (strcmp (arg, "default") == 0)
    336     flag_contract_build_level = DEFAULT;
    337   else if (strcmp (arg, "audit") == 0)
    338     flag_contract_build_level = AUDIT;
    339   else
    340     error ("%<-fcontract-build-level=%> must be off|default|audit");
    341 
    342   setup_default_contract_role ();
    343 }
    344 
    345 void
    346 handle_OPT_fcontract_assumption_mode_ (const char *arg)
    347 {
    348   if (contracts_p1332_default || contracts_p1332_review || contracts_p1429)
    349     {
    350       error ("%<-fcontract-assumption-mode=%> cannot be mixed with p1332/p1429");
    351       return;
    352     }
    353   else
    354     contracts_std = true;
    355 
    356   if (strcmp (arg, "on") == 0)
    357     flag_contract_assumption_mode = true;
    358   else if (strcmp (arg, "off") == 0)
    359     flag_contract_assumption_mode = false;
    360   else
    361     error ("%<-fcontract-assumption-mode=%> must be %<on%> or %<off%>");
    362 
    363   setup_default_contract_role ();
    364 }
    365 
    366 void
    367 handle_OPT_fcontract_continuation_mode_ (const char *arg)
    368 {
    369   if (contracts_p1332_default || contracts_p1332_review || contracts_p1429)
    370     {
    371       error ("%<-fcontract-continuation-mode=%> cannot be mixed with p1332/p1429");
    372       return;
    373     }
    374   else
    375     contracts_std = true;
    376 
    377   if (strcmp (arg, "on") == 0)
    378     flag_contract_continuation_mode = true;
    379   else if (strcmp (arg, "off") == 0)
    380     flag_contract_continuation_mode = false;
    381   else
    382     error ("%<-fcontract-continuation-mode=%> must be %<on%> or %<off%>");
    383 
    384   setup_default_contract_role ();
    385 }
    386 
    387 void
    388 handle_OPT_fcontract_role_ (const char *arg)
    389 {
    390   const char *name = arg;
    391   const char *vals = strchr (name, ':');
    392   if (vals == NULL)
    393     {
    394       error ("%<-fcontract-role=%> must be in the form role:semantics");
    395       return;
    396     }
    397 
    398   contract_semantic dess = CCS_INVALID, auss = CCS_INVALID, axss = CCS_INVALID;
    399   char *des = NULL, *aus = NULL, *axs = NULL;
    400   des = xstrdup (vals + 1);
    401 
    402   aus = strchr (des, ',');
    403   if (aus == NULL)
    404     {
    405       error ("%<-fcontract-role=%> semantics must include default,audit,axiom values");
    406       goto validate;
    407     }
    408   *aus = '\0'; // null terminate des
    409   aus = aus + 1; // move past null
    410 
    411   axs = strchr (aus, ',');
    412   if (axs == NULL)
    413     {
    414       error ("%<-fcontract-role=%> semantics must include default,audit,axiom values");
    415       goto validate;
    416     }
    417   *axs = '\0'; // null terminate aus
    418   axs = axs + 1; // move past null
    419 
    420   dess = lookup_concrete_semantic (des);
    421   auss = lookup_concrete_semantic (aus);
    422   axss = lookup_concrete_semantic (axs);
    423 validate:
    424   free (des);
    425   if (dess == CCS_INVALID || auss == CCS_INVALID || axss == CCS_INVALID)
    426     return;
    427 
    428   bool is_defalult_role = role_name_equal (name, "default");
    429   bool is_review_role = role_name_equal (name, "review");
    430   bool is_std_role = is_defalult_role || is_review_role;
    431   if ((contracts_std && is_std_role) || (contracts_p1429 && is_defalult_role))
    432     {
    433       error ("%<-fcontract-role=%> cannot be mixed with std/p1429 contract flags");
    434       return;
    435     }
    436   else if (is_std_role)
    437     {
    438       contracts_p1332_default |= is_defalult_role;
    439       contracts_p1332_review |= is_review_role;
    440     }
    441 
    442   contract_role *role = add_contract_role (name, dess, auss, axss);
    443 
    444   if (role == NULL)
    445     {
    446       // TODO: not enough space?
    447       error ("%<-fcontract-level=%> too many custom roles");
    448       return;
    449     }
    450   else
    451     validate_contract_role (role);
    452 }
    453 
    454 void
    455 handle_OPT_fcontract_semantic_ (const char *arg)
    456 {
    457   if (!strchr (arg, ':'))
    458     {
    459       error ("%<-fcontract-semantic=%> must be in the form level:semantic");
    460       return;
    461     }
    462 
    463   if (contracts_std || contracts_p1332_default)
    464     {
    465       error ("%<-fcontract-semantic=%> cannot be mixed with std/p1332 contract flags");
    466       return;
    467     }
    468   contracts_p1429 = true;
    469 
    470   contract_role *role = get_contract_role ("default");
    471   if (!role)
    472     {
    473       error ("%<-fcontract-semantic=%> cannot find default role");
    474       return;
    475     }
    476 
    477   const char *semantic = strchr (arg, ':') + 1;
    478   contract_semantic sem = lookup_concrete_semantic (semantic);
    479   if (sem == CCS_INVALID)
    480     return;
    481 
    482   if (strncmp ("default:", arg, 8) == 0)
    483     role->default_semantic = sem;
    484   else if (strncmp ("audit:", arg, 6) == 0)
    485     role->audit_semantic = sem;
    486   else if (strncmp ("axiom:", arg, 6) == 0)
    487     role->axiom_semantic = sem;
    488   else
    489     error ("%<-fcontract-semantic=%> level must be default, audit, or axiom");
    490   validate_contract_role (role);
    491 }
    492 
    493 /* Convert a contract CONFIG into a contract_mode.  */
    494 
    495 static contract_mode
    496 contract_config_to_mode (tree config)
    497 {
    498   if (config == NULL_TREE)
    499     return contract_mode (CONTRACT_DEFAULT, get_default_contract_role ());
    500 
    501   /* TREE_LIST has TREE_VALUE is a level and TREE_PURPOSE is role.  */
    502   if (TREE_CODE (config) == TREE_LIST)
    503     {
    504       contract_role *role = NULL;
    505       if (TREE_PURPOSE (config))
    506 	role = get_contract_role (IDENTIFIER_POINTER (TREE_PURPOSE (config)));
    507       if (!role)
    508 	role = get_default_contract_role ();
    509 
    510       contract_level level =
    511 	map_contract_level (IDENTIFIER_POINTER (TREE_VALUE (config)));
    512       return contract_mode (level, role);
    513     }
    514 
    515   /* Literal semantic.  */
    516   gcc_assert (TREE_CODE (config) == IDENTIFIER_NODE);
    517   contract_semantic semantic =
    518     map_contract_semantic (IDENTIFIER_POINTER (config));
    519   return contract_mode (semantic);
    520 }
    521 
    522 /* Convert a contract's config into a concrete semantic using the current
    523    contract semantic mapping.  */
    524 
    525 static contract_semantic
    526 compute_concrete_semantic (tree contract)
    527 {
    528   contract_mode mode = contract_config_to_mode (CONTRACT_MODE (contract));
    529   /* Compute the concrete semantic for the contract.  */
    530   if (!flag_contract_mode)
    531     /* If contracts are off, treat all contracts as ignore.  */
    532     return CCS_IGNORE;
    533   else if (mode.kind == contract_mode::cm_invalid)
    534     return CCS_INVALID;
    535   else if (mode.kind == contract_mode::cm_explicit)
    536     return mode.get_semantic ();
    537   else
    538     {
    539       gcc_assert (mode.get_role ());
    540       gcc_assert (mode.get_level () != CONTRACT_INVALID);
    541       contract_level level = mode.get_level ();
    542       contract_role *role = mode.get_role ();
    543       if (level == CONTRACT_DEFAULT)
    544 	return role->default_semantic;
    545       else if (level == CONTRACT_AUDIT)
    546 	return role->audit_semantic;
    547       else if (level == CONTRACT_AXIOM)
    548 	return role->axiom_semantic;
    549     }
    550   gcc_assert (false);
    551 }
    552 
    553 /* Return true if any contract in CONTRACT_ATTRs is not yet parsed.  */
    554 
    555 bool
    556 contract_any_deferred_p (tree contract_attr)
    557 {
    558   for (; contract_attr; contract_attr = CONTRACT_CHAIN (contract_attr))
    559     if (CONTRACT_CONDITION_DEFERRED_P (CONTRACT_STATEMENT (contract_attr)))
    560       return true;
    561   return false;
    562 }
    563 
    564 /* Returns true if all attributes are contracts.  */
    565 
    566 bool
    567 all_attributes_are_contracts_p (tree attributes)
    568 {
    569   for (; attributes; attributes = TREE_CHAIN (attributes))
    570     if (!cxx_contract_attribute_p (attributes))
    571       return false;
    572   return true;
    573 }
    574 
    575 /* Mark most of a contract as being invalid.  */
    576 
    577 tree
    578 invalidate_contract (tree t)
    579 {
    580   if (TREE_CODE (t) == POSTCONDITION_STMT && POSTCONDITION_IDENTIFIER (t))
    581     POSTCONDITION_IDENTIFIER (t) = error_mark_node;
    582   CONTRACT_CONDITION (t) = error_mark_node;
    583   CONTRACT_COMMENT (t) = error_mark_node;
    584   return t;
    585 }
    586 
    587 /* Returns an invented parameter declration of the form 'TYPE ID' for the
    588    purpose of parsing the postcondition.
    589 
    590    We use a PARM_DECL instead of a VAR_DECL so that tsubst forces a lookup
    591    in local specializations when we instantiate these things later.  */
    592 
    593 tree
    594 make_postcondition_variable (cp_expr id, tree type)
    595 {
    596   if (id == error_mark_node)
    597     return id;
    598 
    599   tree decl = build_lang_decl (PARM_DECL, id, type);
    600   DECL_ARTIFICIAL (decl) = true;
    601   DECL_SOURCE_LOCATION (decl) = id.get_location ();
    602 
    603   pushdecl (decl);
    604   return decl;
    605 }
    606 
    607 /* As above, except that the type is unknown.  */
    608 
    609 tree
    610 make_postcondition_variable (cp_expr id)
    611 {
    612   return make_postcondition_variable (id, make_auto ());
    613 }
    614 
    615 /* Check that the TYPE is valid for a named postcondition variable. Emit a
    616    diagnostic if it is not.  Returns TRUE if the result is OK and false
    617    otherwise.  */
    618 
    619 bool
    620 check_postcondition_result (tree decl, tree type, location_t loc)
    621 {
    622   /* Do not be confused by targetm.cxx.cdtor_return_this ();
    623      conceptually, cdtors have no return value.  */
    624   if (VOID_TYPE_P (type)
    625       || DECL_CONSTRUCTOR_P (decl)
    626       || DECL_DESTRUCTOR_P (decl))
    627     {
    628       error_at (loc,
    629 		DECL_CONSTRUCTOR_P (decl)
    630 		? G_("constructor does not return a value to test")
    631 		: DECL_DESTRUCTOR_P (decl)
    632 		? G_("destructor does not return a value to test")
    633 		: G_("function does not return a value to test"));
    634       return false;
    635     }
    636 
    637   return true;
    638 }
    639 
    640 /* Instantiate each postcondition with the return type to finalize the
    641    attribute.  */
    642 
    643 void
    644 rebuild_postconditions (tree decl)
    645 {
    646   tree type = TREE_TYPE (TREE_TYPE (decl));
    647   tree attributes = DECL_CONTRACTS (decl);
    648 
    649   for (; attributes ; attributes = TREE_CHAIN (attributes))
    650     {
    651       if (!cxx_contract_attribute_p (attributes))
    652 	continue;
    653       tree contract = TREE_VALUE (TREE_VALUE (attributes));
    654       if (TREE_CODE (contract) != POSTCONDITION_STMT)
    655 	continue;
    656       tree condition = CONTRACT_CONDITION (contract);
    657 
    658       /* If any conditions are deferred, they're all deferred.  Note that
    659 	 we don't have to instantiate postconditions in that case because
    660 	 the type is available through the declaration.  */
    661       if (TREE_CODE (condition) == DEFERRED_PARSE)
    662 	return;
    663 
    664       tree oldvar = POSTCONDITION_IDENTIFIER (contract);
    665       if (!oldvar)
    666 	continue;
    667 
    668       /* Always update the context of the result variable so that it can
    669 	 be remapped by remap_contracts.  */
    670       DECL_CONTEXT (oldvar) = decl;
    671 
    672       /* If the return type is undeduced, defer until later.  */
    673       if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
    674 	return;
    675 
    676       /* Check the postcondition variable.  */
    677       location_t loc = DECL_SOURCE_LOCATION (oldvar);
    678       if (!check_postcondition_result (decl, type, loc))
    679 	{
    680 	  invalidate_contract (contract);
    681 	  continue;
    682 	}
    683 
    684       /* "Instantiate" the result variable using the known type.  Also update
    685 	  the context so the inliner will actually remap this the parameter when
    686 	  generating contract checks.  */
    687       tree newvar = copy_node (oldvar);
    688       TREE_TYPE (newvar) = type;
    689 
    690       /* Make parameters and result available for substitution.  */
    691       local_specialization_stack stack (lss_copy);
    692       for (tree t = DECL_ARGUMENTS (decl); t != NULL_TREE; t = TREE_CHAIN (t))
    693 	register_local_identity (t);
    694       register_local_specialization (newvar, oldvar);
    695 
    696       ++processing_contract_condition;
    697       condition = tsubst_expr (condition, make_tree_vec (0),
    698 			       tf_warning_or_error, decl);
    699       --processing_contract_condition;
    700 
    701       /* Update the contract condition and result.  */
    702       POSTCONDITION_IDENTIFIER (contract) = newvar;
    703       CONTRACT_CONDITION (contract) = finish_contract_condition (condition);
    704     }
    705 }
    706 
    707 static tree
    708 build_comment (cp_expr condition)
    709 {
    710   /* Try to get the actual source text for the condition; if that fails pretty
    711      print the resulting tree.  */
    712   char *str = get_source_text_between (global_dc->get_file_cache (),
    713 				       condition.get_start (),
    714 				       condition.get_finish ());
    715   if (!str)
    716     {
    717       /* FIXME cases where we end up here
    718 	 #line macro usage (oof)
    719 	 contracts10.C
    720 	 contracts11.C  */
    721       const char *str = expr_to_string (condition);
    722       return build_string_literal (strlen (str) + 1, str);
    723     }
    724 
    725   tree t = build_string_literal (strlen (str) + 1, str);
    726   free (str);
    727   return t;
    728 }
    729 
    730 /* Build a contract statement.  */
    731 
    732 tree
    733 grok_contract (tree attribute, tree mode, tree result, cp_expr condition,
    734 	       location_t loc)
    735 {
    736   tree_code code;
    737   if (is_attribute_p ("assert", attribute))
    738     code = ASSERTION_STMT;
    739   else if (is_attribute_p ("pre", attribute))
    740     code = PRECONDITION_STMT;
    741   else if (is_attribute_p ("post", attribute))
    742     code = POSTCONDITION_STMT;
    743   else
    744     gcc_unreachable ();
    745 
    746   /* Build the contract. The condition is added later.  In the case that
    747      the contract is deferred, result an plain identifier, not a result
    748      variable.  */
    749   tree contract;
    750   tree type = void_type_node;
    751   if (code != POSTCONDITION_STMT)
    752     contract = build3_loc (loc, code, type, mode, NULL_TREE, NULL_TREE);
    753   else
    754     contract = build4_loc (loc, code, type, mode, NULL_TREE, NULL_TREE, result);
    755 
    756   /* Determine the concrete semantic.  */
    757   set_contract_semantic (contract, compute_concrete_semantic (contract));
    758 
    759   /* If the contract is deferred, don't do anything with the condition.  */
    760   if (TREE_CODE (condition) == DEFERRED_PARSE)
    761     {
    762       CONTRACT_CONDITION (contract) = condition;
    763       return contract;
    764     }
    765 
    766   /* Generate the comment from the original condition.  */
    767   CONTRACT_COMMENT (contract) = build_comment (condition);
    768 
    769   /* The condition is converted to bool.  */
    770   condition = finish_contract_condition (condition);
    771   CONTRACT_CONDITION (contract) = condition;
    772 
    773   return contract;
    774 }
    775 
    776 /* Build the contract attribute specifier where IDENTIFIER is one of 'pre',
    777    'post' or 'assert' and CONTRACT is the underlying statement.  */
    778 tree
    779 finish_contract_attribute (tree identifier, tree contract)
    780 {
    781   if (contract == error_mark_node)
    782     return error_mark_node;
    783 
    784   tree attribute = build_tree_list (build_tree_list (NULL_TREE, identifier),
    785 				    build_tree_list (NULL_TREE, contract));
    786 
    787   /* Mark the attribute as dependent if the condition is dependent.
    788 
    789      TODO: I'm not sure this is strictly necessary. It's going to be marked as
    790      such by a subroutine of cplus_decl_attributes. */
    791   tree condition = CONTRACT_CONDITION (contract);
    792   if (TREE_CODE (condition) == DEFERRED_PARSE
    793       || value_dependent_expression_p (condition))
    794     ATTR_IS_DEPENDENT (attribute) = true;
    795 
    796   return attribute;
    797 }
    798 
    799 /* Update condition of a late-parsed contract and postcondition variable,
    800    if any.  */
    801 
    802 void
    803 update_late_contract (tree contract, tree result, tree condition)
    804 {
    805   if (TREE_CODE (contract) == POSTCONDITION_STMT)
    806     POSTCONDITION_IDENTIFIER (contract) = result;
    807 
    808   /* Generate the comment from the original condition.  */
    809   CONTRACT_COMMENT (contract) = build_comment (condition);
    810 
    811   /* The condition is converted to bool.  */
    812   condition = finish_contract_condition (condition);
    813   CONTRACT_CONDITION (contract) = condition;
    814 }
    815 
    816 /* Return TRUE iff ATTR has been parsed by the front-end as a c++2a contract
    817    attribute. */
    818 
    819 bool
    820 cxx_contract_attribute_p (const_tree attr)
    821 {
    822   if (attr == NULL_TREE
    823       || TREE_CODE (attr) != TREE_LIST)
    824     return false;
    825 
    826   if (!TREE_PURPOSE (attr) || TREE_CODE (TREE_PURPOSE (attr)) != TREE_LIST)
    827     return false;
    828   if (!TREE_VALUE (attr) || TREE_CODE (TREE_VALUE (attr)) != TREE_LIST)
    829     return false;
    830   if (!TREE_VALUE (TREE_VALUE (attr)))
    831     return false;
    832 
    833   return (TREE_CODE (TREE_VALUE (TREE_VALUE (attr))) == PRECONDITION_STMT
    834       || TREE_CODE (TREE_VALUE (TREE_VALUE (attr))) == POSTCONDITION_STMT
    835       || TREE_CODE (TREE_VALUE (TREE_VALUE (attr))) == ASSERTION_STMT);
    836 }
    837 
    838 /* True if ATTR is an assertion.  */
    839 
    840 bool
    841 cp_contract_assertion_p (const_tree attr)
    842 {
    843   /* This is only an assertion if it is a valid cxx contract attribute and the
    844      statement is an ASSERTION_STMT.  */
    845   return cxx_contract_attribute_p (attr)
    846     && TREE_CODE (CONTRACT_STATEMENT (attr)) == ASSERTION_STMT;
    847 }
    848 
    849 /* Remove all c++2a style contract attributes from the DECL_ATTRIBUTEs of the
    850    FUNCTION_DECL FNDECL.  */
    851 
    852 void
    853 remove_contract_attributes (tree fndecl)
    854 {
    855   if (!flag_contracts)
    856     return;
    857 
    858   tree list = NULL_TREE;
    859   for (tree p = DECL_ATTRIBUTES (fndecl); p; p = TREE_CHAIN (p))
    860     if (!cxx_contract_attribute_p (p))
    861       {
    862 	tree nl = copy_node (p);
    863 	TREE_CHAIN (nl) = list;
    864 	list = nl;
    865       }
    866   DECL_ATTRIBUTES (fndecl) = nreverse (list);
    867 }
    868 
    869 static tree find_first_non_contract (tree attributes)
    870 {
    871   tree head = attributes;
    872   tree p = find_contract (attributes);
    873 
    874   /* There are no contracts.  */
    875   if (!p)
    876     return head;
    877 
    878   /* There are leading contracts.  */
    879   if (p == head)
    880     {
    881       while (cxx_contract_attribute_p (p))
    882 	p = TREE_CHAIN (p);
    883       head = p;
    884     }
    885 
    886   return head;
    887 }
    888 
    889 /* Remove contracts from ATTRIBUTES.  */
    890 
    891 tree splice_out_contracts (tree attributes)
    892 {
    893   tree head = find_first_non_contract (attributes);
    894   if (!head)
    895     return NULL_TREE;
    896 
    897   /* Splice out remaining contracts.  */
    898   tree p = TREE_CHAIN (head);
    899   tree q = head;
    900   while (p)
    901     {
    902       if (cxx_contract_attribute_p (p))
    903 	{
    904 	  /* Skip a sequence of contracts and then link q to the next
    905 	     non-contract attribute.  */
    906 	  do
    907 	    p = TREE_CHAIN (p);
    908 	  while (cxx_contract_attribute_p (p));
    909 	  TREE_CHAIN (q) = p;
    910 	}
    911       else
    912 	p = TREE_CHAIN (p);
    913     }
    914 
    915   return head;
    916 }
    917 
    918 /* Copy contract attributes from NEWDECL onto the attribute list of OLDDECL.  */
    919 
    920 void copy_contract_attributes (tree olddecl, tree newdecl)
    921 {
    922   tree attrs = NULL_TREE;
    923   for (tree c = DECL_CONTRACTS (newdecl); c; c = TREE_CHAIN (c))
    924     {
    925       if (!cxx_contract_attribute_p (c))
    926 	continue;
    927       attrs = tree_cons (TREE_PURPOSE (c), TREE_VALUE (c), attrs);
    928     }
    929   attrs = chainon (DECL_ATTRIBUTES (olddecl), nreverse (attrs));
    930   DECL_ATTRIBUTES (olddecl) = attrs;
    931 
    932   /* And update DECL_CONTEXT of the postcondition result identifier.  */
    933   rebuild_postconditions (olddecl);
    934 }
    935 
    936 /* Returns the parameter corresponding to the return value of a guarded
    937    function D.  Returns NULL_TREE if D has no postconditions or is void.  */
    938 
    939 static tree
    940 get_postcondition_result_parameter (tree d)
    941 {
    942   if (!d || d == error_mark_node)
    943     return NULL_TREE;
    944 
    945   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (d))))
    946     return NULL_TREE;
    947 
    948   tree post = DECL_POST_FN (d);
    949   if (!post || post == error_mark_node)
    950     return NULL_TREE;
    951 
    952   for (tree arg = DECL_ARGUMENTS (post); arg; arg = TREE_CHAIN (arg))
    953     if (!TREE_CHAIN (arg))
    954       return arg;
    955 
    956   return NULL_TREE;
    957 }
    958 
    959 
    960 /* For use with the tree inliner. This preserves non-mapped local variables,
    961    such as postcondition result variables, during remapping.  */
    962 
    963 static tree
    964 retain_decl (tree decl, copy_body_data *)
    965 {
    966   return decl;
    967 }
    968 
    969 /* Rewrite the condition of contract in place, so that references to SRC's
    970    parameters are updated to refer to DST's parameters. The postcondition
    971    result variable is left unchanged.
    972 
    973    This, along with remap_contracts, are subroutines of duplicate_decls.
    974    When declarations are merged, we sometimes need to update contracts to
    975    refer to new parameters.
    976 
    977    If DUPLICATE_P is true, this is called by duplicate_decls to rewrite contacts
    978    in terms of a new set of parameters. In this case, we can retain local
    979    variables appearing in the contract because the contract is not being
    980    prepared for insertion into a new function. Importantly, this preserves the
    981    references to postcondition results, which are not replaced during merging.
    982 
    983    If false, we're preparing to emit the contract condition into the body
    984    of a new function, so we need to make copies of all local variables
    985    appearing in the contract (e.g., if it includes a lambda expression). Note
    986    that in this case, postcondition results are mapped to the last parameter
    987    of DST.
    988 
    989    This is also used to reuse a parent type's contracts on virtual methods.  */
    990 
    991 static void
    992 remap_contract (tree src, tree dst, tree contract, bool duplicate_p)
    993 {
    994   copy_body_data id;
    995   hash_map<tree, tree> decl_map;
    996 
    997   memset (&id, 0, sizeof (id));
    998   id.src_fn = src;
    999   id.dst_fn = dst;
   1000   id.src_cfun = DECL_STRUCT_FUNCTION (src);
   1001   id.decl_map = &decl_map;
   1002 
   1003   /* If we're merging contracts, don't copy local variables.  */
   1004   id.copy_decl = duplicate_p ? retain_decl : copy_decl_no_change;
   1005 
   1006   id.transform_call_graph_edges = CB_CGE_DUPLICATE;
   1007   id.transform_new_cfg = false;
   1008   id.transform_return_to_modify = false;
   1009   id.transform_parameter = true;
   1010 
   1011   /* Make sure not to unshare trees behind the front-end's back
   1012      since front-end specific mechanisms may rely on sharing.  */
   1013   id.regimplify = false;
   1014   id.do_not_unshare = true;
   1015   id.do_not_fold = true;
   1016 
   1017   /* We're not inside any EH region.  */
   1018   id.eh_lp_nr = 0;
   1019 
   1020   bool do_remap = false;
   1021 
   1022   /* Insert parameter remappings.  */
   1023   if (TREE_CODE (src) == FUNCTION_DECL)
   1024     src = DECL_ARGUMENTS (src);
   1025   if (TREE_CODE (dst) == FUNCTION_DECL)
   1026     dst = DECL_ARGUMENTS (dst);
   1027 
   1028   for (tree sp = src, dp = dst;
   1029        sp || dp;
   1030        sp = DECL_CHAIN (sp), dp = DECL_CHAIN (dp))
   1031     {
   1032       if (!sp && dp
   1033 	  && TREE_CODE (contract) == POSTCONDITION_STMT
   1034 	  && DECL_CHAIN (dp) == NULL_TREE)
   1035 	{
   1036 	  gcc_assert (!duplicate_p);
   1037 	  if (tree result = POSTCONDITION_IDENTIFIER (contract))
   1038 	    {
   1039 	      gcc_assert (DECL_P (result));
   1040 	      insert_decl_map (&id, result, dp);
   1041 	      do_remap = true;
   1042 	    }
   1043 	  break;
   1044 	}
   1045       gcc_assert (sp && dp);
   1046 
   1047       if (sp == dp)
   1048 	continue;
   1049 
   1050       insert_decl_map (&id, sp, dp);
   1051       do_remap = true;
   1052     }
   1053   if (!do_remap)
   1054     return;
   1055 
   1056   walk_tree (&CONTRACT_CONDITION (contract), copy_tree_body_r, &id, NULL);
   1057 }
   1058 
   1059 /* Rewrite any references to SRC's PARM_DECLs to the corresponding PARM_DECL in
   1060    DST in all of the contract attributes in CONTRACTS by calling remap_contract
   1061    on each.
   1062 
   1063    This is used for two purposes: to rewrite contract attributes during
   1064    duplicate_decls, and to prepare contracts for emission into a function's
   1065    respective precondition and postcondition functions. DUPLICATE_P is used
   1066    to determine the context in which this function is called. See above for
   1067    the behavior described by this flag.  */
   1068 
   1069 void
   1070 remap_contracts (tree src, tree dst, tree contracts, bool duplicate_p)
   1071 {
   1072   for (tree attr = contracts; attr; attr = CONTRACT_CHAIN (attr))
   1073     {
   1074       if (!cxx_contract_attribute_p (attr))
   1075 	continue;
   1076       tree contract = CONTRACT_STATEMENT (attr);
   1077       if (TREE_CODE (CONTRACT_CONDITION (contract)) != DEFERRED_PARSE)
   1078 	remap_contract (src, dst, contract, duplicate_p);
   1079     }
   1080 }
   1081 
   1082 /* Helper to replace references to dummy this parameters with references to
   1083    the first argument of the FUNCTION_DECL DATA.  */
   1084 
   1085 static tree
   1086 remap_dummy_this_1 (tree *tp, int *, void *data)
   1087 {
   1088   if (!is_this_parameter (*tp))
   1089     return NULL_TREE;
   1090   tree fn = (tree)data;
   1091   *tp = DECL_ARGUMENTS (fn);
   1092   return NULL_TREE;
   1093 }
   1094 
   1095 /* Replace all references to dummy this parameters in EXPR with references to
   1096    the first argument of the FUNCTION_DECL FN.  */
   1097 
   1098 static void
   1099 remap_dummy_this (tree fn, tree *expr)
   1100 {
   1101   walk_tree (expr, remap_dummy_this_1, fn, NULL);
   1102 }
   1103 
   1104 /* Contract matching.  */
   1105 
   1106 /* True if the contract is valid.  */
   1107 
   1108 static bool
   1109 contract_valid_p (tree contract)
   1110 {
   1111   return CONTRACT_CONDITION (contract) != error_mark_node;
   1112 }
   1113 
   1114 /* True if the contract attribute is valid.  */
   1115 
   1116 static bool
   1117 contract_attribute_valid_p (tree attribute)
   1118 {
   1119   return contract_valid_p (TREE_VALUE (TREE_VALUE (attribute)));
   1120 }
   1121 
   1122 /* Compare the contract conditions of OLD_ATTR and NEW_ATTR. Returns false
   1123    if the conditions are equivalent, and true otherwise.  */
   1124 
   1125 static bool
   1126 check_for_mismatched_contracts (tree old_attr, tree new_attr,
   1127 			       contract_matching_context ctx)
   1128 {
   1129   tree old_contract = CONTRACT_STATEMENT (old_attr);
   1130   tree new_contract = CONTRACT_STATEMENT (new_attr);
   1131 
   1132   /* Different kinds of contracts do not match.  */
   1133   if (TREE_CODE (old_contract) != TREE_CODE (new_contract))
   1134     {
   1135       auto_diagnostic_group d;
   1136       error_at (EXPR_LOCATION (new_contract),
   1137 		ctx == cmc_declaration
   1138 		? "mismatched contract attribute in declaration"
   1139 		: "mismatched contract attribute in override");
   1140       inform (EXPR_LOCATION (old_contract), "previous contract here");
   1141       return true;
   1142     }
   1143 
   1144   /* A deferred contract tentatively matches.  */
   1145   if (CONTRACT_CONDITION_DEFERRED_P (new_contract))
   1146     return false;
   1147 
   1148   /* Compare the conditions of the contracts.  We fold immediately to avoid
   1149      issues comparing contracts on overrides that use parameters -- see
   1150      contracts-pre3.  */
   1151   tree t1 = cp_fully_fold_init (CONTRACT_CONDITION (old_contract));
   1152   tree t2 = cp_fully_fold_init (CONTRACT_CONDITION (new_contract));
   1153 
   1154   /* Compare the contracts. The fold doesn't eliminate conversions to members.
   1155      Set the comparing_override_contracts flag to ensure that references
   1156      through 'this' are equal if they designate the same member, regardless of
   1157      the path those members.  */
   1158   bool saved_comparing_contracts = comparing_override_contracts;
   1159   comparing_override_contracts = (ctx == cmc_override);
   1160   bool matching_p = cp_tree_equal (t1, t2);
   1161   comparing_override_contracts = saved_comparing_contracts;
   1162 
   1163   if (!matching_p)
   1164     {
   1165       auto_diagnostic_group d;
   1166       error_at (EXPR_LOCATION (CONTRACT_CONDITION (new_contract)),
   1167 		ctx == cmc_declaration
   1168 		? "mismatched contract condition in declaration"
   1169 		: "mismatched contract condition in override");
   1170       inform (EXPR_LOCATION (CONTRACT_CONDITION (old_contract)),
   1171 	      "previous contract here");
   1172       return true;
   1173     }
   1174 
   1175   return false;
   1176 }
   1177 
   1178 /* Compare the contract attributes of OLDDECL and NEWDECL. Returns true
   1179    if the contracts match, and false if they differ.  */
   1180 
   1181 bool
   1182 match_contract_conditions (location_t oldloc, tree old_attrs,
   1183 			   location_t newloc, tree new_attrs,
   1184 			   contract_matching_context ctx)
   1185 {
   1186   /* Contracts only match if they are both specified.  */
   1187   if (!old_attrs || !new_attrs)
   1188     return true;
   1189 
   1190   /* Compare each contract in turn.  */
   1191   while (old_attrs && new_attrs)
   1192     {
   1193       /* If either contract is ill-formed, skip the rest of the comparison,
   1194 	 since we've already diagnosed an error.  */
   1195       if (!contract_attribute_valid_p (new_attrs)
   1196 	  || !contract_attribute_valid_p (old_attrs))
   1197 	return false;
   1198 
   1199       if (check_for_mismatched_contracts (old_attrs, new_attrs, ctx))
   1200 	return false;
   1201       old_attrs = CONTRACT_CHAIN (old_attrs);
   1202       new_attrs = CONTRACT_CHAIN (new_attrs);
   1203     }
   1204 
   1205   /* If we didn't compare all attributes, the contracts don't match.  */
   1206   if (old_attrs || new_attrs)
   1207     {
   1208       auto_diagnostic_group d;
   1209       error_at (newloc,
   1210 		ctx == cmc_declaration
   1211 		? "declaration has a different number of contracts than "
   1212 		  "previously declared"
   1213 		: "override has a different number of contracts than "
   1214 		  "previously declared");
   1215       inform (oldloc,
   1216 	      new_attrs
   1217 	      ? "original declaration with fewer contracts here"
   1218 	      : "original declaration with more contracts here");
   1219       return false;
   1220     }
   1221 
   1222   return true;
   1223 }
   1224 
   1225 /* Deferred contract mapping.
   1226 
   1227    This is used to compare late-parsed contracts on overrides with their
   1228    base class functions.
   1229 
   1230    TODO: It seems like this could be replaced by a simple list that maps from
   1231    overrides to their base functions. It's not clear that we really need
   1232    a map to a function + a list of contracts.   */
   1233 
   1234 /* Map from FNDECL to a tree list of contracts that have not been matched or
   1235    diagnosed yet.  The TREE_PURPOSE is the basefn we're overriding, and the
   1236    TREE_VALUE is the list of contract attrs for BASEFN.  */
   1237 
   1238 static hash_map<tree_decl_hash, tree> pending_guarded_decls;
   1239 
   1240 void
   1241 defer_guarded_contract_match (tree fndecl, tree fn, tree contracts)
   1242 {
   1243   if (!pending_guarded_decls.get (fndecl))
   1244     {
   1245       pending_guarded_decls.put (fndecl, build_tree_list (fn, contracts));
   1246       return;
   1247     }
   1248   for (tree pending = *pending_guarded_decls.get (fndecl);
   1249       pending;
   1250       pending = TREE_CHAIN (pending))
   1251     {
   1252       if (TREE_VALUE (pending) == contracts)
   1253 	return;
   1254       if (TREE_CHAIN (pending) == NULL_TREE)
   1255 	TREE_CHAIN (pending) = build_tree_list (fn, contracts);
   1256     }
   1257 }
   1258 
   1259 /* If the FUNCTION_DECL DECL has any contracts that had their matching
   1260    deferred earlier, do that checking now.  */
   1261 
   1262 void
   1263 match_deferred_contracts (tree decl)
   1264 {
   1265   tree *tp = pending_guarded_decls.get (decl);
   1266   if (!tp)
   1267     return;
   1268 
   1269   gcc_assert(!contract_any_deferred_p (DECL_CONTRACTS (decl)));
   1270 
   1271   processing_template_decl_sentinel ptds;
   1272   processing_template_decl = uses_template_parms (decl);
   1273 
   1274   /* Do late contract matching.  */
   1275   for (tree pending = *tp; pending; pending = TREE_CHAIN (pending))
   1276     {
   1277       tree new_contracts = TREE_VALUE (pending);
   1278       location_t new_loc = CONTRACT_SOURCE_LOCATION (new_contracts);
   1279       tree old_contracts = DECL_CONTRACTS (decl);
   1280       location_t old_loc = CONTRACT_SOURCE_LOCATION (old_contracts);
   1281       tree base = TREE_PURPOSE (pending);
   1282       match_contract_conditions (new_loc, new_contracts,
   1283 				 old_loc, old_contracts,
   1284 				 base ? cmc_override : cmc_declaration);
   1285     }
   1286 
   1287   /* Clear out deferred match list so we don't check it twice.  */
   1288   pending_guarded_decls.remove (decl);
   1289 }
   1290 
   1291 /* Map from FUNCTION_DECL to a FUNCTION_DECL for either the PRE_FN or POST_FN.
   1292    These are used to parse contract conditions and are called inside the body
   1293    of the guarded function.  */
   1294 static GTY(()) hash_map<tree, tree> *decl_pre_fn;
   1295 static GTY(()) hash_map<tree, tree> *decl_post_fn;
   1296 
   1297 /* Returns the precondition funtion for D, or null if not set.  */
   1298 
   1299 tree
   1300 get_precondition_function (tree d)
   1301 {
   1302   hash_map_maybe_create<hm_ggc> (decl_pre_fn);
   1303   tree *result = decl_pre_fn->get (d);
   1304   return result ? *result : NULL_TREE;
   1305 }
   1306 
   1307 /* Returns the postcondition funtion for D, or null if not set.  */
   1308 
   1309 tree
   1310 get_postcondition_function (tree d)
   1311 {
   1312   hash_map_maybe_create<hm_ggc> (decl_post_fn);
   1313   tree *result = decl_post_fn->get (d);
   1314   return result ? *result : NULL_TREE;
   1315 }
   1316 
   1317 /* Makes PRE the precondition function for D.  */
   1318 
   1319 void
   1320 set_precondition_function (tree d, tree pre)
   1321 {
   1322   gcc_assert (pre);
   1323   hash_map_maybe_create<hm_ggc> (decl_pre_fn);
   1324   gcc_assert (!decl_pre_fn->get (d));
   1325   decl_pre_fn->put (d, pre);
   1326 }
   1327 
   1328 /* Makes POST the postcondition function for D.  */
   1329 
   1330 void
   1331 set_postcondition_function (tree d, tree post)
   1332 {
   1333   gcc_assert (post);
   1334   hash_map_maybe_create<hm_ggc> (decl_post_fn);
   1335   gcc_assert (!decl_post_fn->get (d));
   1336   decl_post_fn->put (d, post);
   1337 }
   1338 
   1339 /* Set the PRE and POST functions for D.  Note that PRE and POST can be
   1340    null in this case. If so the functions are not recorded.  */
   1341 
   1342 void
   1343 set_contract_functions (tree d, tree pre, tree post)
   1344 {
   1345   if (pre)
   1346     set_precondition_function (d, pre);
   1347   if (post)
   1348     set_postcondition_function (d, post);
   1349 }
   1350 
   1351 /* Return a copy of the FUNCTION_DECL IDECL with its own unshared
   1352    PARM_DECL and DECL_ATTRIBUTEs.  */
   1353 
   1354 static tree
   1355 copy_fn_decl (tree idecl)
   1356 {
   1357   tree decl = copy_decl (idecl);
   1358   DECL_ATTRIBUTES (decl) = copy_list (DECL_ATTRIBUTES (idecl));
   1359 
   1360   if (DECL_RESULT (idecl))
   1361     {
   1362       DECL_RESULT (decl) = copy_decl (DECL_RESULT (idecl));
   1363       DECL_CONTEXT (DECL_RESULT (decl)) = decl;
   1364     }
   1365   if (!DECL_ARGUMENTS (idecl) || VOID_TYPE_P (DECL_ARGUMENTS (idecl)))
   1366     return decl;
   1367 
   1368   tree last = DECL_ARGUMENTS (decl) = copy_decl (DECL_ARGUMENTS (decl));
   1369   DECL_CONTEXT (last) = decl;
   1370   for (tree p = TREE_CHAIN (DECL_ARGUMENTS (idecl)); p; p = TREE_CHAIN (p))
   1371     {
   1372       if (VOID_TYPE_P (p))
   1373 	{
   1374 	  TREE_CHAIN (last) = void_list_node;
   1375 	  break;
   1376 	}
   1377       last = TREE_CHAIN (last) = copy_decl (p);
   1378       DECL_CONTEXT (last) = decl;
   1379     }
   1380   return decl;
   1381 }
   1382 
   1383 /* Build a declaration for the pre- or postcondition of a guarded FNDECL.  */
   1384 
   1385 static tree
   1386 build_contract_condition_function (tree fndecl, bool pre)
   1387 {
   1388   if (TREE_TYPE (fndecl) == error_mark_node)
   1389     return error_mark_node;
   1390   if (DECL_IOBJ_MEMBER_FUNCTION_P (fndecl)
   1391       && !TYPE_METHOD_BASETYPE (TREE_TYPE (fndecl)))
   1392     return error_mark_node;
   1393 
   1394   /* Create and rename the unchecked function and give an internal name.  */
   1395   tree fn = copy_fn_decl (fndecl);
   1396   DECL_RESULT (fn) = NULL_TREE;
   1397   tree value_type = pre ? void_type_node : TREE_TYPE (TREE_TYPE (fn));
   1398 
   1399   /* Don't propagate declaration attributes to the checking function,
   1400      including the original contracts.  */
   1401   DECL_ATTRIBUTES (fn) = NULL_TREE;
   1402 
   1403   tree arg_types = NULL_TREE;
   1404   tree *last = &arg_types;
   1405 
   1406   /* FIXME will later optimizations delete unused args to prevent extra arg
   1407      passing? do we care? */
   1408   tree class_type = NULL_TREE;
   1409   for (tree arg_type = TYPE_ARG_TYPES (TREE_TYPE (fn));
   1410       arg_type && arg_type != void_list_node;
   1411       arg_type = TREE_CHAIN (arg_type))
   1412     {
   1413       if (DECL_IOBJ_MEMBER_FUNCTION_P (fndecl)
   1414 	  && TYPE_ARG_TYPES (TREE_TYPE (fn)) == arg_type)
   1415       {
   1416 	class_type = TREE_TYPE (TREE_VALUE (arg_type));
   1417 	continue;
   1418       }
   1419       *last = build_tree_list (TREE_PURPOSE (arg_type), TREE_VALUE (arg_type));
   1420       last = &TREE_CHAIN (*last);
   1421     }
   1422 
   1423   if (pre || VOID_TYPE_P (value_type))
   1424     *last = void_list_node;
   1425   else
   1426     {
   1427       tree name = get_identifier ("__r");
   1428       tree parm = build_lang_decl (PARM_DECL, name, value_type);
   1429       DECL_CONTEXT (parm) = fn;
   1430       DECL_ARTIFICIAL (parm) = true;
   1431       DECL_ARGUMENTS (fn) = chainon (DECL_ARGUMENTS (fn), parm);
   1432 
   1433       *last = build_tree_list (NULL_TREE, value_type);
   1434       TREE_CHAIN (*last) = void_list_node;
   1435 
   1436       /* The handler is a void return.  */
   1437       value_type = void_type_node;
   1438     }
   1439 
   1440   TREE_TYPE (fn) = build_function_type (value_type, arg_types);
   1441   if (DECL_IOBJ_MEMBER_FUNCTION_P (fndecl))
   1442     TREE_TYPE (fn) = build_method_type (class_type, TREE_TYPE (fn));
   1443 
   1444   DECL_NAME (fn) = copy_node (DECL_NAME (fn));
   1445   DECL_INITIAL (fn) = error_mark_node;
   1446   DECL_ABSTRACT_ORIGIN (fn) = fndecl;
   1447 
   1448   IDENTIFIER_VIRTUAL_P (DECL_NAME (fn)) = false;
   1449   DECL_VIRTUAL_P (fn) = false;
   1450 
   1451   /* Make these functions internal if we can, i.e. if the guarded function is
   1452      not vague linkage, or if we can put them in a comdat group with the
   1453      guarded function.  */
   1454   if (!DECL_WEAK (fndecl) || HAVE_COMDAT_GROUP)
   1455     {
   1456       TREE_PUBLIC (fn) = false;
   1457       DECL_EXTERNAL (fn) = false;
   1458       DECL_WEAK (fn) = false;
   1459       DECL_COMDAT (fn) = false;
   1460 
   1461       /* We haven't set the comdat group on the guarded function yet, we'll add
   1462 	 this to the same group in comdat_linkage later.  */
   1463       gcc_assert (!DECL_ONE_ONLY (fndecl));
   1464 
   1465       DECL_INTERFACE_KNOWN (fn) = true;
   1466     }
   1467 
   1468   DECL_ARTIFICIAL (fn) = true;
   1469 
   1470   /* Update various inline related declaration properties.  */
   1471   //DECL_DECLARED_INLINE_P (fn) = true;
   1472   DECL_DISREGARD_INLINE_LIMITS (fn) = true;
   1473   TREE_NO_WARNING (fn) = 1;
   1474 
   1475   return fn;
   1476 }
   1477 
   1478 /* Return true if CONTRACT is checked or assumed under the current build
   1479    configuration. */
   1480 
   1481 bool
   1482 contract_active_p (tree contract)
   1483 {
   1484   return get_contract_semantic (contract) != CCS_IGNORE;
   1485 }
   1486 
   1487 static bool
   1488 has_active_contract_condition (tree d, tree_code c)
   1489 {
   1490   for (tree as = DECL_CONTRACTS (d) ; as != NULL_TREE; as = TREE_CHAIN (as))
   1491     {
   1492       tree contract = TREE_VALUE (TREE_VALUE (as));
   1493       if (TREE_CODE (contract) == c && contract_active_p (contract))
   1494 	return true;
   1495     }
   1496   return false;
   1497 }
   1498 
   1499 /* True if D has any checked or assumed preconditions.  */
   1500 
   1501 static bool
   1502 has_active_preconditions (tree d)
   1503 {
   1504   return has_active_contract_condition (d, PRECONDITION_STMT);
   1505 }
   1506 
   1507 /* True if D has any checked or assumed postconditions.  */
   1508 
   1509 static bool
   1510 has_active_postconditions (tree d)
   1511 {
   1512   return has_active_contract_condition (d, POSTCONDITION_STMT);
   1513 }
   1514 
   1515 /* Return true if any contract in the CONTRACT list is checked or assumed
   1516    under the current build configuration. */
   1517 
   1518 bool
   1519 contract_any_active_p (tree contract)
   1520 {
   1521   for (; contract != NULL_TREE; contract = CONTRACT_CHAIN (contract))
   1522     if (contract_active_p (TREE_VALUE (TREE_VALUE (contract))))
   1523       return true;
   1524   return false;
   1525 }
   1526 
   1527 /* Do we need to mess with contracts for DECL1?  */
   1528 
   1529 static bool
   1530 handle_contracts_p (tree decl1)
   1531 {
   1532   return (flag_contracts
   1533 	  && !processing_template_decl
   1534 	  && DECL_ABSTRACT_ORIGIN (decl1) == NULL_TREE
   1535 	  && contract_any_active_p (DECL_CONTRACTS (decl1)));
   1536 }
   1537 
   1538 /* Should we break out DECL1's pre/post contracts into separate functions?
   1539    FIXME I'd like this to default to 0, but that will need an overhaul to the
   1540    return identifier handling to just refer to the RESULT_DECL.  */
   1541 
   1542 static bool
   1543 outline_contracts_p (tree decl1)
   1544 {
   1545   return (!DECL_CONSTRUCTOR_P (decl1)
   1546 	  && !DECL_DESTRUCTOR_P (decl1));
   1547 }
   1548 
   1549 /* Build the precondition checking function for D.  */
   1550 
   1551 static tree
   1552 build_precondition_function (tree d)
   1553 {
   1554   if (!has_active_preconditions (d))
   1555     return NULL_TREE;
   1556 
   1557   return build_contract_condition_function (d, /*pre=*/true);
   1558 }
   1559 
   1560 /* Build the postcondition checking function for D. If the return
   1561    type is undeduced, don't build the function yet. We do that in
   1562    apply_deduced_return_type.  */
   1563 
   1564 static tree
   1565 build_postcondition_function (tree d)
   1566 {
   1567   if (!has_active_postconditions (d))
   1568     return NULL_TREE;
   1569 
   1570   tree type = TREE_TYPE (TREE_TYPE (d));
   1571   if (is_auto (type))
   1572     return NULL_TREE;
   1573 
   1574   return build_contract_condition_function (d, /*pre=*/false);
   1575 }
   1576 
   1577 static void
   1578 build_contract_function_decls (tree d)
   1579 {
   1580   /* Constructors and destructors have their contracts inserted inline.  */
   1581   if (!outline_contracts_p (d))
   1582     return;
   1583 
   1584   /* Build the pre/post functions (or not).  */
   1585   tree pre = build_precondition_function (d);
   1586   tree post = build_postcondition_function (d);
   1587   set_contract_functions (d, pre, post);
   1588 }
   1589 
   1590 static const char *
   1591 get_contract_level_name (tree contract)
   1592 {
   1593   if (CONTRACT_LITERAL_MODE_P (contract))
   1594     return "";
   1595   if (tree mode = CONTRACT_MODE (contract))
   1596     if (tree level = TREE_VALUE (mode))
   1597       return IDENTIFIER_POINTER (level);
   1598   return "default";
   1599 }
   1600 
   1601 static const char *
   1602 get_contract_role_name (tree contract)
   1603 {
   1604   if (CONTRACT_LITERAL_MODE_P (contract))
   1605     return "";
   1606   if (tree mode = CONTRACT_MODE (contract))
   1607     if (tree role = TREE_PURPOSE (mode))
   1608       return IDENTIFIER_POINTER (role);
   1609   return "default";
   1610 }
   1611 
   1612 /* Build a layout-compatible internal version of std::contract_violation.  */
   1613 
   1614 static tree
   1615 get_pseudo_contract_violation_type ()
   1616 {
   1617   if (!pseudo_contract_violation_type)
   1618     {
   1619       /* Must match <contract>:
   1620 	 class contract_violation {
   1621 	   const char* _M_file;
   1622 	   const char* _M_function;
   1623 	   const char* _M_comment;
   1624 	   const char* _M_level;
   1625 	   const char* _M_role;
   1626 	   uint_least32_t _M_line;
   1627 	   signed char _M_continue;
   1628 	 If this changes, also update the initializer in
   1629 	 build_contract_violation.  */
   1630       const tree types[] = { const_string_type_node,
   1631 			     const_string_type_node,
   1632 			     const_string_type_node,
   1633 			     const_string_type_node,
   1634 			     const_string_type_node,
   1635 			     uint_least32_type_node,
   1636 			     signed_char_type_node };
   1637       tree fields = NULL_TREE;
   1638       for (tree type : types)
   1639 	{
   1640 	  /* finish_builtin_struct wants fieldss chained in reverse.  */
   1641 	  tree next = build_decl (BUILTINS_LOCATION, FIELD_DECL,
   1642 				  NULL_TREE, type);
   1643 	  DECL_CHAIN (next) = fields;
   1644 	  fields = next;
   1645 	}
   1646       iloc_sentinel ils (input_location);
   1647       input_location = BUILTINS_LOCATION;
   1648       pseudo_contract_violation_type = make_class_type (RECORD_TYPE);
   1649       finish_builtin_struct (pseudo_contract_violation_type,
   1650 			     "__pseudo_contract_violation",
   1651 			     fields, NULL_TREE);
   1652       CLASSTYPE_AS_BASE (pseudo_contract_violation_type)
   1653 	= pseudo_contract_violation_type;
   1654       DECL_CONTEXT (TYPE_NAME (pseudo_contract_violation_type))
   1655 	= FROB_CONTEXT (global_namespace);
   1656       TREE_PUBLIC (TYPE_NAME (pseudo_contract_violation_type)) = true;
   1657       CLASSTYPE_LITERAL_P (pseudo_contract_violation_type) = true;
   1658       CLASSTYPE_LAZY_COPY_CTOR (pseudo_contract_violation_type) = true;
   1659       xref_basetypes (pseudo_contract_violation_type, /*bases=*/NULL_TREE);
   1660       pseudo_contract_violation_type
   1661 	= cp_build_qualified_type (pseudo_contract_violation_type,
   1662 				   TYPE_QUAL_CONST);
   1663     }
   1664   return pseudo_contract_violation_type;
   1665 }
   1666 
   1667 /* Return a VAR_DECL to pass to handle_contract_violation.  */
   1668 
   1669 static tree
   1670 build_contract_violation (tree contract, contract_continuation cmode)
   1671 {
   1672   expanded_location loc = expand_location (EXPR_LOCATION (contract));
   1673   const char *function = fndecl_name (DECL_ORIGIN (current_function_decl));
   1674   const char *level = get_contract_level_name (contract);
   1675   const char *role = get_contract_role_name (contract);
   1676 
   1677   /* Must match the type layout in get_pseudo_contract_violation_type.  */
   1678   tree ctor = build_constructor_va
   1679     (init_list_type_node, 7,
   1680      NULL_TREE, build_string_literal (loc.file),
   1681      NULL_TREE, build_string_literal (function),
   1682      NULL_TREE, CONTRACT_COMMENT (contract),
   1683      NULL_TREE, build_string_literal (level),
   1684      NULL_TREE, build_string_literal (role),
   1685      NULL_TREE, build_int_cst (uint_least32_type_node, loc.line),
   1686      NULL_TREE, build_int_cst (signed_char_type_node, cmode));
   1687 
   1688   ctor = finish_compound_literal (get_pseudo_contract_violation_type (),
   1689 				  ctor, tf_none);
   1690   protected_set_expr_location (ctor, EXPR_LOCATION (contract));
   1691   return ctor;
   1692 }
   1693 
   1694 /* Return handle_contract_violation(), declaring it if needed.  */
   1695 
   1696 static tree
   1697 declare_handle_contract_violation ()
   1698 {
   1699   tree fnname = get_identifier ("handle_contract_violation");
   1700   tree viol_name = get_identifier ("contract_violation");
   1701   tree l = lookup_qualified_name (global_namespace, fnname,
   1702 				  LOOK_want::HIDDEN_FRIEND);
   1703   for (tree f: lkp_range (l))
   1704     if (TREE_CODE (f) == FUNCTION_DECL)
   1705 	{
   1706 	  tree parms = TYPE_ARG_TYPES (TREE_TYPE (f));
   1707 	  if (remaining_arguments (parms) != 1)
   1708 	    continue;
   1709 	  tree parmtype = non_reference (TREE_VALUE (parms));
   1710 	  if (CLASS_TYPE_P (parmtype)
   1711 	      && TYPE_IDENTIFIER (parmtype) == viol_name)
   1712 	    return f;
   1713 	}
   1714 
   1715   tree id_exp = get_identifier ("experimental");
   1716   tree ns_exp = lookup_qualified_name (std_node, id_exp);
   1717 
   1718   tree violation = error_mark_node;
   1719   if (TREE_CODE (ns_exp) == NAMESPACE_DECL)
   1720     violation = lookup_qualified_name (ns_exp, viol_name,
   1721 				       LOOK_want::TYPE
   1722 				       |LOOK_want::HIDDEN_FRIEND);
   1723 
   1724   if (TREE_CODE (violation) == TYPE_DECL)
   1725     violation = TREE_TYPE (violation);
   1726   else
   1727     {
   1728       push_nested_namespace (std_node);
   1729       push_namespace (id_exp, /*inline*/false);
   1730       violation = make_class_type (RECORD_TYPE);
   1731       create_implicit_typedef (viol_name, violation);
   1732       DECL_SOURCE_LOCATION (TYPE_NAME (violation)) = BUILTINS_LOCATION;
   1733       DECL_CONTEXT (TYPE_NAME (violation)) = current_namespace;
   1734       pushdecl_namespace_level (TYPE_NAME (violation), /*hidden*/true);
   1735       pop_namespace ();
   1736       pop_nested_namespace (std_node);
   1737     }
   1738 
   1739   tree argtype = cp_build_qualified_type (violation, TYPE_QUAL_CONST);
   1740   argtype = cp_build_reference_type (argtype, /*rval*/false);
   1741   tree fntype = build_function_type_list (void_type_node, argtype, NULL_TREE);
   1742 
   1743   push_nested_namespace (global_namespace);
   1744   tree fn = build_cp_library_fn_ptr ("handle_contract_violation", fntype,
   1745 				     ECF_COLD);
   1746   pushdecl_namespace_level (fn, /*hiding*/true);
   1747   pop_nested_namespace (global_namespace);
   1748 
   1749   return fn;
   1750 }
   1751 
   1752 /* Build the call to handle_contract_violation for CONTRACT.  */
   1753 
   1754 static void
   1755 build_contract_handler_call (tree contract,
   1756 			     contract_continuation cmode)
   1757 {
   1758   tree violation = build_contract_violation (contract, cmode);
   1759   tree violation_fn = declare_handle_contract_violation ();
   1760   tree call = build_call_n (violation_fn, 1, build_address (violation));
   1761   finish_expr_stmt (call);
   1762 }
   1763 
   1764 /* Generate the code that checks or assumes a contract, but do not attach
   1765    it to the current context.  This is called during genericization.  */
   1766 
   1767 tree
   1768 build_contract_check (tree contract)
   1769 {
   1770   contract_semantic semantic = get_contract_semantic (contract);
   1771   if (semantic == CCS_INVALID)
   1772     return NULL_TREE;
   1773 
   1774   /* Ignored contracts are never checked or assumed.  */
   1775   if (semantic == CCS_IGNORE)
   1776     return void_node;
   1777 
   1778   remap_dummy_this (current_function_decl, &CONTRACT_CONDITION (contract));
   1779   tree condition = CONTRACT_CONDITION (contract);
   1780   if (condition == error_mark_node)
   1781     return NULL_TREE;
   1782 
   1783   location_t loc = EXPR_LOCATION (contract);
   1784 
   1785   if (semantic == CCS_ASSUME)
   1786     return build_assume_call (loc, condition);
   1787 
   1788   tree if_stmt = begin_if_stmt ();
   1789   tree cond = build_x_unary_op (loc,
   1790 				TRUTH_NOT_EXPR,
   1791 				condition, NULL_TREE,
   1792 				tf_warning_or_error);
   1793   finish_if_stmt_cond (cond, if_stmt);
   1794 
   1795   /* Get the continuation mode.  */
   1796   contract_continuation cmode;
   1797   switch (semantic)
   1798     {
   1799     case CCS_NEVER: cmode = NEVER_CONTINUE; break;
   1800     case CCS_MAYBE: cmode = MAYBE_CONTINUE; break;
   1801     default: gcc_unreachable ();
   1802     }
   1803 
   1804   build_contract_handler_call (contract, cmode);
   1805   if (cmode == NEVER_CONTINUE)
   1806     finish_expr_stmt (build_call_a (terminate_fn, 0, nullptr));
   1807 
   1808   finish_then_clause (if_stmt);
   1809   tree scope = IF_SCOPE (if_stmt);
   1810   IF_SCOPE (if_stmt) = NULL;
   1811   return do_poplevel (scope);
   1812 }
   1813 
   1814 /* Add the contract statement CONTRACT to the current block if valid.  */
   1815 
   1816 static void
   1817 emit_contract_statement (tree contract)
   1818 {
   1819   /* Only add valid contracts.  */
   1820   if (get_contract_semantic (contract) != CCS_INVALID
   1821       && CONTRACT_CONDITION (contract) != error_mark_node)
   1822     add_stmt (contract);
   1823 }
   1824 
   1825 /* Generate the statement for the given contract attribute by adding the
   1826    statement to the current block. Returns the next contract in the chain.  */
   1827 
   1828 static tree
   1829 emit_contract_attr (tree attr)
   1830 {
   1831   gcc_assert (TREE_CODE (attr) == TREE_LIST);
   1832 
   1833   emit_contract_statement (CONTRACT_STATEMENT (attr));
   1834 
   1835   return CONTRACT_CHAIN (attr);
   1836 }
   1837 
   1838 /* Add the statements of contract attributes ATTRS to the current block.  */
   1839 
   1840 static void
   1841 emit_contract_conditions (tree attrs, tree_code code)
   1842 {
   1843   if (!attrs) return;
   1844   gcc_assert (TREE_CODE (attrs) == TREE_LIST);
   1845   gcc_assert (code == PRECONDITION_STMT || code == POSTCONDITION_STMT);
   1846   while (attrs)
   1847     {
   1848       tree contract = CONTRACT_STATEMENT (attrs);
   1849       if (TREE_CODE (contract) == code)
   1850 	attrs = emit_contract_attr (attrs);
   1851       else
   1852 	attrs = CONTRACT_CHAIN (attrs);
   1853     }
   1854 }
   1855 
   1856 /* Emit the statement for an assertion attribute.  */
   1857 
   1858 void
   1859 emit_assertion (tree attr)
   1860 {
   1861   emit_contract_attr (attr);
   1862 }
   1863 
   1864 /* Emit statements for precondition attributes.  */
   1865 
   1866 static void
   1867 emit_preconditions (tree attr)
   1868 {
   1869   return emit_contract_conditions (attr, PRECONDITION_STMT);
   1870 }
   1871 
   1872 /* Emit statements for postcondition attributes.  */
   1873 
   1874 static void
   1875 emit_postconditions (tree attr)
   1876 {
   1877   return emit_contract_conditions (attr, POSTCONDITION_STMT);
   1878 }
   1879 
   1880 /* We're compiling the pre/postcondition function CONDFN; remap any FN
   1881    attributes that match CODE and emit them.  */
   1882 
   1883 static void
   1884 remap_and_emit_conditions (tree fn, tree condfn, tree_code code)
   1885 {
   1886   gcc_assert (code == PRECONDITION_STMT || code == POSTCONDITION_STMT);
   1887   for (tree attr = DECL_CONTRACTS (fn); attr;
   1888        attr = CONTRACT_CHAIN (attr))
   1889     {
   1890       tree contract = CONTRACT_STATEMENT (attr);
   1891       if (TREE_CODE (contract) == code)
   1892 	{
   1893 	  contract = copy_node (contract);
   1894 	  remap_contract (fn, condfn, contract, /*duplicate_p=*/false);
   1895 	  emit_contract_statement (contract);
   1896 	}
   1897     }
   1898 }
   1899 
   1900 /* Converts a contract condition to bool and ensures it has a locaiton.  */
   1901 
   1902 tree
   1903 finish_contract_condition (cp_expr condition)
   1904 {
   1905   /* Ensure we have the condition location saved in case we later need to
   1906      emit a conversion error during template instantiation and wouldn't
   1907      otherwise have it.  */
   1908   if (!CAN_HAVE_LOCATION_P (condition) || EXCEPTIONAL_CLASS_P (condition))
   1909     {
   1910       condition = build1_loc (condition.get_location (), VIEW_CONVERT_EXPR,
   1911 			      TREE_TYPE (condition), condition);
   1912       EXPR_LOCATION_WRAPPER_P (condition) = 1;
   1913     }
   1914 
   1915   if (condition == error_mark_node || type_dependent_expression_p (condition))
   1916     return condition;
   1917 
   1918   return condition_conversion (condition);
   1919 }
   1920 
   1921 void
   1922 maybe_update_postconditions (tree fco)
   1923 {
   1924   /* Update any postconditions and the postcondition checking function
   1925      as needed.  If there are postconditions, we'll use those to rewrite
   1926      return statements to check postconditions.  */
   1927   if (has_active_postconditions (fco))
   1928     {
   1929       rebuild_postconditions (fco);
   1930       tree post = build_postcondition_function (fco);
   1931       set_postcondition_function (fco, post);
   1932     }
   1933 }
   1934 
   1935 /* Called on attribute lists that must not contain contracts.  If any
   1936    contracts are present, issue an error diagnostic and return true.  */
   1937 
   1938 bool
   1939 diagnose_misapplied_contracts (tree attributes)
   1940 {
   1941   if (attributes == NULL_TREE)
   1942     return false;
   1943 
   1944   tree contract_attr = find_contract (attributes);
   1945   if (!contract_attr)
   1946     return false;
   1947 
   1948   error_at (EXPR_LOCATION (CONTRACT_STATEMENT (contract_attr)),
   1949 	    "contracts must appertain to a function type");
   1950 
   1951   /* Invalidate the contract so we don't treat it as valid later on.  */
   1952   invalidate_contract (TREE_VALUE (TREE_VALUE (contract_attr)));
   1953 
   1954   return true;
   1955 }
   1956 
   1957 /* Build and return an argument list containing all the parameters of the
   1958    (presumably guarded) FUNCTION_DECL FN.  This can be used to forward all of
   1959    FN's arguments to a function taking the same list of arguments -- namely
   1960    the unchecked form of FN.
   1961 
   1962    We use CALL_FROM_THUNK_P instead of forward_parm for forwarding
   1963    semantics.  */
   1964 
   1965 static vec<tree, va_gc> *
   1966 build_arg_list (tree fn)
   1967 {
   1968   vec<tree, va_gc> *args = make_tree_vector ();
   1969   for (tree t = DECL_ARGUMENTS (fn); t; t = DECL_CHAIN (t))
   1970     vec_safe_push (args, t);
   1971   return args;
   1972 }
   1973 
   1974 void
   1975 start_function_contracts (tree decl1)
   1976 {
   1977   if (!handle_contracts_p (decl1))
   1978     return;
   1979 
   1980   /* For cdtors, we evaluate the contracts check inline.  */
   1981   if (!outline_contracts_p (decl1))
   1982     return;
   1983 
   1984   /* Contracts may have just been added without a chance to parse them, though
   1985      we still need the PRE_FN available to generate a call to it.  */
   1986   if (!DECL_PRE_FN (decl1))
   1987     build_contract_function_decls (decl1);
   1988 
   1989 }
   1990 
   1991 /* If we have a precondition function and it's valid, call it.  */
   1992 
   1993 static void
   1994 add_pre_condition_fn_call (tree fndecl)
   1995 {
   1996   /* If we're starting a guarded function with valid contracts, we need to
   1997      insert a call to the pre function.  */
   1998   gcc_checking_assert (DECL_PRE_FN (fndecl)
   1999 		       && DECL_PRE_FN (fndecl) != error_mark_node);
   2000 
   2001   releasing_vec args = build_arg_list (fndecl);
   2002   tree call = build_call_a (DECL_PRE_FN (fndecl), args->length (),
   2003 			    args->address ());
   2004   CALL_FROM_THUNK_P (call) = true;
   2005   finish_expr_stmt (call);
   2006 }
   2007 
   2008 /* Build and add a call to the post-condition checking function, when that
   2009    is in use.  */
   2010 
   2011 static void
   2012 add_post_condition_fn_call (tree fndecl)
   2013 {
   2014   gcc_checking_assert (DECL_POST_FN (fndecl)
   2015 		       && DECL_POST_FN (fndecl) != error_mark_node);
   2016 
   2017   releasing_vec args = build_arg_list (fndecl);
   2018   if (get_postcondition_result_parameter (fndecl))
   2019     vec_safe_push (args, DECL_RESULT (fndecl));
   2020   tree call = build_call_a (DECL_POST_FN (fndecl), args->length (),
   2021 			    args->address ());
   2022   CALL_FROM_THUNK_P (call) = true;
   2023   finish_expr_stmt (call);
   2024 }
   2025 
   2026 /* Add a call or a direct evaluation of the pre checks.  */
   2027 
   2028 static void
   2029 apply_preconditions (tree fndecl)
   2030 {
   2031   if (outline_contracts_p (fndecl))
   2032     add_pre_condition_fn_call (fndecl);
   2033   else
   2034     emit_preconditions (DECL_CONTRACTS (fndecl));
   2035 }
   2036 
   2037 /* Add a call or a direct evaluation of the post checks.  */
   2038 
   2039 static void
   2040 apply_postconditions (tree fndecl)
   2041 {
   2042   if (outline_contracts_p (fndecl))
   2043     add_post_condition_fn_call (fndecl);
   2044   else
   2045     emit_postconditions (DECL_CONTRACTS (fndecl));
   2046 }
   2047 
   2048 /* Add contract handling to the function in FNDECL.
   2049 
   2050    When we have only pre-conditions, this simply prepends a call (or a direct
   2051    evaluation, for cdtors) to the existing function body.
   2052 
   2053    When we have post conditions we build a try-finally block.
   2054    If the function might throw then the handler in the try-finally is an
   2055    EH_ELSE expression, where the post condition check is applied to the
   2056    non-exceptional path, and an empty statement is added to the EH path.  If
   2057    the function has a non-throwing eh spec, then the handler is simply the
   2058    post-condition checker.  */
   2059 
   2060 void
   2061 maybe_apply_function_contracts (tree fndecl)
   2062 {
   2063   if (!handle_contracts_p (fndecl))
   2064     /* We did nothing and the original function body statement list will be
   2065        popped by our caller.  */
   2066     return;
   2067 
   2068   bool do_pre = has_active_preconditions (fndecl);
   2069   bool do_post = has_active_postconditions (fndecl);
   2070   /* We should not have reached here with nothing to do... */
   2071   gcc_checking_assert (do_pre || do_post);
   2072 
   2073   /* This copies the approach used for function try blocks.  */
   2074   tree fnbody = pop_stmt_list (DECL_SAVED_TREE (fndecl));
   2075   DECL_SAVED_TREE (fndecl) = push_stmt_list ();
   2076   tree compound_stmt = begin_compound_stmt (0);
   2077   current_binding_level->artificial = 1;
   2078 
   2079   /* Do not add locations for the synthesised code.  */
   2080   location_t loc = UNKNOWN_LOCATION;
   2081 
   2082   /* For other cases, we call a function to process the check.  */
   2083 
   2084   /* If we have a pre, but not a post, then just emit that and we are done.  */
   2085   if (!do_post)
   2086     {
   2087       apply_preconditions (fndecl);
   2088       add_stmt (fnbody);
   2089       finish_compound_stmt (compound_stmt);
   2090       return;
   2091     }
   2092 
   2093   if (do_pre)
   2094     /* Add a precondition call, if we have one. */
   2095     apply_preconditions (fndecl);
   2096   tree try_fin = build_stmt (loc, TRY_FINALLY_EXPR, fnbody, NULL_TREE);
   2097   add_stmt (try_fin);
   2098   TREE_OPERAND (try_fin, 1) = push_stmt_list ();
   2099   /* If we have exceptions, and a function that might throw, then add
   2100      an EH_ELSE clause that allows the exception to propagate upwards
   2101      without encountering the post-condition checks.  */
   2102   if (flag_exceptions && !type_noexcept_p (TREE_TYPE (fndecl)))
   2103     {
   2104       tree eh_else = build_stmt (loc, EH_ELSE_EXPR, NULL_TREE, NULL_TREE);
   2105       add_stmt (eh_else);
   2106       TREE_OPERAND (eh_else, 0) = push_stmt_list ();
   2107       apply_postconditions (fndecl);
   2108       TREE_OPERAND (eh_else, 0) = pop_stmt_list (TREE_OPERAND (eh_else, 0));
   2109       TREE_OPERAND (eh_else, 1) = build_empty_stmt (loc);
   2110     }
   2111   else
   2112     apply_postconditions (fndecl);
   2113   TREE_OPERAND (try_fin, 1) = pop_stmt_list (TREE_OPERAND (try_fin, 1));
   2114   finish_compound_stmt (compound_stmt);
   2115   /* The DECL_SAVED_TREE stmt list will be popped by our caller.  */
   2116 }
   2117 
   2118 /* Finish up the pre & post function definitions for a guarded FNDECL,
   2119    and compile those functions all the way to assembler language output.  */
   2120 
   2121 void
   2122 finish_function_contracts (tree fndecl)
   2123 {
   2124   if (!handle_contracts_p (fndecl)
   2125       || !outline_contracts_p (fndecl))
   2126     return;
   2127 
   2128   for (tree ca = DECL_CONTRACTS (fndecl); ca; ca = CONTRACT_CHAIN (ca))
   2129     {
   2130       tree contract = CONTRACT_STATEMENT (ca);
   2131       if (!CONTRACT_CONDITION (contract)
   2132 	  || CONTRACT_CONDITION_DEFERRED_P (contract)
   2133 	  || CONTRACT_CONDITION (contract) == error_mark_node)
   2134 	return;
   2135     }
   2136 
   2137   int flags = SF_DEFAULT | SF_PRE_PARSED;
   2138 
   2139   /* If either the pre or post functions are bad, don't bother emitting
   2140      any contracts.  The program is already ill-formed.  */
   2141   tree pre = DECL_PRE_FN (fndecl);
   2142   tree post = DECL_POST_FN (fndecl);
   2143   if (pre == error_mark_node || post == error_mark_node)
   2144     return;
   2145 
   2146   if (pre && DECL_INITIAL (fndecl) != error_mark_node)
   2147     {
   2148       DECL_PENDING_INLINE_P (pre) = false;
   2149       start_preparsed_function (pre, DECL_ATTRIBUTES (pre), flags);
   2150       remap_and_emit_conditions (fndecl, pre, PRECONDITION_STMT);
   2151       tree finished_pre = finish_function (false);
   2152       expand_or_defer_fn (finished_pre);
   2153     }
   2154 
   2155   if (post && DECL_INITIAL (fndecl) != error_mark_node)
   2156     {
   2157       DECL_PENDING_INLINE_P (post) = false;
   2158       start_preparsed_function (post,
   2159 				DECL_ATTRIBUTES (post),
   2160 				flags);
   2161       remap_and_emit_conditions (fndecl, post, POSTCONDITION_STMT);
   2162       if (!VOID_TYPE_P (TREE_TYPE (TREE_TYPE (post))))
   2163 	finish_return_stmt (get_postcondition_result_parameter (fndecl));
   2164 
   2165       tree finished_post = finish_function (false);
   2166       expand_or_defer_fn (finished_post);
   2167     }
   2168 }
   2169 
   2170 
   2171 /* A subroutine of duplicate_decls. Diagnose issues in the redeclaration of
   2172    guarded functions.  */
   2173 
   2174 void
   2175 duplicate_contracts (tree newdecl, tree olddecl)
   2176 {
   2177   if (TREE_CODE (newdecl) == TEMPLATE_DECL)
   2178     newdecl = DECL_TEMPLATE_RESULT (newdecl);
   2179   if (TREE_CODE (olddecl) == TEMPLATE_DECL)
   2180     olddecl = DECL_TEMPLATE_RESULT (olddecl);
   2181 
   2182   /* Compare contracts to see if they match.    */
   2183   tree old_contracts = DECL_CONTRACTS (olddecl);
   2184   tree new_contracts = DECL_CONTRACTS (newdecl);
   2185 
   2186   if (!old_contracts && !new_contracts)
   2187     return;
   2188 
   2189   location_t old_loc = DECL_SOURCE_LOCATION (olddecl);
   2190   location_t new_loc = DECL_SOURCE_LOCATION (newdecl);
   2191 
   2192   /* If both declarations specify contracts, ensure they match.
   2193 
   2194      TODO: This handles a potential error a little oddly. Consider:
   2195 
   2196 	struct B {
   2197 	  virtual void f(int n) [[pre: n == 0]];
   2198 	};
   2199 	struct D : B {
   2200 	  void f(int n) override; // inherits contracts
   2201 	};
   2202 	void D::f(int n) [[pre: n == 0]] // OK
   2203 	{ }
   2204 
   2205     It's okay because we're explicitly restating the inherited contract.
   2206     Changing the precondition on the definition D::f causes match_contracts
   2207     to complain about the mismatch.
   2208 
   2209     This would previously have been diagnosed as adding contracts to an
   2210     override, but this seems like it should be well-formed.  */
   2211   if (old_contracts && new_contracts)
   2212     {
   2213       if (!match_contract_conditions (old_loc, old_contracts,
   2214 				      new_loc, new_contracts,
   2215 				      cmc_declaration))
   2216 	return;
   2217       if (DECL_UNIQUE_FRIEND_P (newdecl))
   2218 	/* Newdecl's contracts are still DEFERRED_PARSE, and we're about to
   2219 	   collapse it into olddecl, so stash away olddecl's contracts for
   2220 	   later comparison.  */
   2221 	defer_guarded_contract_match (olddecl, olddecl, old_contracts);
   2222     }
   2223 
   2224   /* Handle cases where contracts are omitted in one or the other
   2225      declaration.  */
   2226   if (old_contracts)
   2227     {
   2228       /* Contracts have been previously specified by are no omitted. The
   2229 	 new declaration inherits the existing contracts. */
   2230       if (!new_contracts)
   2231 	copy_contract_attributes (newdecl, olddecl);
   2232 
   2233       /* In all cases, remove existing contracts from OLDDECL to prevent the
   2234 	 attribute merging function from adding excess contracts.  */
   2235       remove_contract_attributes (olddecl);
   2236     }
   2237   else if (!old_contracts)
   2238     {
   2239       /* We are adding contracts to a declaration.  */
   2240       if (new_contracts)
   2241 	{
   2242 	  /* We can't add to a previously defined function.  */
   2243 	  if (DECL_INITIAL (olddecl))
   2244 	    {
   2245 	      auto_diagnostic_group d;
   2246 	      error_at (new_loc, "cannot add contracts after definition");
   2247 	      inform (DECL_SOURCE_LOCATION (olddecl), "original definition here");
   2248 	      return;
   2249 	    }
   2250 
   2251 	  /* We can't add to an unguarded virtual function declaration.  */
   2252 	  if (DECL_VIRTUAL_P (olddecl) && new_contracts)
   2253 	    {
   2254 	      auto_diagnostic_group d;
   2255 	      error_at (new_loc, "cannot add contracts to a virtual function");
   2256 	      inform (DECL_SOURCE_LOCATION (olddecl), "original declaration here");
   2257 	      return;
   2258 	    }
   2259 
   2260 	  /* Depending on the "first declaration" rule, we may not be able
   2261 	     to add contracts to a function after the fact.  */
   2262 	  if (flag_contract_strict_declarations)
   2263 	    {
   2264 	      warning_at (new_loc,
   2265 			  OPT_fcontract_strict_declarations_,
   2266 			  "declaration adds contracts to %q#D",
   2267 			  olddecl);
   2268 	      return;
   2269 	    }
   2270 
   2271 	  /* Copy the contracts from NEWDECL to OLDDECL. We shouldn't need to
   2272 	     remap them because NEWDECL's parameters will replace those of
   2273 	     OLDDECL.  Remove the contracts from NEWDECL so they aren't
   2274 	     cloned when merging.  */
   2275 	  copy_contract_attributes (olddecl, newdecl);
   2276 	  remove_contract_attributes (newdecl);
   2277 	}
   2278     }
   2279 }
   2280 
   2281 /* Replace the any contract attributes on OVERRIDER with a copy where any
   2282    references to BASEFN's PARM_DECLs have been rewritten to the corresponding
   2283    PARM_DECL in OVERRIDER.  */
   2284 
   2285 void
   2286 inherit_base_contracts (tree overrider, tree basefn)
   2287 {
   2288   tree last = NULL_TREE, contract_attrs = NULL_TREE;
   2289   for (tree a = DECL_CONTRACTS (basefn);
   2290       a != NULL_TREE;
   2291       a = CONTRACT_CHAIN (a))
   2292     {
   2293       tree c = copy_node (a);
   2294       TREE_VALUE (c) = build_tree_list (TREE_PURPOSE (TREE_VALUE (c)),
   2295 					copy_node (CONTRACT_STATEMENT (c)));
   2296 
   2297       tree src = basefn;
   2298       tree dst = overrider;
   2299       remap_contract (src, dst, CONTRACT_STATEMENT (c), /*duplicate_p=*/true);
   2300 
   2301       CONTRACT_COMMENT (CONTRACT_STATEMENT (c)) =
   2302 	copy_node (CONTRACT_COMMENT (CONTRACT_STATEMENT (c)));
   2303 
   2304       chainon (last, c);
   2305       last = c;
   2306       if (!contract_attrs)
   2307 	contract_attrs = c;
   2308     }
   2309 
   2310   set_decl_contracts (overrider, contract_attrs);
   2311 }
   2312 
   2313 #include "gt-cp-contracts.h"
   2314