C++ Logo

sg15

Advanced search

Re: [isocpp-sg15] [P2758] Emitting messages at compile time

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Wed, 16 Oct 2024 14:56:47 +0100
On Wed, 16 Oct 2024 at 14:42, Aaron Ballman <aaron_at_[hidden]> wrote:

> On Wed, Oct 16, 2024 at 6:10 AM Jonathan Wakely <cxx_at_[hidden]> wrote:
> >
> >
> >
> > On Tue, 15 Oct 2024 at 18:53, Aaron Ballman via SG15 <
> sg15_at_[hidden]> wrote:
> >>
> >> Thanks! FWIW, users do want this sort of capability, but the fact that
> >> no implementation has yet to add a feature with bells and whistles is
> >> because the problem is not easy to solve. I'm highly skeptical that
> >> this is something WG21 should be standardizing at all currently; it's
> >> firmly in the realm of QoI and different implementations have
> >> different needs (and our needs evolve over time). The only form of the
> >> feature I would consider supporting would be one that accepts the
> >> message to be printed during constant evaluation and nothing else.
> >> Anything with more bells and whistles will be problematic in practice.
> >>
> >> Practical implementability problems include:
> >> * Different implementations have different severities for diagnostics
> >> (error, warning, note, remark, no severity distinctions, etc)
> >
> >
> > We already have a distinction between #error and #warning, how is this
> any different?
> > constexpr_print just outputs a message at compile time (which you've
> said is fine).
>
> Because it adds another layer of distinction (constexpr_print_str)
> which may or may not make sense to any given implementation. In Clang
> specifically, is that a note or a remark? (There are problems with
> whichever one we pick, so it'd probably be an entirely new thing, but
> none of our users have actually asked for something like that, at
> least that I'm aware of.)
>
> > constexpr_warning outputs a diagnostic message with similar behaviour to
> #warning. If the implementation can't do non-fatal diagnostic messages,
> i.e. warnings as opposed to errors, then presumably that's already a
> problem for #warning. The behaviour for constexpr_warning can be consistent
> with that.
>
> This alone is fine for us, except it comes with a tag which is problematic.
>
> > constexpr_error outputs a diagnostic message with similar behaviour to
> #error, rendering the program ill-formed.
>
> This alone is (generally) fine for us.
>
> >> * Different implementations have different rules for additional
> >> effects on diagnostics (default ignore, default error, SFINAE trap,
> >> etc)
> >
> > I don't think I understand this point.
>
> When discussing adding a similar feature to Clang, the points always
> raised are 1) I want to pick the diagnostic name and grouping for
> this, 2) I have a special case that I know the compiler supports
> because there's a diagnostic I can point to which does the thing I
> want. Real-world use cases for this functionality will naturally want
> to have the same power as what the compiler already provides, but that
> isn't something that can be easily standardized due to the differences
> across implementations. We could perhaps figure out some
> implementation-defined "options" object that lets the implementation
> expose any extra options to the diagnostic they want.
>
> I realize the paper isn't proposing anything nearly this complicated,
> but my point is: if we start down the road of providing more than what
> `#error` or `#warning` can do in terms of "tags", there will be a
> natural pressure on the committee and implementers to go further. I'd
> rather see us skip the "tag" or design the feature so it can be
> extended by implementations however they see fit.
>
> >> * Different implementations have different ways to identify
> >> diagnostics (unique numeric identifier, warning group, no
> >> identification at all, etc)
> >>
> >> * Some implementations have the ability to group diagnostics together,
> >> other implementations don't
> >
> > Those with a unique identifier could give a single ID to all
> constexpr_warning diagnostics, and they would all be disabled or all
> enabled together. That would be conforming (the grouping and suppression
> are only recommended practice).
> > Those with no grouping could do something similar, with a
> -Wno-constexpr-warnings that affects them all. That would be conforming.
>
> Those with no grouping support should introduce grouping for one
> particular class of diagnostics?
>

OK, they don't support disabling constexpr_warning diagnostics at all then.
Sucks to be a user of that implementation, I guess.


>
> Based on past discussions in Clang about this, our users would most
> likely expect the tag to correspond to a warning group so they could
> do `-Wno-user-specified-tag` which is probably also under some
>

I was imagining it would be -Wfoo=tag-str not -Wfoo-tag-str (where "foo"
would be something like "user-specified" or "constexpr-print")


