https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87709

--- Comment #4 from Baruch Burstein <bmburstein at gmail dot com> ---
There is a pretty good (speculative) analysis of this issue here:
https://stackoverflow.com/a/52986284/331785
I am copying it to here for completeness, but credit for this goes to the
author of that post:

There are two kinds of expressions that look similar but have vastly different
meaning:

(type) + expr
(expr) + expr

The first is a C-style cast expression, that converts the unary expression +
expr to type, the second is a binary expression that performs addition.

To disambiguate an expression of form (something) + expr, GCC first assumes
that something is a type and does a tentative parse. If that succeeds, then the
whole expression is treated as a cast expression, otherwise, something is
reparsed as an expression.

Now here's where I think the bug resides: during the tentative parse, GCC
wrongly believes that class template argument deduction (CTAD) cannot appear,
so it issues an error when it appears. But in fact, even though the tentative
parse will definitely fail in this case, something may still be a valid
function-style cast expression, and thus the reparse might be successful.

For cat((lit('b')), lit('d')), lit('b') + lit('d'), and (lit('b')), GCC is
clever enough to see that they can't be C-style cast expression, so it does not
do the tentative parse. For (lit<char>('b')) + lit('d'), there's no CTAD in
lit<char>('b'), so it is fine as well.

Prove of the above analysis:

If + is changed to / (or most operators other than -, * or &), no error occurs,
because (something) / expr can't be a valid cast expression.

Similar ambiguity exists in sizeof(something) (could be sizeof(type) or
sizeof(expr)), and as expected, sizeof(lit(0)) triggers a similar error.

Reply via email to