diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index edb97347f0771..39b9176865fc0 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -686,6 +686,9 @@ Bug Fixes in This Version - Fix an issue where clang doesn't respect detault template arguments that are added in a later redeclaration for CTAD. Fixes (#69987 <https://github.com/llvm/llvm-project/issues/69987>`_) +- Fix an issue where CTAD fails for explicit type conversion. + Fixes (#64347 <https://github.com/llvm/llvm-project/issues/64347>`_) + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 9887cc4ba4658..5e3b57ea33220 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9354,8 +9354,7 @@ class Sema final { QualType DeduceTemplateSpecializationFromInitializer( TypeSourceInfo *TInfo, const InitializedEntity &Entity, - const InitializationKind &Kind, MultiExprArg Init, - ParenListExpr *PL = nullptr); + const InitializationKind &Kind, MultiExprArg Init); QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, QualType Type, TypeSourceInfo *TSI, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index edf44bbc52119..e08fed49f9ec0 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12957,7 +12957,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, // FIXME: Initialization should not be taking a mutable list of inits. SmallVector<Expr*, 8> InitsCopy(DeduceInits.begin(), DeduceInits.end()); return DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind, - InitsCopy, PL); + InitsCopy); } if (DirectInit) { diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index d6459fd9d7875..0fbd87ce34db9 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -10561,7 +10561,7 @@ static bool isOrIsDerivedFromSpecializationOf(CXXRecordDecl *RD, QualType Sema::DeduceTemplateSpecializationFromInitializer( TypeSourceInfo *TSInfo, const InitializedEntity &Entity, - const InitializationKind &Kind, MultiExprArg Inits, ParenListExpr *PL) { + const InitializationKind &Kind, MultiExprArg Inits) { auto *DeducedTST = dyn_cast<DeducedTemplateSpecializationType>( TSInfo->getType()->getContainedDeducedType()); assert(DeducedTST && "not a deduced template specialization type"); @@ -10792,9 +10792,12 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( if (getLangOpts().CPlusPlus20 && !HasAnyDeductionGuide) { if (ListInit && ListInit->getNumInits()) { SynthesizeAggrGuide(ListInit); - } else if (PL && PL->getNumExprs()) { - InitListExpr TempListInit(getASTContext(), PL->getLParenLoc(), - PL->exprs(), PL->getRParenLoc()); + } else if (Inits.size()) { // parenthesized expression-list + // Inits are expressions inside the parentheses. We don't have + // the parentheses source locations, use the begin/end of Inits as the + // best heuristic. + InitListExpr TempListInit(getASTContext(), Inits.front()->getBeginLoc(), + Inits, Inits.back()->getEndLoc()); SynthesizeAggrGuide(&TempListInit); } } diff --git a/clang/test/SemaCXX/ctad.cpp b/clang/test/SemaCXX/ctad.cpp new file mode 100644 index 0000000000000..10806f107b4ee --- /dev/null +++ b/clang/test/SemaCXX/ctad.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s +// expected-no-diagnostics + +namespace GH64347 { + +template<typename X, typename Y> struct A { X x; Y y;}; +void test() { + A(1, 2); + new A(1, 2); +} + +template<A a> +void f() { (void)a; } +void k() { + // Test CTAD works for non-type template arguments. + f<A(0, 0)>(); +} + +} // namespace GH64347