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( 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 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 struct B : B { + using B::B; + }; + + template + void g(B); // expected-note {{cannot convert}} + + void f1() { + B b1; + B b2{}; + B b3 = {}; + new B{}; + new B(); + g({}); + B{}; + B(); + } + + void f2() { + B b1; + B b2{}; + B b3 = {}; + new B{}; + new B(); + g({}); + B{}; + B(); + } + + void f3() { + B b1; // expected-error {{no matching constructor}} + B b2{}; // expected-error {{no matching constructor}} + B b3 = {}; // expected-error {{no matching constructor}} + new B{}; // expected-error {{no matching constructor}} + new B(); // expected-error {{no matching constructor}} + g({}); // expected-error {{no matching function}} + B{}; // expected-error {{no matching constructor}} + B(); // expected-error {{no matching constructor}} + } +} + +namespace no_early_substitution { + template concept X = true; + + struct A {}; + + template struct B { + B() requires X; + B(); + }; + + template + struct C : public B { + using B::B; + }; + + void foo() { + // OK, we only substitute T ~> V& into X in a SFINAE context, + // during satisfaction checks. + C(); + } +}