summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-09-10 19:16:56 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-09-10 19:16:56 +0000
commit744ff96f70c6261a92dc496d34310f182e9c27d0 (patch)
treec32266b1026f18eaac8f7ca3852e7b00a1a4f0ec
parente7a3af41563dec471f37e5c2b4a74d206b5865f1 (diff)
downloadclang-744ff96f70c6261a92dc496d34310f182e9c27d0.tar.gz
Fix for PR43175: compiler crash when trying to emit noncapturable
constant. If the constexpr variable is partially initialized, the initializer can be emitted as the structure, not as an array, because of some early optimizations. The llvm variable gets the type from this constant and, thus, gets the type which is pointer to struct rather than pointer to an array. We need to convert this type to be truely array, otherwise it may lead to the compiler crash when trying to emit array subscript expression. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@371548 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGExpr.cpp5
-rw-r--r--test/OpenMP/constexpr_partial_array.cpp10
2 files changed, 15 insertions, 0 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 6cabfccf3a..cf6dfbe76b 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -2539,6 +2539,11 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// Spill the constant value to a global.
Addr = CGM.createUnnamedGlobalFrom(*VD, Val,
getContext().getDeclAlign(VD));
+ llvm::Type *VarTy = getTypes().ConvertTypeForMem(VD->getType());
+ auto *PTy = llvm::PointerType::get(
+ VarTy, getContext().getTargetAddressSpace(VD->getType()));
+ if (PTy != Addr.getType())
+ Addr = Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, PTy);
} else {
// Should we be using the alignment of the constant pointer we emitted?
CharUnits Alignment =
diff --git a/test/OpenMP/constexpr_partial_array.cpp b/test/OpenMP/constexpr_partial_array.cpp
new file mode 100644
index 0000000000..998d75edbb
--- /dev/null
+++ b/test/OpenMP/constexpr_partial_array.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -verify -triple x86_64-pc-windows-msvc19.22.27905 -emit-llvm -o - -fopenmp %s | FileCheck %s
+// expected-no-diagnostics
+
+// CHECK: [[C_VAR_VAL:@.+]] = private unnamed_addr constant <{ i8, [26 x i8] }> <{ i8 1, [26 x i8] zeroinitializer }>,
+char a;
+bool b() {
+ static constexpr bool c[27]{1};
+ // CHECK: getelementptr inbounds [27 x i8], [27 x i8]* bitcast (<{ i8, [26 x i8] }>* [[C_VAR_VAL]] to [27 x i8]*),
+ return c[a];
+}