nickdesaulniers updated this revision to Diff 528605.
nickdesaulniers added a comment.
- use @efriedma's suggestion w/ dyn_cast
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151587/new/
https://reviews.llvm.org/D151587
Files:
clang/lib/CodeGen/CGExprConstant.cpp
clang/test/CodeGenCXX/const-init-cxx11.cpp
clang/test/CodeGenCXX/const-init-cxx1y.cpp
clang/test/CodeGenOpenCL/amdgpu-nullptr.cl
Index: clang/test/CodeGenOpenCL/amdgpu-nullptr.cl
===================================================================
--- clang/test/CodeGenOpenCL/amdgpu-nullptr.cl
+++ clang/test/CodeGenOpenCL/amdgpu-nullptr.cl
@@ -57,7 +57,7 @@
// CHECK: @fold_generic ={{.*}} local_unnamed_addr addrspace(1) global ptr null, align 8
generic int *fold_generic = (global int*)(generic float*)(private char*)0;
-// CHECK: @fold_priv ={{.*}} local_unnamed_addr addrspace(1) global ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5)), align 4
+// CHECK: @fold_priv ={{.*}} local_unnamed_addr addrspace(1) global ptr addrspace(5) addrspacecast (ptr addrspace(1) null to ptr addrspace(5)), align 4
private short *fold_priv = (private short*)(generic int*)(global void*)0;
// CHECK: @fold_priv_arith ={{.*}} local_unnamed_addr addrspace(1) global ptr addrspace(5) inttoptr (i32 9 to ptr addrspace(5)), align 4
Index: clang/test/CodeGenCXX/const-init-cxx1y.cpp
===================================================================
--- clang/test/CodeGenCXX/const-init-cxx1y.cpp
+++ clang/test/CodeGenCXX/const-init-cxx1y.cpp
@@ -34,8 +34,8 @@
// 'c.temporary', not the value as modified by the partial evaluation within
// the initialization of 'c.x'.
A c = { 10, (++c.temporary, b.x) };
- // CHECK: @_ZGRN21ModifyStaticTemporary1cE_ = internal global i32 10
// CHECK: @_ZN21ModifyStaticTemporary1cE ={{.*}} global {{.*}} zeroinitializer
+ // CHECK: @_ZGRN21ModifyStaticTemporary1cE_ = internal global i32 10
}
// CHECK: @_ZGRN28VariableTemplateWithConstRef1iIvEE_ = linkonce_odr constant i32 5, align 4
Index: clang/test/CodeGenCXX/const-init-cxx11.cpp
===================================================================
--- clang/test/CodeGenCXX/const-init-cxx11.cpp
+++ clang/test/CodeGenCXX/const-init-cxx11.cpp
@@ -88,7 +88,7 @@
struct E {};
struct Test2 : X<E,0>, X<E,1>, X<E,2>, X<E,3> {};
- // CHECK: @_ZN9BaseClass2t2E ={{.*}} constant {{.*}} undef
+ // CHECK: @_ZN9BaseClass2t2E ={{.*}} constant {{.*}} zeroinitializer, align 1
extern constexpr Test2 t2 = Test2();
struct __attribute((packed)) PackedD { double y = 2; };
Index: clang/lib/CodeGen/CGExprConstant.cpp
===================================================================
--- clang/lib/CodeGen/CGExprConstant.cpp
+++ clang/lib/CodeGen/CGExprConstant.cpp
@@ -910,6 +910,27 @@
.Build(Updater, /*AllowOverwrite*/ true);
}
+class HasAnyMaterializeTemporaryExpr :
+ public ConstStmtVisitor<HasAnyMaterializeTemporaryExpr, bool> {
+public:
+ bool VisitImplicitCastExpr(const ImplicitCastExpr *I) {
+ return Visit(I->getSubExpr());
+ }
+ bool VisitCXXConstructExpr(const CXXConstructExpr *C) {
+ return llvm::any_of(C->arguments(), [this](const Expr *A){
+ return Visit(A);
+ });
+ }
+ bool VisitInitListExpr(const InitListExpr *I) {
+ return llvm::any_of(I->inits(), [this](const Expr *II) {
+ return Visit(II);
+ });
+ }
+ bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *) {
+ return true;
+ }
+};
+
//===----------------------------------------------------------------------===//
// ConstExprEmitter
//===----------------------------------------------------------------------===//
@@ -1215,11 +1236,6 @@
return Visit(E->getSubExpr(), T);
}
- llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E,
- QualType T) {
- return Visit(E->getSubExpr(), T);
- }
-
llvm::Constant *EmitArrayInitialization(InitListExpr *ILE, QualType T) {
auto *CAT = CGM.getContext().getAsConstantArrayType(ILE->getType());
assert(CAT && "can't emit array init for non-constant-bound array");
@@ -1279,6 +1295,12 @@
if (ILE->isTransparent())
return Visit(ILE->getInit(0), T);
+ // If the InitListExpr contains a MaterializeTemporaryExpr recursively,
+ // bail...
+ HasAnyMaterializeTemporaryExpr H;
+ if (H.Visit(ILE))
+ return nullptr;
+
if (ILE->getType()->isArrayType())
return EmitArrayInitialization(ILE, T);
@@ -1322,7 +1344,12 @@
assert(CGM.getContext().hasSameUnqualifiedType(Ty, Arg->getType()) &&
"argument to copy ctor is of wrong type");
- return Visit(Arg, Ty);
+ // Look through the temporary; it's just converting the value to an
+ // lvalue to pass it to the constructor.
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
+ return Visit(MTE->getSubExpr(), Ty);
+ // Don't try to support arbitrary lvalue-to-rvalue conversions for now.
+ return nullptr;
}
return CGM.EmitNullConstant(Ty);
@@ -1655,27 +1682,27 @@
QualType destType = D.getType();
- // Try to emit the initializer. Note that this can allow some things that
- // are not allowed by tryEmitPrivateForMemory alone.
- if (APValue *value = D.evaluateValue())
- return tryEmitPrivateForMemory(*value, destType);
-
// FIXME: Implement C++11 [basic.start.init]p2: if the initializer of a
// reference is a constant expression, and the reference binds to a temporary,
// then constant initialization is performed. ConstExprEmitter will
// incorrectly emit a prvalue constant in this case, and the calling code
// interprets that as the (pointer) value of the reference, rather than the
// desired value of the referee.
- if (destType->isReferenceType())
- return nullptr;
const Expr *E = D.getInit();
assert(E && "No initializer to emit");
QualType nonMemoryDestType = getNonMemoryType(CGM, destType);
- if (llvm::Constant *C = ConstExprEmitter(*this).Visit(const_cast<Expr *>(E),
- nonMemoryDestType))
- return emitForMemory(C, destType);
+ if (!destType->isReferenceType())
+ if (llvm::Constant *C = ConstExprEmitter(*this).Visit(const_cast<Expr *>(E),
+ nonMemoryDestType))
+ return emitForMemory(C, destType);
+
+ // Try to emit the initializer. Note that this can allow some things that
+ // are not allowed by tryEmitPrivateForMemory alone.
+ if (APValue *value = D.evaluateValue())
+ return tryEmitPrivateForMemory(*value, destType);
+
return nullptr;
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits