Author: Aaron Ballman Date: 2024-09-16T07:46:58-04:00 New Revision: 1881f648e28aa58aa0a4dca1422572f65dafa9a4
URL: https://github.com/llvm/llvm-project/commit/1881f648e28aa58aa0a4dca1422572f65dafa9a4 DIFF: https://github.com/llvm/llvm-project/commit/1881f648e28aa58aa0a4dca1422572f65dafa9a4.diff LOG: Remove ^^ as a token in OpenCL (#108224) OpenCL has a reserved operator (^^), the use of which was diagnosed as an error (735c6cdebdcd4292928079cb18a90f0dd5cd65fb). 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. Added: Modified: clang-tools-extra/clang-tidy/readability/AvoidUnconditionalPreprocessorIfCheck.cpp clang-tools-extra/pseudo/lib/cxx/cxx.bnf clang/include/clang/Basic/DiagnosticLexKinds.td clang/include/clang/Basic/DiagnosticParseKinds.td clang/include/clang/Basic/TokenKinds.def clang/lib/Basic/OperatorPrecedence.cpp clang/lib/Lex/Lexer.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Sema/SemaCodeComplete.cpp clang/test/SemaOpenCL/unsupported.cl Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/readability/AvoidUnconditionalPreprocessorIfCheck.cpp b/clang-tools-extra/clang-tidy/readability/AvoidUnconditionalPreprocessorIfCheck.cpp index d92d0e8f2dbf7a..ca5fc358ce290a 100644 --- a/clang-tools-extra/clang-tidy/readability/AvoidUnconditionalPreprocessorIfCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/AvoidUnconditionalPreprocessorIfCheck.cpp @@ -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; } } diff --git a/clang-tools-extra/pseudo/lib/cxx/cxx.bnf b/clang-tools-extra/pseudo/lib/cxx/cxx.bnf index 36caf7b1e63379..fbd964d4abe861 100644 --- a/clang-tools-extra/pseudo/lib/cxx/cxx.bnf +++ b/clang-tools-extra/pseudo/lib/cxx/cxx.bnf @@ -639,7 +639,6 @@ operator-name := > operator-name := <= operator-name := >= operator-name := <=> -operator-name := ^^ operator-name := || operator-name := << operator-name := greatergreater diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index fc14bb6aa21651..889370221f32f0 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -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">, diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index fec2456d6f4497..1afadb3bff750d 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -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< diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index a82ff684b2ac7d..00e150dbd7a3a7 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -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 diff --git a/clang/lib/Basic/OperatorPrecedence.cpp b/clang/lib/Basic/OperatorPrecedence.cpp index 02876f14291d12..c4e8fe96cdf4b5 100644 --- a/clang/lib/Basic/OperatorPrecedence.cpp +++ b/clang/lib/Basic/OperatorPrecedence.cpp @@ -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; diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 8647e9f2f27c3d..12cb46042c946b 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -4325,10 +4325,9 @@ bool Lexer::LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine) { 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; diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 64f284d78b24db..e7514500dc53a4 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -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, diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 88d4732c7d5c6a..3e31f3d82657a3 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -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. diff --git a/clang/test/SemaOpenCL/unsupported.cl b/clang/test/SemaOpenCL/unsupported.cl index 75175c88fe2673..7195ceb7ca49c8 100644 --- a/clang/test/SemaOpenCL/unsupported.cl +++ b/clang/test/SemaOpenCL/unsupported.cl @@ -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}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits