From b5890a329a08715f1974f5f46f1205f2ca1de41e Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 10 Sep 2019 19:16:56 +0000 Subject: [PATCH] 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. llvm-svn: 371548 --- clang/lib/CodeGen/CGExpr.cpp | 5 +++++ clang/test/OpenMP/constexpr_partial_array.cpp | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 clang/test/OpenMP/constexpr_partial_array.cpp diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 6cabfcc..cf6dfbe 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/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/clang/test/OpenMP/constexpr_partial_array.cpp b/clang/test/OpenMP/constexpr_partial_array.cpp new file mode 100644 index 0000000..998d75e --- /dev/null +++ b/clang/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]; +} -- 2.7.4