[PATCH] D51855: [constexpr] Fix ICE when memcpy() is given a pointer to an incomplete array
Phabricator via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 4 02:27:28 PDT 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rL343761: [constexpr] Fix ICE when memcpy() is given a pointer to an incomplete array (authored by petr.pavlu, committed by ).
Herald added a subscriber: llvm-commits.
Changed prior to commit:
https://reviews.llvm.org/D51855?vs=166073&id=168244#toc
Repository:
rL LLVM
https://reviews.llvm.org/D51855
Files:
cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/CodeGen/builtin-memfns.c
cfe/trunk/test/SemaCXX/constexpr-string.cpp
Index: cfe/trunk/lib/AST/ExprConstant.cpp
===================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp
+++ cfe/trunk/lib/AST/ExprConstant.cpp
@@ -6239,6 +6239,10 @@
Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << SrcT << T;
return false;
}
+ if (T->isIncompleteType()) {
+ Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) << Move << T;
+ return false;
+ }
if (!T.isTriviallyCopyableType(Info.Ctx)) {
Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) << Move << T;
return false;
Index: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
===================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
@@ -173,6 +173,9 @@
def note_constexpr_memcpy_nontrivial : Note<
"cannot constant evaluate '%select{memcpy|memmove}0' between objects of "
"non-trivially-copyable type %1">;
+def note_constexpr_memcpy_incomplete_type : Note<
+ "cannot constant evaluate '%select{memcpy|memmove}0' between objects of "
+ "incomplete type %1">;
def note_constexpr_memcpy_overlap : Note<
"'%select{memcpy|wmemcpy}0' between overlapping memory regions">;
def note_constexpr_memcpy_unsupported : Note<
Index: cfe/trunk/test/SemaCXX/constexpr-string.cpp
===================================================================
--- cfe/trunk/test/SemaCXX/constexpr-string.cpp
+++ cfe/trunk/test/SemaCXX/constexpr-string.cpp
@@ -387,4 +387,41 @@
// designators until we have a long enough matching size, if both designators
// point to the start of their respective final elements.
static_assert(test_derived_to_base(2) == 3434); // expected-error {{constant}} expected-note {{in call}}
+
+ // Check that when address-of an array is passed to a tested function the
+ // array can be fully copied.
+ constexpr int test_address_of_const_array_type() {
+ int arr[4] = {1, 2, 3, 4};
+ __builtin_memmove(&arr, &arr, sizeof(arr));
+ return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3];
+ }
+ static_assert(test_address_of_const_array_type() == 1234);
+
+ // Check that an incomplete array is rejected.
+ constexpr int test_incomplete_array_type() { // expected-error {{never produces a constant}}
+ extern int arr[];
+ __builtin_memmove(arr, arr, 4 * sizeof(arr[0]));
+ // expected-note at -1 2{{'memmove' not supported: source is not a contiguous array of at least 4 elements of type 'int'}}
+ return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3];
+ }
+ static_assert(test_incomplete_array_type() == 1234); // expected-error {{constant}} expected-note {{in call}}
+
+ // Check that a pointer to an incomplete array is rejected.
+ constexpr int test_address_of_incomplete_array_type() { // expected-error {{never produces a constant}}
+ extern int arr[];
+ __builtin_memmove(&arr, &arr, 4 * sizeof(arr[0]));
+ // expected-note at -1 2{{cannot constant evaluate 'memmove' between objects of incomplete type 'int []'}}
+ return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3];
+ }
+ static_assert(test_address_of_incomplete_array_type() == 1234); // expected-error {{constant}} expected-note {{in call}}
+
+ // Check that a pointer to an incomplete struct is rejected.
+ constexpr bool test_address_of_incomplete_struct_type() { // expected-error {{never produces a constant}}
+ struct Incomplete;
+ extern Incomplete x, y;
+ __builtin_memcpy(&x, &x, 4);
+ // expected-note at -1 2{{cannot constant evaluate 'memcpy' between objects of incomplete type 'Incomplete'}}
+ return true;
+ }
+ static_assert(test_address_of_incomplete_struct_type()); // expected-error {{constant}} expected-note {{in call}}
}
Index: cfe/trunk/test/CodeGen/builtin-memfns.c
===================================================================
--- cfe/trunk/test/CodeGen/builtin-memfns.c
+++ cfe/trunk/test/CodeGen/builtin-memfns.c
@@ -111,3 +111,10 @@
memcpy(&d, (char *)&e.a, sizeof(e));
}
+// CHECK-LABEL: @test12
+extern char dest_array[];
+extern char src_array[];
+void test12() {
+ // CHECK: call void @llvm.memcpy{{.*}}(
+ memcpy(&dest_array, &dest_array, 2);
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51855.168244.patch
Type: text/x-patch
Size: 4262 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181004/16fb2cec/attachment.bin>
More information about the cfe-commits
mailing list