> umbrella to disable all user-specified diagnostics. However, we
> diagnose unknown diagnostic groups from the driver
> (https://godbolt.org/z/q4fb15e1q), so if there are now diagnostic
> groups that we won't know about until constant expression evaluation
> time we would struggle to support letting the user place diagnostics
> under a user-specified warning group (beyond the umbrella).
>

With what I imagined above, -Wuser-specified= would still be recognized,
and you could ignore any tag-str argument to it. There's no unknown warning
flag, just unrecognized arguments, but that's fine. The user says don't
want warnings for the "acme-debug-dumps" tag-str? Fine ... if you don't get
any such warnings during constant evaluation, they won't get them.


>
> > Implementations that want to give better user experiences could have
> options that use the tag-str to be more fine-grained. But it wouldn't be
> required for conformance.
> >
> > "Some implementations could not implement the Recommended practice" is
> fine, that's how normative encouragement is supposed to work.
>
> Sure, is that really what the committee wants to aim for though?
>

For implementations that absolutely *can't* do it, yes, that's why it's
only a recommendation not a requirement.

If none of the known implementations could follow the recommendation, that
would be a problem. But I'm not aware of anything in this proposal that GCC
couldn't implement here. I'd be surprised if Clang couldn't either. But it
sounds like it's not a case of being unable, it's not wanting to because it
opens unwanted cans of worms.



>
> Also keep in mind that there are more implementations than just
> compilers. Static analysis tools also have way different functionality
> in terms of how and what they present as diagnostics. (The point I'm
> getting at is: there's a reason the standard traditionally has not
> strayed into the realm of diagnostics any farther than #error and
> #warning -- those are pretty ubiquitous, anything beyond that such as
> suggested tags or groupings quickly runs afoul of all the various
> implementation differences. Those differences are what distinguish the
> implementations and are sometimes the primary driver of sales for the
> tool, hence can be *very important* to leave up to QoI.)
>
> >> * Some implementations localize their diagnostics, so trying to make
> >> user-defined diagnostics look like compiler diagnostics can cause
> >> consistency issues
> >
> > Isn't that already the case for static_assert messages? Would this be
> worse? Couldn't we cope?
>
> It is already the case, this is only incrementally worse.
>
> >> * Not all diagnostics are emitted to a terminal (there may be
> >> limitations on what can be emitted as a diagnostic depending on
> >> whether the diagnostics are being emitted to a terminal, to a list box
> >> UI, to a SARIF file, etc)
> >
> >
> > Isn't that also already the case for static_assert messages?
> >
> > If I do static_assert(false, "{ lol: { \"wat [ "); then the compiler
> already needs to be able to output that as SARIF without producing
> corrupted JSON.
>
> True!
>
> To be clear, what I'd prefer to see is: 1) drop the
> constexpr_print_str function as it doesn't cleanly map across
> implementations, 2) drop the tag from the interfaces. Alternatively
> for #2, instead of having a tag, have implementation-defined structs
> for use with constexpr_warning_str and constexpr_error_str that allow
> the implementation to specify whatever options they're comfortable
> supporting.
>
> ~Aaron
>
> >> These sorts of things are why I only support a very simple
> >> standardized interface, if anything. Trying to standardize something
> >> with more bells and whistles will run into problems where not every
> >> implementation can support it or will be willing to change their
> >> diagnostic practices to support it.
> >>
> >> ~Aaron
> >>
> >> On Mon, Oct 14, 2024 at 4:05 PM Barry Revzin via SG15
> >> <sg15_at_[hidden]> wrote:
> >> >
> >> > Hey Tooling Study Group,
> >> >
> >> > I have this paper, P2758 (latest currently:
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2758r3.html),
> which proposes low-level utilities for emitting messages during constant
> evaluation time.
> >> >
> >> > Those messages have three kinds (print, warning, and error) and can
> also be tagged. The intent of the tagging is to give the user the kind of
> control typically reserved for the compiler. That is, the format library
> can diagnose something with:
> >> >
> >> > std::constexpr_warning("format-too-many-args", "Format string
> consumed {} arguments but {} were provided.", current_arg, total);
> >> >
> >> > And that'll emit a compiler warning that maybe can be explicitly
> enabled (with some flag like -Wformat-too-many-args) or disabled (with some
> flag like -Wno-format-too-many-args). And possibly likewise with #pragmas
> for local blocks. Of course the actual mechanism is implementation-defined
> and it's likely the flags won't be exactly that so that they won't clash
> with actual implementation warnings.
> >> >
> >> > Evolution was happy with this proposal, but wanted you all to take a
> look at it for its use of tagging to make sure that this is a viable path.
> Right now, the paper's restriction on tagging is that it only contains,
> basically, a-z, A-Z, 0-9, an underscore, or a hyphen — although it
> presently also allows empty strings, which I'll change in a subsequent
> revision. That restriction avoids having to really deal with unicode stuff,
> while also matching the set of characters currently used in compiler flags
> anyway, so doesn't seem like it's cutting off anything useful to me.
> >> >
> >> > Thanks in advance for the feedback,
> >> >
> >> > Barry
> >> > _______________________________________________
> >> > SG15 mailing list
> >> > SG15_at_[hidden]
> >> > https://lists.isocpp.org/mailman/listinfo.cgi/sg15
> >> _______________________________________________
> >> SG15 mailing list
> >> SG15_at_[hidden]
> >> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
>

Received on 2024-10-16 13:58:06