This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG7e459126185f: [clang] Do not crash on arrow operator on dependent type. (authored by adamcz).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D121824/new/ https://reviews.llvm.org/D121824 Files: clang/lib/Sema/TreeTransform.h clang/test/SemaCXX/arrow-operator.cpp Index: clang/test/SemaCXX/arrow-operator.cpp =================================================================== --- clang/test/SemaCXX/arrow-operator.cpp +++ clang/test/SemaCXX/arrow-operator.cpp @@ -65,3 +65,51 @@ } } // namespace arrow_suggest + +namespace no_crash_dependent_type { + +template <class T> +struct A { + void call(); + A *operator->(); +}; + +template <class T> +void foo() { + // The "requires an initializer" error seems unnecessary. + A<int> &x = blah[7]; // expected-error {{use of undeclared identifier 'blah'}} \ + // expected-error {{requires an initializer}} + // x is dependent. + x->call(); +} + +void test() { + foo<int>(); // expected-note {{requested here}} +} + +} // namespace no_crash_dependent_type + +namespace clangd_issue_1073_no_crash_dependent_type { + +template <typename T> struct Ptr { + T *operator->(); +}; + +struct Struct { + int len; +}; + +template <int> +struct TemplateStruct { + Ptr<Struct> val(); // expected-note {{declared here}} +}; + +template <int I> +void templateFunc(const TemplateStruct<I> &ts) { + Ptr<Struct> ptr = ts.val(); // expected-error {{function is not marked const}} + auto foo = ptr->len; +} + +template void templateFunc<0>(const TemplateStruct<0> &); // expected-note {{requested here}} + +} // namespace clangd_issue_1073_no_crash_dependent_type Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -14757,6 +14757,10 @@ return getSema().CreateBuiltinArraySubscriptExpr( First, Callee->getBeginLoc(), Second, OpLoc); } else if (Op == OO_Arrow) { + // It is possible that the type refers to a RecoveryExpr created earlier + // in the tree transformation. + if (First->getType()->isDependentType()) + return ExprError(); // -> is never a builtin operation. return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc); } else if (Second == nullptr || isPostIncDec) {
Index: clang/test/SemaCXX/arrow-operator.cpp =================================================================== --- clang/test/SemaCXX/arrow-operator.cpp +++ clang/test/SemaCXX/arrow-operator.cpp @@ -65,3 +65,51 @@ } } // namespace arrow_suggest + +namespace no_crash_dependent_type { + +template <class T> +struct A { + void call(); + A *operator->(); +}; + +template <class T> +void foo() { + // The "requires an initializer" error seems unnecessary. + A<int> &x = blah[7]; // expected-error {{use of undeclared identifier 'blah'}} \ + // expected-error {{requires an initializer}} + // x is dependent. + x->call(); +} + +void test() { + foo<int>(); // expected-note {{requested here}} +} + +} // namespace no_crash_dependent_type + +namespace clangd_issue_1073_no_crash_dependent_type { + +template <typename T> struct Ptr { + T *operator->(); +}; + +struct Struct { + int len; +}; + +template <int> +struct TemplateStruct { + Ptr<Struct> val(); // expected-note {{declared here}} +}; + +template <int I> +void templateFunc(const TemplateStruct<I> &ts) { + Ptr<Struct> ptr = ts.val(); // expected-error {{function is not marked const}} + auto foo = ptr->len; +} + +template void templateFunc<0>(const TemplateStruct<0> &); // expected-note {{requested here}} + +} // namespace clangd_issue_1073_no_crash_dependent_type Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -14757,6 +14757,10 @@ return getSema().CreateBuiltinArraySubscriptExpr( First, Callee->getBeginLoc(), Second, OpLoc); } else if (Op == OO_Arrow) { + // It is possible that the type refers to a RecoveryExpr created earlier + // in the tree transformation. + if (First->getType()->isDependentType()) + return ExprError(); // -> is never a builtin operation. return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc); } else if (Second == nullptr || isPostIncDec) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits