diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 90c1bfa8f6d1f..b893d358dfe79 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -10675,7 +10675,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( TD, FoundDecl, /*ExplicitArgs=*/nullptr, TmpInits, Candidates, SuppressUserConversions, /*PartialOverloading=*/false, AllowExplicit, ADLCallKind::NotADL, - /*PO=*/{}, /*AggregateCandidateDeduction=*/true); + /*PO=*/{}, AllowAggregateDeductionCandidate); } else { AddOverloadCandidate(GD, FoundDecl, Inits, Candidates, SuppressUserConversions, @@ -10772,7 +10772,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( // parenthesized expression-list, and there are no deduction-guides for // C, the set contains an additional function template, called the // aggregate deduction candidate, defined as follows. - if (!HasAnyDeductionGuide) { + if (getLangOpts().CPlusPlus20 && !HasAnyDeductionGuide) { if (ListInit && ListInit->getNumInits()) { SynthesizeAggrGuide(ListInit); } else if (PL && PL->getNumExprs()) { diff --git a/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp b/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp index 4bec1a8d4c48a..71189be076236 100644 --- a/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp +++ b/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp @@ -1,15 +1,16 @@ -// RUN: %clang_cc1 -std=c++20 -verify -ast-dump -ast-dump-decl-types -ast-dump-filter "deduction guide" %s | FileCheck %s --strict-whitespace +// RUN: %clang_cc1 -std=c++17 -verify=expected,cxx17 %s +// RUN: %clang_cc1 -std=c++20 -verify=expected,cxx20 -ast-dump -ast-dump-decl-types -ast-dump-filter "deduction guide" %s | FileCheck %s --strict-whitespace namespace Basic { - template struct A { + template struct A { // cxx17-note 6 {{candidate}} T x; T y; }; - A a1 = {3.0, 4.0}; - A a2 = {.x = 3.0, .y = 4.0}; + A a1 = {3.0, 4.0}; // cxx17-error {{no viable}} + A a2 = {.x = 3.0, .y = 4.0}; // cxx17-error {{no viable}} - A a3(3.0, 4.0); + A a3(3.0, 4.0); // cxx17-error {{no viable}} // CHECK-LABEL: Dumping Basic::: // CHECK: FunctionTemplateDecl {{.*}} implicit @@ -30,31 +31,31 @@ namespace Basic { // CHECK: `-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0 // CHECK: `-TemplateTypeParm {{.*}} 'T' - template struct S { // expected-note 2 {{candidate}} + template struct S { // cxx20-note 2 {{candidate}} T x; T y; }; - template struct C { // expected-note 10 {{candidate}} + template struct C { // cxx20-note 10 {{candidate}} cxx17-note 12 {{candidate}} S s; T t; }; - template struct D { // expected-note 6 {{candidate}} + template struct D { // cxx20-note 6 {{candidate}} cxx17-note 8 {{candidate}} S s; T t; }; C c1 = {1, 2}; // expected-error {{no viable}} C c2 = {1, 2, 3}; // expected-error {{no viable}} - C c3 = {{1u, 2u}, 3}; + C c3 = {{1u, 2u}, 3}; // cxx17-error {{no viable}} C c4(1, 2); // expected-error {{no viable}} C c5(1, 2, 3); // expected-error {{no viable}} - C c6({1u, 2u}, 3); + C c6({1u, 2u}, 3); // cxx17-error {{no viable}} D d1 = {1, 2}; // expected-error {{no viable}} - D d2 = {1, 2, 3}; + D d2 = {1, 2, 3}; // cxx17-error {{no viable}} D d3(1, 2); // expected-error {{no viable}} // CTAD succeed but brace elision is not allowed for parenthesized aggregate init. @@ -98,14 +99,14 @@ namespace Basic { // CHECK: |-ClassTemplateSpecialization {{.*}} 'S' // CHECK: `-BuiltinType {{.*}} 'int' - template struct E { + template struct E { // cxx17-note 4 {{candidate}} T t; decltype(t) t2; }; - E e1 = {1, 2}; + E e1 = {1, 2}; // cxx17-error {{no viable}} - E e2(1, 2); + E e2(1, 2); // cxx17-error {{no viable}} // CHECK-LABEL: Dumping Basic::: // CHECK: FunctionTemplateDecl {{.*}} implicit @@ -132,12 +133,12 @@ namespace Basic { }; template - struct F { + struct F { // cxx17-note 2 {{candidate}} typename I::type i; T t; }; - F f1 = {1, 2}; + F f1 = {1, 2}; // cxx17-error {{no viable}} // CHECK-LABEL: Dumping Basic::: // CHECK: FunctionTemplateDecl {{.*}} implicit @@ -160,18 +161,18 @@ namespace Basic { namespace Array { typedef __SIZE_TYPE__ size_t; - template struct A { // expected-note 2 {{candidate}} + template struct A { // cxx20-note 2 {{candidate}} cxx17-note 14 {{candidate}} T array[N]; }; - A a1 = {{1, 2, 3}}; + A a1 = {{1, 2, 3}}; // cxx17-error {{no viable}} A a2 = {1, 2, 3}; // expected-error {{no viable}} - A a3 = {"meow"}; - A a4 = {("meow")}; + A a3 = {"meow"}; // cxx17-error {{no viable}} + A a4 = {("meow")}; // cxx17-error {{no viable}} - A a5({1, 2, 3}); - A a6("meow"); - A a7(("meow")); + A a5({1, 2, 3}); // cxx17-error {{no viable}} + A a6("meow"); // cxx17-error {{no viable}} + A a7(("meow")); // cxx17-error {{no viable}} // CHECK-LABEL: Dumping Array::: // CHECK: FunctionTemplateDecl {{.*}} implicit @@ -216,14 +217,14 @@ namespace Array { } namespace BraceElision { - template struct A { + template struct A { // cxx17-note 4 {{candidate}} T array[2]; }; - A a1 = {0, 1}; + A a1 = {0, 1}; // cxx17-error {{no viable}} // CTAD succeed but brace elision is not allowed for parenthesized aggregate init. - A a2(0, 1); // expected-error {{array initializer must be an initializer list}} + A a2(0, 1); // cxx20-error {{array initializer must be an initializer list}} cxx17-error {{no viable}} // CHECK-LABEL: Dumping BraceElision::: // CHECK: FunctionTemplateDecl {{.*}} implicit @@ -246,15 +247,15 @@ namespace BraceElision { } namespace TrailingPack { - template struct A : T... { + template struct A : T... { // cxx17-note 4 {{candidate}} }; - A a1 = { + A a1 = { // cxx17-error {{no viable}} []{ return 1; }, []{ return 2; } }; - A a2( + A a2( // cxx17-error {{no viable}} []{ return 1; }, []{ return 2; } ); @@ -302,20 +303,20 @@ namespace NonTrailingPack { namespace DeduceArity { template struct Types {}; - template struct F : Types, T... {}; // expected-note 12 {{candidate}} + template struct F : Types, T... {}; // cxx20-note 12 {{candidate}} cxx17-note 16 {{candidate}} struct X {}; struct Y {}; struct Z {}; struct W { operator Y(); }; - F f1 = {Types{}, {}, {}}; - F f2 = {Types{}, X{}, Y{}}; + F f1 = {Types{}, {}, {}}; // cxx17-error {{no viable}} + F f2 = {Types{}, X{}, Y{}}; // cxx17-error {{no viable}} F f3 = {Types{}, X{}, W{}}; // expected-error {{no viable}} F f4 = {Types{}, {}, {}}; // expected-error {{no viable}} - F f5(Types{}, {}, {}); - F f6(Types{}, X{}, Y{}); + F f5(Types{}, {}, {}); // cxx17-error {{no viable}} + F f6(Types{}, X{}, Y{}); // cxx17-error {{no viable}} F f7(Types{}, X{}, W{}); // expected-error {{no viable}} F f8(Types{}, {}, {}); // expected-error {{no viable}}