Skip to content

Commit

Permalink
Fix aggregate CTAD with string literals adding extra const
Browse files Browse the repository at this point in the history
Missing a `withConst`, so when deducing from a string literal, a `const` is erroneously added to the deduced type.

Reviewed By: ychen

Differential Revision: https://reviews.llvm.org/D154301
  • Loading branch information
MitalAshok authored and Yuanfang Chen committed Jul 5, 2023
1 parent 2265bb0 commit 92f4bf2
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 14 deletions.
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10714,7 +10714,8 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
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;
Expand Down
24 changes: 24 additions & 0 deletions clang/test/CXX/drs/dr26xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,27 @@ void f() {
brachiosaur |= neck; // OK
}
}

namespace dr2681 { // dr2681: 17
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}}
}
24 changes: 12 additions & 12 deletions clang/test/SemaTemplate/aggregate-deduction-candidate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,22 +198,22 @@ namespace Array {
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for A>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
// CHECK: |-NonTypeTemplateParmDecl {{.*}} 'size_t':'unsigned {{.*}}' depth 0 index 1 N
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T (&)[N]) -> A<T, N>'
// CHECK: | `-ParmVarDecl {{.*}} 'T (&)[N]'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A> 'auto (const char (&)[5]) -> Array::A<const char, 5>'
// CHECK: |-TemplateArgument type 'const char'
// CHECK: | `-QualType {{.*}} 'const char' const
// CHECK: | `-BuiltinType {{.*}} 'char'
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (const T (&)[N]) -> A<T, N>'
// CHECK: | `-ParmVarDecl {{.*}} 'const T (&)[N]'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A> 'auto (const char (&)[5]) -> Array::A<char, 5>'
// CHECK: |-TemplateArgument type 'char'
// CHECK: | `-BuiltinType {{.*}} 'char'
// CHECK: |-TemplateArgument integral 5
// CHECK: `-ParmVarDecl {{.*}} 'const char (&)[5]'
// CHECK: FunctionProtoType {{.*}} 'auto (T (&)[N]) -> A<T, N>' dependent trailing_return cdecl
// CHECK: FunctionProtoType {{.*}} 'auto (const T (&)[N]) -> A<T, N>' dependent trailing_return cdecl
// CHECK: |-InjectedClassNameType {{.*}} 'A<T, N>' dependent
// CHECK: | `-CXXRecord {{.*}} 'A'
// CHECK: `-LValueReferenceType {{.*}} 'T (&)[N]' dependent
// CHECK: `-DependentSizedArrayType {{.*}} 'T[N]' dependent
// CHECK: |-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0
// CHECK: | `-TemplateTypeParm {{.*}} 'T'
// CHECK: `-DeclRefExpr {{.*}} 'size_t':'unsigned {{.*}}' NonTypeTemplateParm {{.*}} 'N' 'size_t':'unsigned {{.*}}'
// CHECK: `-LValueReferenceType {{.*}} 'const T (&)[N]' dependent
// CHECK: `-QualType {{.*}} 'const T[N]' const
// CHECK: `-DependentSizedArrayType {{.*}} 'T[N]' dependent
// CHECK: |-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0
// CHECK: | `-TemplateTypeParm {{.*}} 'T'
// CHECK: `-DeclRefExpr {{.*}} 'size_t':'unsigned{{.*}}' NonTypeTemplateParm {{.*}} 'N' 'size_t':'unsigned{{.*}}'
}

namespace BraceElision {
Expand Down
2 changes: 1 addition & 1 deletion clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -15893,7 +15893,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2681.html">2681</a></td>
<td>DR</td>
<td>Deducing member array type from string literal</td>
<td class="none" align="center">Unknown</td>
<td class="unreleased" align="center">Clang 17</td>
</tr>
<tr id="2682">
<td><a href="https://cplusplus.github.io/CWG/issues/2682.html">2682</a></td>
Expand Down

0 comments on commit 92f4bf2

Please sign in to comment.