On Thu, 22 Feb 2024, Jakub Jelinek wrote:

> Hi!
> 
> We aren't able to parse __has_attribute (vendor::attr) (and __has_c_attribute
> and __has_cpp_attribute) in strict C < C23 modes.  While in -std=gnu* modes
> or in -std=c23 there is CPP_SCOPE token, in -std=c* (except for -std=c23)
> there are is just a pair of CPP_COLON tokens.
> The c-lex.cc hunk adds support for that.
> 
> That leads to a question if we should return 1 or 0 from
> __has_attribute (gnu::unused) or not, because while
> [[gnu::unused]] is parsed fine in -std=gnu*/-std=c23 modes (sure, with
> pedwarn for < C23), we do not parse it at all in -std=c* (except for
> -std=c23), we only parse [[__extension__ gnu::unused]] there.  While
> the __extension__ in there helps to avoid the pedwarn, I think it is
> better to be consistent between GNU and strict C < C23 modes and
> parse [[gnu::unused]] too; on the other side, I think parsing
> [[__extension__ gnu : : unused]] is too weird and undesirable.
> 
> So, the following patch adds a flag during preprocessing at the point
> where we normally create CPP_SCOPE tokens out of 2 consecutive colons
> on the first CPP_COLON to mark the consecutive case (as we are tight
> on the bits, I've reused the PURE_ZERO flag, which is used just by the
> C++ FE and only ever set (both C and C++) on CPP_NUMBER tokens, this
> new flag has the same value and is only ever used on CPP_COLON tokens)
> and instead of checking loose_scope_p argument (i.e. whether it is
> [[__extension__ ...]] or not), it just parses CPP_SCOPE or CPP_COLON
> with CLONE_SCOPE flag followed by another CPP_COLON the same.
> The latter will never appear in >= C23 or -std=gnu* modes, though
> guarding its use say with flag_iso && !flag_isoc23 && doesn't really
> work because the __extension__ case temporarily clears flag_iso flag.

This patch (the one using COLON_SCOPE, *not* the one using PREV_WHITE) is 
OK.

PREV_WHITE is about whether there is whitespace between the tokens in the 
macro expansion, for the purposes of stringization - I don't think it's 
appropriate to use here.  For example, given

  #define COLON() :

then

  [[gnu COLON()COLON() unused]] int x;

should preferably not be valid; stringizing the results of expanding 
COLON()COLON() will produce "::" (PREV_WHITE not set), but that wouldn't 
be a valid attribute in C23 and I don't think anyone could reasonably 
expect it to be valid with previous standard versions.

-- 
Joseph S. Myers
josmy...@redhat.com

Reply via email to