From 1e43349e321694d7fee3d77cb691887ad67fb5d7 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 26 Apr 2023 16:53:34 -0700 Subject: [PATCH] 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. --- clang/lib/Sema/SemaInit.cpp | 6 +- .../SemaTemplate/concepts-inherited-ctor.cpp | 70 +++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 clang/test/SemaTemplate/concepts-inherited-ctor.cpp diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 018ba5ed1bce..243c3c1c9a4d 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 000000000000..f50a6aebeeab --- /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(); + } +}