Skip to content

Commit c3f281a

Browse files
committed
c++: mangle function template constraints
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.
1 parent c6bb413 commit c3f281a

File tree

15 files changed

+551
-72
lines changed

15 files changed

+551
-72
lines changed

gcc/cp/constraint.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,9 @@ combine_constraint_expressions (tree lhs, tree rhs)
240240
return rhs;
241241
if (!rhs)
242242
return lhs;
243-
return finish_constraint_and_expr (input_location, lhs, rhs);
243+
/* Use UNKNOWN_LOCATION so write_template_args can tell the difference
244+
between this and a && the user wrote. */
245+
return finish_constraint_and_expr (UNKNOWN_LOCATION, lhs, rhs);
244246
}
245247

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

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

16131617
return check;

gcc/cp/cp-tree.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3799,6 +3799,12 @@ struct GTY(()) lang_decl {
37993799
: TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE))
38003800
#endif
38013801

3802+
/* True iff NODE represents the template args for a type-constraint,
3803+
in which case the first one represents the constrained type.
3804+
Currently only set during mangling. */
3805+
#define TEMPLATE_ARGS_TYPE_CONSTRAINT_P(NODE) \
3806+
TREE_PRIVATE (TREE_VEC_CHECK (NODE))
3807+
38023808
/* The list of access checks that were deferred during parsing
38033809
which need to be performed at template instantiation time.
38043810
@@ -8509,6 +8515,7 @@ struct processing_constraint_expression_sentinel
85098515
extern bool processing_constraint_expression_p ();
85108516

85118517
extern tree unpack_concept_check (tree);
8518+
extern tree get_concept_check_template (tree);
85128519
extern tree evaluate_concept_check (tree);
85138520
extern bool constraints_satisfied_p (tree, tree = NULL_TREE);
85148521
extern bool* lookup_subsumption_result (tree, tree);

0 commit comments

Comments
 (0)