Remove ^^ as a token in OpenCL (#108224)
OpenCL has a reserved operator (^^), the use of which was diagnosed as
an error (735c6cdebd). However, OpenCL
also encourages working with the blocks language extension. This token
has a parsing ambiguity as a result. Consider:
unsigned x=0;
unsigned y=x^^{return 0;}();
This should result in y holding the value zero (0^0) through an
immediately invoked block call as the right-hand side of the xor
operator. However, it causes errors instead because of this reserved
token: https://godbolt.org/z/navf7jTv1
This token is still reserved in OpenCL 3.0, so we still wish to issue a
diagnostic for its use. However, we do not need to create a token for an
extension point that's been unused for about a decade. So this patch
moves the diagnostic from a parsing diagnostic to a lexing diagnostic
and no longer forms a single token. The diagnostic behavior is slightly
worse as a result, but still seems acceptable.
Part of the reason this is coming up is because WG21 is considering
using ^^ as a token for reflection, so this token may come back in the
future.
This commit is contained in:
@@ -84,7 +84,8 @@ struct AvoidUnconditionalPreprocessorIfPPCallbacks : public PPCallbacks {
|
||||
return (Tok.getRawIdentifier() == "true" ||
|
||||
Tok.getRawIdentifier() == "false");
|
||||
default:
|
||||
return Tok.getKind() >= tok::l_square && Tok.getKind() <= tok::caretcaret;
|
||||
return Tok.getKind() >= tok::l_square &&
|
||||
Tok.getKind() <= tok::greatergreatergreater;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -639,7 +639,6 @@ operator-name := >
|
||||
operator-name := <=
|
||||
operator-name := >=
|
||||
operator-name := <=>
|
||||
operator-name := ^^
|
||||
operator-name := ||
|
||||
operator-name := <<
|
||||
operator-name := greatergreater
|
||||
|
||||
@@ -508,6 +508,8 @@ def note_macro_expansion_here : Note<"expansion of macro %0 requested here">;
|
||||
|
||||
def ext_pp_opencl_variadic_macros : Extension<
|
||||
"variadic macros are a Clang extension in OpenCL">;
|
||||
def err_opencl_logical_exclusive_or : Error<
|
||||
"^^ is a reserved operator in OpenCL">;
|
||||
|
||||
def ext_pp_gnu_line_directive : Extension<
|
||||
"this style of line directive is a GNU extension">,
|
||||
|
||||
@@ -1397,8 +1397,6 @@ def err_modifier_expected_colon : Error<"missing ':' after %0 modifier">;
|
||||
// OpenCL errors.
|
||||
def err_opencl_taking_function_address_parser : Error<
|
||||
"taking address of function is not allowed">;
|
||||
def err_opencl_logical_exclusive_or : Error<
|
||||
"^^ is a reserved operator in OpenCL">;
|
||||
|
||||
// C++ for OpenCL.
|
||||
def err_openclcxx_virtual_function : Error<
|
||||
|
||||
@@ -255,9 +255,6 @@ PUNCTUATOR(at, "@")
|
||||
PUNCTUATOR(lesslessless, "<<<")
|
||||
PUNCTUATOR(greatergreatergreater, ">>>")
|
||||
|
||||
// CL support
|
||||
PUNCTUATOR(caretcaret, "^^")
|
||||
|
||||
// C99 6.4.1: Keywords. These turn into kw_* tokens.
|
||||
// Flags allowed:
|
||||
// KEYALL - This is a keyword in all variants of C and C++, or it
|
||||
|
||||
@@ -52,7 +52,6 @@ prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator,
|
||||
case tok::pipeequal: return prec::Assignment;
|
||||
case tok::question: return prec::Conditional;
|
||||
case tok::pipepipe: return prec::LogicalOr;
|
||||
case tok::caretcaret:
|
||||
case tok::ampamp: return prec::LogicalAnd;
|
||||
case tok::pipe: return prec::InclusiveOr;
|
||||
case tok::caret: return prec::ExclusiveOr;
|
||||
|
||||
@@ -4325,10 +4325,9 @@ LexStart:
|
||||
if (Char == '=') {
|
||||
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
|
||||
Kind = tok::caretequal;
|
||||
} else if (LangOpts.OpenCL && Char == '^') {
|
||||
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
|
||||
Kind = tok::caretcaret;
|
||||
} else {
|
||||
if (LangOpts.OpenCL && Char == '^')
|
||||
Diag(CurPtr, diag::err_opencl_logical_exclusive_or);
|
||||
Kind = tok::caret;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -446,10 +446,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
|
||||
Token OpToken = Tok;
|
||||
ConsumeToken();
|
||||
|
||||
if (OpToken.is(tok::caretcaret)) {
|
||||
return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or));
|
||||
}
|
||||
|
||||
// If we're potentially in a template-id, we may now be able to determine
|
||||
// whether we're actually in one or not.
|
||||
if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater,
|
||||
|
||||
@@ -520,7 +520,6 @@ static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS,
|
||||
// Logical operators, assume we want bool.
|
||||
case tok::ampamp:
|
||||
case tok::pipepipe:
|
||||
case tok::caretcaret:
|
||||
return S.getASTContext().BoolTy;
|
||||
// Operators often used for bit manipulation are typically used with the type
|
||||
// of the left argument.
|
||||
|
||||
@@ -17,5 +17,7 @@ void no_vla(int n) {
|
||||
}
|
||||
|
||||
void no_logxor(int n) {
|
||||
int logxor = n ^^ n; // expected-error {{^^ is a reserved operator in OpenCL}}
|
||||
int logxor = n ^^ n; // expected-error {{^^ is a reserved operator in OpenCL}} \
|
||||
expected-error {{type name requires a specifier or qualifier}} \
|
||||
expected-error {{expected expression}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user