Author: Zhouyi Zhou Date: 2022-11-06T15:07:42-08:00 New Revision: b84fd822fa7eeaec2bb084a26caa9e41f3495923
URL: https://github.com/llvm/llvm-project/commit/b84fd822fa7eeaec2bb084a26caa9e41f3495923 DIFF: https://github.com/llvm/llvm-project/commit/b84fd822fa7eeaec2bb084a26caa9e41f3495923.diff LOG: Add boundary check for ASTUnresolvedSet::erase When compile following code with clang (Debug build), Assertion will be triggered. ``` struct A { struct Nested {}; operator Nested*() {return 0;}; }; struct B : A { using A::operator typename A::Nested*; operator typename A::Nested *() { struct A * thi = this; return *thi; }; }; ``` The assertion fail is caused by: `void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); }` when size of `Decls` is 1 before erase. Reviewed By: rjmccall, MaskRay Differential Revision: https://reviews.llvm.org/D137263 Added: Modified: clang/include/clang/AST/ASTUnresolvedSet.h clang/test/SemaCXX/using-decl-templates.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTUnresolvedSet.h b/clang/include/clang/AST/ASTUnresolvedSet.h index 8d2b23b3539a2..398ffb188c95b 100644 --- a/clang/include/clang/AST/ASTUnresolvedSet.h +++ b/clang/include/clang/AST/ASTUnresolvedSet.h @@ -69,7 +69,12 @@ class ASTUnresolvedSet { return false; } - void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); } + void erase(unsigned I) { + if (I == Decls.size() - 1) + Decls.pop_back(); + else + Decls[I] = Decls.pop_back_val(); + } void clear() { Decls.clear(); } diff --git a/clang/test/SemaCXX/using-decl-templates.cpp b/clang/test/SemaCXX/using-decl-templates.cpp index 73d9bc3e774cb..77dc596fdfc9f 100644 --- a/clang/test/SemaCXX/using-decl-templates.cpp +++ b/clang/test/SemaCXX/using-decl-templates.cpp @@ -102,6 +102,28 @@ struct Derived : Base<false> { // expected-note {{requested here}} }; } // namespace DontDiagnoseInvalidTest +namespace shadow_nested_operator { +template <typename T> +struct A { + struct Nested {}; + operator Nested*() {return 0;}; +}; + +template <typename T> +struct B : A<T> { + using A<T>::operator typename A<T>::Nested*; + operator typename A<T>::Nested *() { + struct A<T> * thi = this; + return *thi; + }; +}; + +int foo () { + struct B<int> b; + auto s = *b; +} +} // namespace shadow_nested_operator + namespace func_templ { namespace sss { double foo(int, double); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits