Skip to content

Commit

Permalink
c++: mangle function template constraints
Browse files Browse the repository at this point in the history
Per itanium-cxx-abi/cxx-abi#24 and
itanium-cxx-abi/cxx-abi#166

We need to mangle constraints to be able to distinguish between function
templates that only differ in constraints.  From the latter link, we want to
use the template parameter mangling previously specified for lambdas to also
make explicit the form of a template parameter where the argument is not a
"natural" fit for it, such as when the parameter is constrained or deduced.

I'm concerned about how the latter link changes the mangling for some C++98
and C++11 patterns, so I've limited template_parm_natural_p to avoid two
cases found by running the testsuite with -Wabi forced on:

template <class T, T V> T f() { return V; }
int main() { return f<int,42>(); }

template <int i> int max() { return i; }
template <int i, int j, int... rest> int max()
{
  int sub = max<j, rest...>();
  return i > sub ? i : sub;
}
int main() {  return max<1,2,3>(); }

A third C++11 pattern is changed by this patch:

template <template <typename...> class TT, typename... Ts> TT<Ts...> f();
template <typename> struct A { };
int main() { f<A,int>(); }

I aim to resolve these with the ABI committee before GCC 14.1.

We also need to resolve itanium-cxx-abi/cxx-abi#38
(mangling references to dependent template-ids where the name is fully
resolved) as references to concepts in std:: will consistently run into this
area.  This is why mangle-concepts1.C only refers to concepts in the global
namespace so far.

The library changes are to avoid trying to mangle builtins, which fails.

Demangler support and test coverage is not complete yet.

gcc/cp/ChangeLog:

	* cp-tree.h (TEMPLATE_ARGS_TYPE_CONSTRAINT_P): New.
	(get_concept_check_template): Declare.
	* constraint.cc (combine_constraint_expressions)
	(finish_shorthand_constraint): Use UNKNOWN_LOCATION.
	* pt.cc (convert_generic_types_to_packs): Likewise.
	* mangle.cc (write_constraint_expression)
	(write_tparms_constraints, write_type_constraint)
	(template_parm_natural_p, write_requirement)
	(write_requires_expr): New.
	(write_encoding): Mangle trailing requires-clause.
	(write_name): Pass parms to write_template_args.
	(write_template_param_decl): Factor out from...
	(write_closure_template_head): ...here.
	(write_template_args): Mangle non-natural parms
	and requires-clause.
	(write_expression): Handle REQUIRES_EXPR.

include/ChangeLog:

	* demangle.h (enum demangle_component_type): Add
	DEMANGLE_COMPONENT_CONSTRAINTS.

libiberty/ChangeLog:

	* cp-demangle.c (d_make_comp): Handle
	DEMANGLE_COMPONENT_CONSTRAINTS.
	(d_count_templates_scopes): Likewise.
	(d_print_comp_inner): Likewise.
	(d_maybe_constraints): New.
	(d_encoding, d_template_args_1): Call it.
	(d_parmlist): Handle 'Q'.
	* testsuite/demangle-expected: Add some constraint tests.

libstdc++-v3/ChangeLog:

	* include/std/bit: Avoid builtins in requires-clauses.
	* include/std/variant: Likewise.

gcc/testsuite/ChangeLog:

	* g++.dg/abi/mangle10.C: Disable compat aliases.
	* g++.dg/abi/mangle52.C: Specify ABI 18.
	* g++.dg/cpp2a/class-deduction-alias3.C
	* g++.dg/cpp2a/class-deduction-alias8.C:
	Avoid builtins in requires-clauses.
	* g++.dg/abi/mangle-concepts1.C: New test.
	* g++.dg/abi/mangle-ttp1.C: New test.
  • Loading branch information
jicama authored and Blackhex committed Dec 18, 2023
1 parent 0492ad4 commit 3e18be4
Show file tree
Hide file tree
Showing 15 changed files with 551 additions and 72 deletions.
10 changes: 7 additions & 3 deletions gcc/cp/constraint.cc
Expand Up @@ -240,7 +240,9 @@ combine_constraint_expressions (tree lhs, tree rhs)
return rhs;
if (!rhs)
return lhs;
return finish_constraint_and_expr (input_location, lhs, rhs);
/* Use UNKNOWN_LOCATION so write_template_args can tell the difference
between this and a && the user wrote. */
return finish_constraint_and_expr (UNKNOWN_LOCATION, lhs, rhs);
}

/* Extract the template-id from a concept check. For standard and variable
Expand Down Expand Up @@ -1605,9 +1607,11 @@ finish_shorthand_constraint (tree decl, tree constr)
check = ovl_make (tmpl);
check = build_concept_check (check, arg, args, tf_warning_or_error);

/* Make the check a fold-expression if needed. */
/* Make the check a fold-expression if needed.
Use UNKNOWN_LOCATION so write_template_args can tell the
difference between this and a fold the user wrote. */
if (apply_to_each_p && declared_pack_p)
check = finish_left_unary_fold_expr (DECL_SOURCE_LOCATION (decl),
check = finish_left_unary_fold_expr (UNKNOWN_LOCATION,
check, TRUTH_ANDIF_EXPR);

return check;
Expand Down
7 changes: 7 additions & 0 deletions gcc/cp/cp-tree.h
Expand Up @@ -3799,6 +3799,12 @@ struct GTY(()) lang_decl {
: TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE))
#endif

/* True iff NODE represents the template args for a type-constraint,
in which case the first one represents the constrained type.
Currently only set during mangling. */
#define TEMPLATE_ARGS_TYPE_CONSTRAINT_P(NODE) \
TREE_PRIVATE (TREE_VEC_CHECK (NODE))

/* The list of access checks that were deferred during parsing
which need to be performed at template instantiation time.
Expand Down Expand Up @@ -8509,6 +8515,7 @@ struct processing_constraint_expression_sentinel
extern bool processing_constraint_expression_p ();

extern tree unpack_concept_check (tree);
extern tree get_concept_check_template (tree);
extern tree evaluate_concept_check (tree);
extern bool constraints_satisfied_p (tree, tree = NULL_TREE);
extern bool* lookup_subsumption_result (tree, tree);
Expand Down

0 comments on commit 3e18be4

Please sign in to comment.