[PATCH] D131555: [Clang] Propagate const context info when emitting compound literal

Ties Stuij via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 10 03:16:58 PDT 2022


stuij created this revision.
Herald added a project: All.
stuij requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch fixes a crash when trying to emit a constant compound literal.

For C++ Clang evaluates either casts or binary operations at translation time,
but doesn't pass on the InConstantContext information that was inferred when
parsing the statement.  Because of this, strict FP evaluation (-ftrapping-math)
which should be in effect yet, then causes checkFloatingpointResult to return
false, which in tryEmitGlobalCompoundLiteral will trigger an assert that the
compound literal wasn't constant.

The discussion here around 'manifestly constant evaluated contexts' was very
helpful to me when trying to understand what LLVM's position is on what
evaluation context should be in effect, together with the explanatory text in
that patch itself:
https://reviews.llvm.org/D87528


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131555

Files:
  clang/lib/CodeGen/CGExprConstant.cpp
  clang/lib/CodeGen/ConstantEmitter.h
  clang/test/CodeGen/const-init.c


Index: clang/test/CodeGen/const-init.c
===================================================================
--- clang/test/CodeGen/const-init.c
+++ clang/test/CodeGen/const-init.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -triple i386-pc-linux-gnu -ffreestanding -Wno-pointer-to-int-cast -Wno-int-conversion -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -no-opaque-pointers -triple i386-pc-linux-gnu -ffreestanding -Wno-pointer-to-int-cast -Wno-int-conversion -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s
 
 #include <stdint.h>
 
@@ -181,3 +181,7 @@
 #pragma pack()
   // CHECK: @g31.a = internal global %struct.anon.2 { i16 23122, i32 -12312731, i16 -312 }, align 4
 }
+
+struct { const float *floats; } compoundliteral = {
+  (float[1]) { 0.1, },
+};
Index: clang/lib/CodeGen/ConstantEmitter.h
===================================================================
--- clang/lib/CodeGen/ConstantEmitter.h
+++ clang/lib/CodeGen/ConstantEmitter.h
@@ -67,6 +67,9 @@
     return Abstract;
   }
 
+  bool isInConstantContext() const { return InConstantContext; }
+  void setInConstantContext(bool var) { InConstantContext = var; }
+
   /// Try to emit the initiaizer of the given declaration as an abstract
   /// constant.  If this succeeds, the emission must be finalized.
   llvm::Constant *tryEmitForInitializer(const VarDecl &D);
Index: clang/lib/CodeGen/CGExprConstant.cpp
===================================================================
--- clang/lib/CodeGen/CGExprConstant.cpp
+++ clang/lib/CodeGen/CGExprConstant.cpp
@@ -913,17 +913,15 @@
 //                             ConstExprEmitter
 //===----------------------------------------------------------------------===//
 
-static ConstantAddress tryEmitGlobalCompoundLiteral(CodeGenModule &CGM,
-                                                    CodeGenFunction *CGF,
+static ConstantAddress tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter,
                                               const CompoundLiteralExpr *E) {
+  CodeGenModule &CGM = emitter.CGM;
   CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
   if (llvm::GlobalVariable *Addr =
           CGM.getAddrOfConstantCompoundLiteralIfEmitted(E))
     return ConstantAddress(Addr, Addr->getValueType(), Align);
 
   LangAS addressSpace = E->getType().getAddressSpace();
-
-  ConstantEmitter emitter(CGM, CGF);
   llvm::Constant *C = emitter.tryEmitForInitializer(E->getInitializer(),
                                                     addressSpace, E->getType());
   if (!C) {
@@ -1970,7 +1968,9 @@
 
 ConstantLValue
 ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
-  return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E);
+  ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.CGF);
+  CompoundLiteralEmitter.setInConstantContext(Emitter.isInConstantContext());
+  return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter, E);
 }
 
 ConstantLValue
@@ -2214,7 +2214,8 @@
 ConstantAddress
 CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
   assert(E->isFileScope() && "not a file-scope compound literal expr");
-  return tryEmitGlobalCompoundLiteral(*this, nullptr, E);
+  ConstantEmitter emitter(*this, nullptr);
+  return tryEmitGlobalCompoundLiteral(emitter, E);
 }
 
 llvm::Constant *


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D131555.451405.patch
Type: text/x-patch
Size: 3345 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220810/d40d6e59/attachment.bin>


More information about the cfe-commits mailing list