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

Reply via email to