llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Krystian Stasiowski (sdkrystian)

<details>
<summary>Changes</summary>

The following snippet causes a crash ([godbolt 
link](https://godbolt.org/z/E17sYfYrY)):
```cpp
template&lt;typename T&gt;
struct A : T {
  using T::f;
  void f();

  void g() {
    f&lt;int&gt;(); // crash here
  }
};
```
This happens because we cast the result of `getAsTemplateNameDecl` as a 
`TemplateDecl` in `Sema::ClassifyName`, which we cannot do for an 
`UnresolvedUsingValueDecl`. I believe the correct thing to do here is to create 
an `OverloadedTemplateName`.

---
Full diff: https://github.com/llvm/llvm-project/pull/83842.diff


3 Files Affected:

- (modified) clang/lib/AST/ASTContext.cpp (+2-1) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+2-1) 
- (added) clang/test/SemaTemplate/unqual-unresolved-using-value.cpp (+24) 


``````````diff
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 5a8fae76a43a4d..28dd69b8e45758 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -9200,7 +9200,8 @@ TemplateName
 ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
                                       UnresolvedSetIterator End) const {
   unsigned size = End - Begin;
-  assert(size > 1 && "set is not overloaded!");
+  assert((size == 1 && isa<UnresolvedUsingValueDecl>(*Begin)) ||
+         size > 1 && "set is not overloaded!");
 
   void *memory = Allocate(sizeof(OverloadedTemplateStorage) +
                           size * sizeof(FunctionTemplateDecl*));
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9fdd8eb236d1ee..c62e4ce7d0f9c4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1115,7 +1115,8 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, 
CXXScopeSpec &SS,
     bool IsFunctionTemplate;
     bool IsVarTemplate;
     TemplateName Template;
-    if (Result.end() - Result.begin() > 1) {
+
+    if ((Result.end() - Result.begin() > 1) || Result.isUnresolvableResult()) {
       IsFunctionTemplate = true;
       Template = Context.getOverloadedTemplateName(Result.begin(),
                                                    Result.end());
diff --git a/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp 
b/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp
new file mode 100644
index 00000000000000..7c45342adce783
--- /dev/null
+++ b/clang/test/SemaTemplate/unqual-unresolved-using-value.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+template<typename T>
+struct A : T {
+  using T::f;
+  using T::g;
+
+  void f();
+  void g();
+
+  void h() {
+    f<int>();
+    g<int>(); // expected-error{{no member named 'g' in 'A<B>'}}
+  }
+};
+
+struct B {
+  template<typename T>
+  void f();
+
+  void g();
+};
+
+template struct A<B>; // expected-note{{in instantiation of member function 
'A<B>::h' requested here}}

``````````

</details>


https://github.com/llvm/llvm-project/pull/83842
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to