Jason Merrill <[email protected]> writes:

> I think this choice could use more explanation of its rationale.  IIUC
> this is e.g. to allow quals | TYPE_QUAL_CONST but not quals1 | quals2
> where quals2 happens to contain only TYPE_QUAL_CONST?

Yes.

Firstly, because quals2 cannot lack an address space qualifier (the
syntactic lack of an address space qualifier just means that the object
is qualified with the generic address space), so it never truly contains
only TYPE_QUAL_CONST if it is a qualifier_set.

Second, for address spaces in particular, it isn't always clear what the
correct way to take the union of them is.  If two address spaces are
different but overlapping, which one do we pick, if any?  If one is
generic and the other not, do we always want to pick the latter (as is
the case with qualifiers on type parameters, for instance, or when
qualifying declarations that use type aliases)?  What if they're fully
disjoint?  Usually, that's a cause to issue a diagnostic; with operator|
we can't pass something like COMPLAIN as an argument.

Third, if we permit that check to become a runtime check, then we do not
get a (GCC-build-time) diagnostic if we fail to reckon with the address
space component, and the goal is precisely to require address spaces to
be handled, to prevent bugs caused by forgetting to do so (such as the
examples I gave).

None of those concerns apply if we're dealing with at most one address
space and, ergo, at most one full qualifier_set, with the other
operands(s) being plain cv_qualifiers: there's at most one address space
involved so there's no question about which one to pick, it is clear
what the union of two plain sets (in this case of cv_qualifiers) is, and
the set union operation can never fail so there's never a diagnostic to
be had.

Note that languages that explicitly do not support address spaces can
fit in this arrangement fairly easily.  Like G++, they can provide their
own version of TYPE_QUALS (called cp_type_quals in G++), and make it
return cv_qualifier, and have it assert that there's no address space.

Then, none of their code would stumble upon a qualifier set set, ever,
and all the functions that would take a qualifier set can also accept a
cv_qualifier (either through an overload as in this version or, if we
switch qualifier_set to be a struct, through an implicit conversion
constructor).

Indeed, this is pretty much what I intend to do with the existing
frontends to convert them.

Similar to G++, this also gives them a "migration path" in the event
that they *do* want address space support at some point.  If they alter
their LANG_type_quals to return a qualifier_set, suddenly, every place
where they forget to deal with the address space becomes a compile-time
error.

> Maybe std::tie would be a useful substitute for structured bindings?

Yeah, that could work, but the verbosity may not pay off in the end.

The idea I had with that is to require that the user does something
like:

  auto [cv, as] = qual_set;

... when dealing with qualifier sets.  This forces the user to reckon
with there being CV-qualifiers and an address space in the qualifier
set, and it means that, if qualifier sets were to gain some third
component (that, similar to address spaces, can't be added as a
present/absent qualifier to 'cv'), each place that inspects the
components of a qualifier_set would break and require being updated,
whereas, if the user is just doing:

  auto cv = qual_set.cv;
  auto as = qual_set.av;

... adding a new component means that, silently, all the places which
need to deal with the qualifier sets component-by-component go out of
date.  And, of course, it is not an error for the user to consult just
one of the two members (whereas the user would explicitly need to throw
away the hypothetical third one with structured bindings).

The reason I reckon it's probably not worth it to use std::tie for this
is because, by my estimate, it is unlikely that we'll get a new
qualifier similar in fashion to address spaces.  It seems more likely
that, if there ever do come about any new qualifiers, they're similar to
CVR; either absent or present.
-- 
Arsen Arsenović

Attachment: signature.asc
Description: PGP signature

Reply via email to