[clang] [CGExprConstant] stop evaluating StringLiterals for non-ConstantArrayTypes (PR #70366)
Nick Desaulniers via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 27 13:48:44 PDT 2023
https://github.com/nickdesaulniers updated https://github.com/llvm/llvm-project/pull/70366
>From 52e5c1083f82c045dc0af26badf159e8b1593bd1 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 26 Oct 2023 11:11:29 -0700
Subject: [PATCH 1/2] [CGExprConstant] stop evaluating StringLiterals for
non-ConstantArrayTypes
Fixes a bug introduced by
commit b54294e2c959 ("[clang][ConstantEmitter] have tryEmitPrivate[ForVarInit] try ConstExprEmitter fast-path first")
In the added test case, the QualType is a LValueReferenceType.
LValueReferenceType 0x558412998d90 'const char (&)[41]'
`-ParenType 0x558412998d30 'const char[41]' sugar
`-ConstantArrayType 0x558412998cf0 'const char[41]' 41
`-QualType 0x55841294c271 'const char' const
`-BuiltinType 0x55841294c270 'char'
---
clang/lib/CodeGen/CGExprConstant.cpp | 3 +++
clang/test/CodeGenCXX/const-init-cxx11.cpp | 6 ++++++
2 files changed, 9 insertions(+)
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 9b67a8b3335a165..0706647bf45466d 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/Builtins.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
@@ -1358,6 +1359,8 @@ class ConstExprEmitter :
}
llvm::Constant *VisitStringLiteral(StringLiteral *E, QualType T) {
+ if (!isa<ConstantArrayType>(T.getDesugaredType(CGM.getContext())))
+ return nullptr;
// This is a string literal initializing an array in an initializer.
return CGM.GetConstantArrayFromStringLiteral(E);
}
diff --git a/clang/test/CodeGenCXX/const-init-cxx11.cpp b/clang/test/CodeGenCXX/const-init-cxx11.cpp
index d22d78d2b94edb5..3a12fe444f137bf 100644
--- a/clang/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/clang/test/CodeGenCXX/const-init-cxx11.cpp
@@ -424,6 +424,8 @@ namespace DR2126 {
// CHECK: @_ZN33ClassTemplateWithStaticDataMember3useE ={{.*}} constant ptr @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_
// CHECK: @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_ = linkonce_odr hidden constant i32 5, comdat
// CHECK: @_ZN39ClassTemplateWithHiddenStaticDataMember3useE ={{.*}} constant ptr @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_
+// CHECK: @.str.[[STR:[0-9]+]] ={{.*}} constant [9 x i8] c"12345678\00"
+// CHECK-NEXT: @e = global %struct.PR69979 { ptr @.str.[[STR]] }
// CHECK: @_ZGRZN20InlineStaticConstRef3funEvE1i_ = linkonce_odr constant i32 10, comdat
// CHECK20: @_ZZN12LocalVarInit4dtorEvE1a = internal constant {{.*}} i32 103
@@ -632,6 +634,10 @@ struct X {
const char *f() { return &X::p; }
}
+struct PR69979 {
+ const char (&d)[9];
+} e {"12345678"};
+
// VirtualMembers::TemplateClass::templateMethod() must be defined in this TU,
// not just declared.
// CHECK: define linkonce_odr void @_ZN14VirtualMembers13TemplateClassIiE14templateMethodEv(ptr {{[^,]*}} %this)
>From 4cff8f0f1cb4bba84f32d3953a5abfafd13c6b09 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Fri, 27 Oct 2023 13:47:28 -0700
Subject: [PATCH 2/2] skip calling into ConstExprEmitter for reference type
destinations instead
---
clang/lib/CodeGen/CGExprConstant.cpp | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 0706647bf45466d..7eb28ae4c4ff173 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1359,8 +1359,6 @@ class ConstExprEmitter :
}
llvm::Constant *VisitStringLiteral(StringLiteral *E, QualType T) {
- if (!isa<ConstantArrayType>(T.getDesugaredType(CGM.getContext())))
- return nullptr;
// This is a string literal initializing an array in an initializer.
return CGM.GetConstantArrayFromStringLiteral(E);
}
@@ -1778,9 +1776,10 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const Expr *E,
QualType destType) {
assert(!destType->isVoidType() && "can't emit a void constant");
- if (llvm::Constant *C =
- ConstExprEmitter(*this).Visit(const_cast<Expr *>(E), destType))
- return C;
+ if (!destType->isReferenceType())
+ if (llvm::Constant *C =
+ ConstExprEmitter(*this).Visit(const_cast<Expr *>(E), destType))
+ return C;
Expr::EvalResult Result;
More information about the cfe-commits
mailing list