rymiel created this revision. rymiel added a project: clang-format. rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay. Herald added a project: All. rymiel requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The noexcept specifier and explicit specifier can optionally include a boolean expression to make these specifiers apply conditionally, however, clang-format didn't set the context for the parenthesized content of these specifiers, meaning they inherited the parent context, which usually isn't an expressions, leading to misannotated binary operators. This patch applies expression context to the content of these specifiers, making them similar to the static_assert keyword. Fixes https://github.com/llvm/llvm-project/issues/44543 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D146284 Files: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -11592,6 +11592,10 @@ verifyFormat("template <bool B, bool C> class A {\n" " static_assert(B && C, \"Something is wrong\");\n" "};"); + verifyFormat("template <typename T> void swap() noexcept(Bar<T> && Foo<T>);"); + verifyFormat("template <typename T> struct S {\n" + " explicit(Bar<T> && Foo<T>) S(const S &);\n" + "};"); verifyGoogleFormat("#define IF(a, b, c) if (a && (b == c))"); verifyGoogleFormat("#define WHILE(a, b, c) while (a && (b == c))"); verifyFormat("#define A(a, b) (a && b)"); Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -318,9 +318,10 @@ // export type X = (...); Contexts.back().IsExpression = false; } else if (OpeningParen.Previous && - (OpeningParen.Previous->isOneOf(tok::kw_static_assert, - tok::kw_while, tok::l_paren, - tok::comma, TT_BinaryOperator) || + (OpeningParen.Previous->isOneOf( + tok::kw_static_assert, tok::kw_noexcept, tok::kw_explicit, + tok::kw_while, tok::l_paren, tok::comma, + TT_BinaryOperator) || OpeningParen.Previous->isIf())) { // static_assert, if and while usually contain expressions. Contexts.back().IsExpression = true;
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -11592,6 +11592,10 @@ verifyFormat("template <bool B, bool C> class A {\n" " static_assert(B && C, \"Something is wrong\");\n" "};"); + verifyFormat("template <typename T> void swap() noexcept(Bar<T> && Foo<T>);"); + verifyFormat("template <typename T> struct S {\n" + " explicit(Bar<T> && Foo<T>) S(const S &);\n" + "};"); verifyGoogleFormat("#define IF(a, b, c) if (a && (b == c))"); verifyGoogleFormat("#define WHILE(a, b, c) while (a && (b == c))"); verifyFormat("#define A(a, b) (a && b)"); Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -318,9 +318,10 @@ // export type X = (...); Contexts.back().IsExpression = false; } else if (OpeningParen.Previous && - (OpeningParen.Previous->isOneOf(tok::kw_static_assert, - tok::kw_while, tok::l_paren, - tok::comma, TT_BinaryOperator) || + (OpeningParen.Previous->isOneOf( + tok::kw_static_assert, tok::kw_noexcept, tok::kw_explicit, + tok::kw_while, tok::l_paren, tok::comma, + TT_BinaryOperator) || OpeningParen.Previous->isIf())) { // static_assert, if and while usually contain expressions. Contexts.back().IsExpression = true;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits