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

Reply via email to