[clang] 1e43349 - Pass the found declaration to DiagnoseUseOfDecl.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 26 16:55:41 PDT 2023


Author: Richard Smith
Date: 2023-04-26T16:55:30-07:00
New Revision: 1e43349e321694d7fee3d77cb691887ad67fb5d7

URL: https://github.com/llvm/llvm-project/commit/1e43349e321694d7fee3d77cb691887ad67fb5d7
DIFF: https://github.com/llvm/llvm-project/commit/1e43349e321694d7fee3d77cb691887ad67fb5d7.diff

LOG: Pass the found declaration to DiagnoseUseOfDecl.

Don't pass in the resolved declaration, because that might be an
inheriting constructor declaration, which should never be used directly
and for which constraint satisfaction checking doesn't work.

Fixes #62361.

Added: 
    clang/test/SemaTemplate/concepts-inherited-ctor.cpp

Modified: 
    clang/lib/Sema/SemaInit.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 018ba5ed1bce4..243c3c1c9a4d1 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -6885,7 +6885,7 @@ PerformConstructorInitialization(Sema &S,
 
   if (isExplicitTemporary(Entity, Kind, NumArgs)) {
     // An explicitly-constructed temporary, e.g., X(1, 2).
-    if (S.DiagnoseUseOfDecl(Constructor, Loc))
+    if (S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc))
       return ExprError();
 
     TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo();
@@ -6900,8 +6900,6 @@ PerformConstructorInitialization(Sema &S,
     if (auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(
             Step.Function.FoundDecl.getDecl())) {
       CalleeDecl = S.findInheritingConstructor(Loc, Constructor, Shadow);
-      if (S.DiagnoseUseOfDecl(CalleeDecl, Loc))
-        return ExprError();
     }
     S.MarkFunctionReferenced(Loc, CalleeDecl);
 
@@ -10608,7 +10606,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
 
     // Make sure we didn't select an unusable deduction guide, and mark it
     // as referenced.
-    DiagnoseUseOfDecl(Best->Function, Kind.getLocation());
+    DiagnoseUseOfDecl(Best->FoundDecl, Kind.getLocation());
     MarkFunctionReferenced(Kind.getLocation(), Best->Function);
     break;
   }

diff  --git a/clang/test/SemaTemplate/concepts-inherited-ctor.cpp b/clang/test/SemaTemplate/concepts-inherited-ctor.cpp
new file mode 100644
index 0000000000000..f50a6aebeeab4
--- /dev/null
+++ b/clang/test/SemaTemplate/concepts-inherited-ctor.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+namespace GH62361 {
+  template <typename T, typename U = void*> struct B { // expected-note 14{{candidate}}
+    B() // expected-note 7{{not viable}}
+      requires __is_same(T, int); // expected-note 7{{because '__is_same(char, int)' evaluated to false}}
+  };
+
+  template <typename U> struct B<void, U> : B<int, U> {
+    using B<int, U>::B;
+  };
+
+  template<typename T>
+  void g(B<T>); // expected-note {{cannot convert}}
+
+  void f1() {
+    B<void> b1;
+    B<void> b2{};
+    B<void> b3 = {};
+    new B<void>{};
+    new B<void>();
+    g<void>({});
+    B<void>{};
+    B<void>();
+  }
+
+  void f2() {
+    B<int> b1;
+    B<int> b2{};
+    B<int> b3 = {};
+    new B<int>{};
+    new B<int>();
+    g<int>({});
+    B<int>{};
+    B<int>();
+  }
+
+  void f3() {
+    B<char> b1; // expected-error {{no matching constructor}}
+    B<char> b2{}; // expected-error {{no matching constructor}}
+    B<char> b3 = {}; // expected-error {{no matching constructor}}
+    new B<char>{}; // expected-error {{no matching constructor}}
+    new B<char>(); // expected-error {{no matching constructor}}
+    g<char>({}); // expected-error {{no matching function}}
+    B<char>{}; // expected-error {{no matching constructor}}
+    B<char>(); // expected-error {{no matching constructor}}
+  }
+}
+
+namespace no_early_substitution {
+  template <typename T> concept X = true;
+
+  struct A {};
+
+  template <typename T> struct B {
+    B() requires X<T*>;
+    B();
+  };
+
+  template <typename U = int, typename V = A>
+  struct C : public B<V&> {
+    using B<V&>::B;
+  };
+
+  void foo() {
+    // OK, we only substitute T ~> V& into X<T*> in a SFINAE context,
+    // during satisfaction checks.
+    C();
+  }
+}


        


More information about the cfe-commits mailing list