MitalAshok created this revision. Herald added a project: All. MitalAshok edited the summary of this revision. MitalAshok added reviewers: ychen, aaron.ballman, cor3ntin. MitalAshok added a subscriber: cfe-commits. MitalAshok retitled this revision from "Fix CTAD with string literals adding extra const" to "Fix aggregate CTAD with string literals adding extra const". MitalAshok added inline comments. MitalAshok published this revision for review. Herald added a project: clang.
================ Comment at: clang/lib/Sema/SemaInit.cpp:10707 // if e_i is of array type and x_i is a bstring-literal, T_i is an // lvalue reference to the const-qualified declared type of e_i and // C++ [over.match.class.deduct]p1.10: ---------------- The "const-qualified" here was missing Missing a `withConst`, so when deducing from a string literal, a `const` is erroneously added to the deduced type. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D154301 Files: clang/lib/Sema/SemaInit.cpp clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p1-9.cpp Index: clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p1-9.cpp =================================================================== --- /dev/null +++ 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<class T, size_t N> +struct H { + T array[N]; +}; +template<class T, size_t N> +struct I { + volatile T array[N]; +}; +template<size_t N> +struct J { // expected-note 3{{candidate}} + unsigned char array[N]; +}; + +H h = { "abc" }; +I i = { "def" }; +static_assert(__is_same(decltype(h), H<char, 4>)); // Not H<const char, 4> +static_assert(__is_same(decltype(i), I<char, 4>)); + +J j = { "ghi" }; // expected-error {{no viable constructor or deduction guide}} + +template<size_t N> +struct K { + char array[N]; +}; +K k = { "abc" }; +static_assert(__is_same(decltype(k), K<4>)); + +template<typename T, size_t N> +struct L { + const T array[N]; +}; +L l = { "abc" }; +static_assert(__is_same(decltype(l), L<char, 4>)); + +template<typename T> +struct M { + T array[sizeof(T) == 0 ? 4 : 4]; +}; +M m = { "abc" }; +static_assert(__is_same(decltype(m), M<char>)); + +/* +template<typename T> +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<char>)); + */ Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -10714,7 +10714,8 @@ ElementTypes[I] = Context.getRValueReferenceType(ElementTypes[I]); else if (isa<StringLiteral>( ListInit->getInit(I)->IgnoreParenImpCasts())) - ElementTypes[I] = Context.getLValueReferenceType(ElementTypes[I]); + ElementTypes[I] = + Context.getLValueReferenceType(ElementTypes[I].withConst()); } llvm::FoldingSetNodeID ID;
Index: clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p1-9.cpp =================================================================== --- /dev/null +++ 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<class T, size_t N> +struct H { + T array[N]; +}; +template<class T, size_t N> +struct I { + volatile T array[N]; +}; +template<size_t N> +struct J { // expected-note 3{{candidate}} + unsigned char array[N]; +}; + +H h = { "abc" }; +I i = { "def" }; +static_assert(__is_same(decltype(h), H<char, 4>)); // Not H<const char, 4> +static_assert(__is_same(decltype(i), I<char, 4>)); + +J j = { "ghi" }; // expected-error {{no viable constructor or deduction guide}} + +template<size_t N> +struct K { + char array[N]; +}; +K k = { "abc" }; +static_assert(__is_same(decltype(k), K<4>)); + +template<typename T, size_t N> +struct L { + const T array[N]; +}; +L l = { "abc" }; +static_assert(__is_same(decltype(l), L<char, 4>)); + +template<typename T> +struct M { + T array[sizeof(T) == 0 ? 4 : 4]; +}; +M m = { "abc" }; +static_assert(__is_same(decltype(m), M<char>)); + +/* +template<typename T> +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<char>)); + */ Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -10714,7 +10714,8 @@ ElementTypes[I] = Context.getRValueReferenceType(ElementTypes[I]); else if (isa<StringLiteral>( ListInit->getInit(I)->IgnoreParenImpCasts())) - ElementTypes[I] = Context.getLValueReferenceType(ElementTypes[I]); + ElementTypes[I] = + Context.getLValueReferenceType(ElementTypes[I].withConst()); } llvm::FoldingSetNodeID ID;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits