diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -10714,7 +10714,8 @@ ElementTypes[I] = Context.getRValueReferenceType(ElementTypes[I]); else if (isa( ListInit->getInit(I)->IgnoreParenImpCasts())) - ElementTypes[I] = Context.getLValueReferenceType(ElementTypes[I]); + ElementTypes[I] = + Context.getLValueReferenceType(ElementTypes[I].withConst()); } llvm::FoldingSetNodeID ID; diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p1-9.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p1-9.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p1-9.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -verify -std=c++20 %s + +using size_t = decltype(sizeof(int)); + +template +struct H { + T array[N]; +}; +template +struct I { + volatile T array[N]; +}; +template +struct J { // expected-note 3{{candidate}} + unsigned char array[N]; +}; + +H h = { "abc" }; +I i = { "def" }; +static_assert(__is_same(decltype(h), H)); // Not H +static_assert(__is_same(decltype(i), I)); + +J j = { "ghi" }; // expected-error {{no viable constructor or deduction guide}} + +template +struct K { + char array[N]; +}; +K k = { "abc" }; +static_assert(__is_same(decltype(k), K<4>)); + +template +struct L { + const T array[N]; +}; +L l = { "abc" }; +static_assert(__is_same(decltype(l), L)); + +template +struct M { + T array[sizeof(T) == 0 ? 4 : 4]; +}; +M m = { "abc" }; +static_assert(__is_same(decltype(m), M)); + +/* +template +struct N { + T array[4]; +}; +// The C99 extension, brace elision for designated initializers, +// makes `T = const char*` viable, and that is used instead +N n = { .array = "abc" }; +static_assert(__is_same(decltype(n), N)); + */