You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It is permissible (but not necessary) for the mangling of f1 and g1 to be the same (other than the name).
(There are also requires-clauses on non-template functions, but I don't believe there is any need to mangle those since at most one such function can have its requires-clause evaluate to true, and the rest are never emitted.)
As a general model, I suggest we include "extra information" about a template-parameter (for a function template -- we don't need this for non-overloadable templates) as a prefix on the template-arg mangling. (We should also consider extending this to the case where the the template parameter is a template template parameter and the template argument does not have an identical template-parameter-list, to handle the case described in http://sourcerytools.com/pipermail/cxx-abi-dev/2014-December/002791.html)
I suggest we affix the constraint expression from the requires-clause (if any) to the template-args, and do not perform any expansion or canonicalization of the as-written form of the template declaration. Strawman mangling suggestion:
<template-arg> ::= C <concept name> <template-arg>
<template-args> ::= I <template-arg>+ Q <requires-clause expr> E
Is your statement about non-template functions true in the case that not all such functions are declared in the same translation unit? Or is that impossible because such functions must be defined within templates?
On Jul 25, 2017, at 11:21 PM, John McCall ***@***.***> wrote:
Does the standard consider these to be different declarations for the purposes of the ODR?
template void foo();
template requires A void foo();
On Jul 26, 2017, at 12:01 AM, Thiago Macieira ***@***.***> wrote:
Similarly, does it consider these two to be two different functions, even if both concepts are exactly the same (same requirements, literally)?
template concept A = ...
template concept B = ...
template void f(T); // f1
template void f(T); // f2
I’m guessing that f1 and f2 meant to be constrained with A and B respectively, and that those two concepts were meant to be defined identically?
If that is the case, trying to call f with any argument that matches the concepts is an ambiguous overload, correct?
But if I split the two in two different translation units, could I call two different functions and not violate ODR?
That’s my understanding of the proposal as adopted into the working draft (which incorporates P0717, which is a change in that regard compared to the Concepts TS).
Daveed
Specifically, aside from the change of A to B, the rest is exactly the same, literally so for the concept declaration. In other words: what defines a concept: the name or the requirements?
And as a corollary, in c.cpp:
template<typename T> concept A = { something very different here; };
template<A T> voidf(T) {}
If concepts are identified by name, then the above is must be ODR violation (no diagnostic required). Is this understanding correct?
On Jul 26, 2017, at 11:15 AM, Thiago Macieira ***@***.***> wrote:
Please note that your reply removed everything between the angle brackets,
Ah, the angle brackets did not show up on my end. Probably some markup gobbling along the way...
so you removed important information. But to be clear, I'm asking:
a.cpp:
template<typename T> concept A = { something here; };
template<A T> void f(T) {}
b.cpp:
template<typename T> concept B = { something here; };
template<B T> void f(T) {}
Specifically, aside from the change of A to B, the rest is exactly the same, literally so for the concept declaration. In other words: what defines a concept: the name or the requirements?
What defines the concept is the concept definition (including the name and its initializer).
I _think_ you meant to ask how equivalence of constraints on function templates is specified: In terms of concept names or the underlying expressions? The answer to that question is that it’s not quite either of those two (and “equivalence” is defined differently depending on context). See:
http://wg21.link/p0717
for details. For your example, that means that the two declarations of f declare distinct templates.
And as a corollary, in c.cpp:
template<typename T> concept A = { something very different here; };
template<A T> void f(T) {}
If concepts are identified by name, then the above is must be ODR violation (no diagnostic required). Is this understanding correct?
I believe concepts have linkage, and therefore, yes, that would be an ODR violation (even without the declaration of f).
Daveed
It looks like concepts with the same name are required to be defined the same way in different translation units. I don't know if there's a way of giving a concept "linkage" per se.
It looks like Daveed's statement is correct: two template-heads (template parameter list + requires clause) are equivalent only if they are written in exactly the same way, but they are functionally equivalent if they accept the same set of template arguments. So we are allowed but not required to treat those as distinct templates. (Exactly like Richard said.)
I feel like people would probably be surprised by trivial differences breaking ABI, but on the other that's already true of function templates, and it mostly doesn't matter because:
depending on function pointer equality is extremely rare (and foolish) and
depending on the address/uniqueness of a static variable within a function template is rare, albeit less so (and most justifiable) than depending on function pointer equality.
So Richard's idea of not doing any canonicalization is appealing. But if anything about concepts requires us to mangle template-heads for something besides identifying a function template, we'll be in more trouble.
(There are also requires-clauses on non-template functions, but I don't believe there is any need to mangle those since at most one such function can have its requires-clause evaluate to true, and the rest are never emitted.)
For tool vendors such as Synopsys/Coverity, having different mangled names for each distinct declaration is useful, even if only one of them can ever be "activated" within a TU. However, this is a niche requirement and we can resort to vendor extensions (as we have in other cases such as "conflicting" inline friend function definitions in different class templates) if including mangling would be at all problematic for other implementors.
Or is that impossible because such functions must be defined within templates?
There is no such requirement... yet.
If nothing else, I'd say the underspecification in this area and the likelihood of changes suggests that we shouldn't commit to a mangling for this construct yet.
Activity
rjmccall commentedon Jul 26, 2017
Is your statement about non-template functions true in the case that not all such functions are declared in the same translation unit? Or is that impossible because such functions must be defined within templates?
rjmccall commentedon Jul 26, 2017
Does the standard consider these to be different declarations for the purposes of the ODR?
Oh, I see you answered that: it's unspecified.
I feel like it would be responsible for us to do some minimal canonicalization here.
thiagomacieira commentedon Jul 26, 2017
Similarly, does it consider these two to be two different functions, even if both concepts are exactly the same (same requirements, literally)?
If that is the case, trying to call f with any argument that matches the concepts is an ambiguous overload, correct?
But if I split the two in two different translation units, could I call two different functions and not violate ODR?
And what happens if two different TUs have differing concepts that have the same name? ODR violation?
daveedvdv commentedon Jul 26, 2017
daveedvdv commentedon Jul 26, 2017
thiagomacieira commentedon Jul 26, 2017
Please note that your reply removed everything between the angle brackets, so you removed important information. But to be clear, I'm asking:
a.cpp:
b.cpp:
Specifically, aside from the change of A to B, the rest is exactly the same, literally so for the concept declaration. In other words: what defines a concept: the name or the requirements?
And as a corollary, in c.cpp:
If concepts are identified by name, then the above is must be ODR violation (no diagnostic required). Is this understanding correct?
daveedvdv commentedon Jul 26, 2017
thiagomacieira commentedon Jul 26, 2017
If they have linkage, we need to mangle that too.
Why do they have to have linkage?
rjmccall commentedon Jul 26, 2017
It looks like concepts with the same name are required to be defined the same way in different translation units. I don't know if there's a way of giving a concept "linkage" per se.
thiagomacieira commentedon Jul 26, 2017
Something like IFNDR then.
rjmccall commentedon Jul 26, 2017
It looks like Daveed's statement is correct: two template-heads (template parameter list + requires clause) are equivalent only if they are written in exactly the same way, but they are functionally equivalent if they accept the same set of template arguments. So we are allowed but not required to treat those as distinct templates. (Exactly like Richard said.)
rjmccall commentedon Jul 26, 2017
I feel like people would probably be surprised by trivial differences breaking ABI, but on the other that's already true of function templates, and it mostly doesn't matter because:
So Richard's idea of not doing any canonicalization is appealing. But if anything about concepts requires us to mangle template-heads for something besides identifying a function template, we'll be in more trouble.
tahonermann commentedon Jul 26, 2017
For tool vendors such as Synopsys/Coverity, having different mangled names for each distinct declaration is useful, even if only one of them can ever be "activated" within a TU. However, this is a niche requirement and we can resort to vendor extensions (as we have in other cases such as "conflicting" inline friend function definitions in different class templates) if including mangling would be at all problematic for other implementors.
zygoloid commentedon Jul 26, 2017
The wording in this area is unclear, and we have an open issue on it. Example:
It's not clear whether this program is valid, or (if valid) what it means. And the same situation can arise even within a TU:
There is no such requirement... yet.
If nothing else, I'd say the underspecification in this area and the likelihood of changes suggests that we shouldn't commit to a mangling for this construct yet.
rjmccall commentedon Jul 27, 2017
Interesting, alright.
18 remaining items
c++: mangle function template constraints
c++: mangle function template constraints
Synchronize sourceware version of the libiberty sources with the mast…
c++: mangle function template constraints
c++: mangle function template constraints
c++: mangle function template constraints
[clang][ItaniumMangle] Mangle friend function templates with a constr…
[clang][ItaniumMangle] Mangle friend function templates with a constr… (
[clang][ItaniumMangle] Mangle friend function templates with a constr…
[clang][ItaniumMangle] Mangle friend function templates with a constr…
Implement mangling rules for C++20 concepts and requires-expressions.
[clang][ItaniumMangle] Mangle friend function templates with a constr…
Implement mangling rules for C++20 concepts and requires-expressions.
[clang][ItaniumMangle] Mangle friend function templates with a constr… (