This revision was automatically updated to reflect the committed changes. Closed by commit rG9be5f4d5afd9: [clang] Don't typo-fix an expression in a SFINAE context. (authored by arthur.j.odwyer).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D117603/new/ https://reviews.llvm.org/D117603 Files: clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaExprMember.cpp clang/test/SemaCXX/PR52970.cpp Index: clang/test/SemaCXX/PR52970.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/PR52970.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s +// expected-no-diagnostics + +struct Incomplete; +template <class T> struct Holder { T t; }; + +namespace DotFollowingFunctionName { +struct Good { + struct Nested { + int b; + } a; +}; + +struct Bad { + Holder<Incomplete> a(); +}; + +template <class T> +constexpr auto f(T t) -> decltype((t.a.b, true)) { return true; } +constexpr bool f(...) { return false; } + +static_assert(DotFollowingFunctionName::f(Good{}), ""); +static_assert(!DotFollowingFunctionName::f(Bad{}), ""); + +#if __cplusplus >= 202002L +template <class T> +concept C = requires(T t) { t.a.b; }; + +static_assert(C<Good>); +static_assert(!C<Bad>); +#endif +} // namespace DotFollowingFunctionName + +namespace DotFollowingPointer { +struct Good { + int begin(); +}; +using Bad = Holder<Incomplete> *; + +template <class T> +constexpr auto f(T t) -> decltype((t.begin(), true)) { return true; } +constexpr bool f(...) { return false; } + +static_assert(DotFollowingPointer::f(Good{}), ""); +static_assert(!DotFollowingPointer::f(Bad{}), ""); + +#if __cplusplus >= 202002L +template <class T> +concept C = requires(T t) { t.begin(); }; + +static_assert(C<Good>); +static_assert(!C<Bad>); +#endif +} // namespace DotFollowingPointer Index: clang/lib/Sema/SemaExprMember.cpp =================================================================== --- clang/lib/Sema/SemaExprMember.cpp +++ clang/lib/Sema/SemaExprMember.cpp @@ -1645,6 +1645,9 @@ << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange() << FixItHint::CreateReplacement(OpLoc, "->"); + if (S.isSFINAEContext()) + return ExprError(); + // Recurse as an -> access. IsArrow = true; return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -2554,6 +2554,11 @@ bool Sema::tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD, bool ForceComplain, bool (*IsPlausibleResult)(QualType)) { + if (isSFINAEContext()) { + // If this is a SFINAE context, don't try anything that might trigger ADL + // prematurely. + return false; + } SourceLocation Loc = E.get()->getExprLoc(); SourceRange Range = E.get()->getSourceRange();
Index: clang/test/SemaCXX/PR52970.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/PR52970.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s +// expected-no-diagnostics + +struct Incomplete; +template <class T> struct Holder { T t; }; + +namespace DotFollowingFunctionName { +struct Good { + struct Nested { + int b; + } a; +}; + +struct Bad { + Holder<Incomplete> a(); +}; + +template <class T> +constexpr auto f(T t) -> decltype((t.a.b, true)) { return true; } +constexpr bool f(...) { return false; } + +static_assert(DotFollowingFunctionName::f(Good{}), ""); +static_assert(!DotFollowingFunctionName::f(Bad{}), ""); + +#if __cplusplus >= 202002L +template <class T> +concept C = requires(T t) { t.a.b; }; + +static_assert(C<Good>); +static_assert(!C<Bad>); +#endif +} // namespace DotFollowingFunctionName + +namespace DotFollowingPointer { +struct Good { + int begin(); +}; +using Bad = Holder<Incomplete> *; + +template <class T> +constexpr auto f(T t) -> decltype((t.begin(), true)) { return true; } +constexpr bool f(...) { return false; } + +static_assert(DotFollowingPointer::f(Good{}), ""); +static_assert(!DotFollowingPointer::f(Bad{}), ""); + +#if __cplusplus >= 202002L +template <class T> +concept C = requires(T t) { t.begin(); }; + +static_assert(C<Good>); +static_assert(!C<Bad>); +#endif +} // namespace DotFollowingPointer Index: clang/lib/Sema/SemaExprMember.cpp =================================================================== --- clang/lib/Sema/SemaExprMember.cpp +++ clang/lib/Sema/SemaExprMember.cpp @@ -1645,6 +1645,9 @@ << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange() << FixItHint::CreateReplacement(OpLoc, "->"); + if (S.isSFINAEContext()) + return ExprError(); + // Recurse as an -> access. IsArrow = true; return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -2554,6 +2554,11 @@ bool Sema::tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD, bool ForceComplain, bool (*IsPlausibleResult)(QualType)) { + if (isSFINAEContext()) { + // If this is a SFINAE context, don't try anything that might trigger ADL + // prematurely. + return false; + } SourceLocation Loc = E.get()->getExprLoc(); SourceRange Range = E.get()->getSourceRange();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits