[PATCH] D87561: [Sema] List conversion validate character array
Mark de Wever via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 12 09:44:53 PDT 2020
Mordante created this revision.
Mordante added reviewers: lvoufo, rsmith.
Mordante added a project: clang.
Mordante requested review of this revision.
The function `TryListConversion` didn't properly validate the following part of the standard:
Otherwise, if the parameter type is a character array [... ]
and the initializer list has a single element that is an
appropriately-typed string literal (8.5.2 [dcl.init.string]), the
implicit conversion sequence is the identity conversion.
This caused the following call to `f()` to be ambiguous.
void f(int(&&)[1]);
void f(unsigned(&&)[1]);
void g(unsigned i) {
f({i});
}
This issue only occurrs when the initializer list had one element.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D87561
Files:
clang/lib/Sema/SemaOverload.cpp
clang/test/CXX/drs/dr14xx.cpp
Index: clang/test/CXX/drs/dr14xx.cpp
===================================================================
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -334,6 +334,22 @@
X x;
X x2{x};
+
+ void f1(int);
+ void f1(std::initializer_list<long>);
+ void g1() { f1({42}); }
+
+ template <class T, class U>
+ struct Pair {
+ Pair(T, U);
+ };
+ struct String {
+ String(const char *);
+ };
+
+ void f2(Pair<const char *, const char *>);
+ void f2(std::initializer_list<String>);
+ void g2() { f2({"foo", "bar"}); }
} // dr_example
namespace nonaggregate {
@@ -379,6 +395,31 @@
struct Value { Value(Pair); Value(TwoPairs); };
void f() { Value{{{1,2},{3,4}}}; }
}
+ namespace NonAmbiguous {
+ // The original implementation made this case ambigious due to the special
+ // handling of one element initialization lists.
+ void f(int(&&)[1]);
+ void f(unsigned(&&)[1]);
+
+ void g(unsigned i) {
+ f({i});
+ }
+ } // namespace NonAmbiguous
+
+#if __cplusplus >= 201103L
+ namespace StringLiterals {
+ void f(const char[4]);
+ void f(const wchar_t[4]);
+ void f(const char16_t[4]);
+ void f(const char32_t[4]);
+ void g() {
+ f({"abc"}); // expected-warning {{braces around scalar initializer}}
+ f({L"abc"}); // expected-warning {{braces around scalar initializer}}
+ f({uR"(abc)"}); // expected-warning {{braces around scalar initializer}}
+ f({UR"(abc)"}); // expected-warning {{braces around scalar initializer}}
+ }
+ } // namespace StringLiterals
+#endif
} // dr1467
namespace dr1490 { // dr1490: 3.7 c++11
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -4984,12 +4984,12 @@
InOverloadResolution,
AllowObjCWritebackConversion);
}
- // FIXME: Check the other conditions here: array of character type,
- // initializer is a string literal.
- if (ToType->isArrayType()) {
+
+ if (ToType->isArrayType() && ToType->isCharType() &&
+ isa<StringLiteral>(From->getInit(0))) {
InitializedEntity Entity =
- InitializedEntity::InitializeParameter(S.Context, ToType,
- /*Consumed=*/false);
+ InitializedEntity::InitializeParameter(S.Context, ToType,
+ /*Consumed=*/false);
if (S.CanPerformCopyInitialization(Entity, From)) {
Result.setStandard();
Result.Standard.setAsIdentityConversion();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87561.291399.patch
Type: text/x-patch
Size: 2690 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200912/49b88db9/attachment.bin>
More information about the cfe-commits
mailing list