-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[CGExprConstant] stop calling into ConstExprEmitter for Reference type destinations #70366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CGExprConstant] stop calling into ConstExprEmitter for Reference type destinations #70366
Conversation
…Types Fixes a bug introduced by commit b54294e ("[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'
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Nick Desaulniers (nickdesaulniers) ChangesFixes a bug introduced by In the added test case, the QualType is a LValueReferenceType.
Fixes: #69979 Full diff: https://github.com/llvm/llvm-project/pull/70366.diff 2 Files Affected:
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)
|
clang/lib/CodeGen/CGExprConstant.cpp
Outdated
@@ -1358,6 +1359,8 @@ class ConstExprEmitter : | |||
} | |||
|
|||
llvm::Constant *VisitStringLiteral(StringLiteral *E, QualType T) { | |||
if (!isa<ConstantArrayType>(T.getDesugaredType(CGM.getContext()))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively this could be:
if (isa<LValueReferenceType>(T))
any preference/thoughts @efriedma-quic ?
I think I'd prefer to avoid calling into ConstExprEmitter at all for cases involving reference binding. I think we've sort of discussed this before. Maybe add a check to tryEmitPrivate()? (We already have a check in tryEmitPrivateForVarInit().) |
Done in 4cff8f0 PTAL @efriedma-quic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Might be good to backport this to 17.x, given the regression was introduced on the 17 branch after 17.0.0 |
|
…e destinations (#70366) Fixes a bug introduced by commit b54294e ("[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' Fixes: #69979 (cherry picked from commit d9b15b0)
Fixes a bug introduced by
commit b54294e ("[clang][ConstantEmitter] have tryEmitPrivate[ForVarInit] try ConstExprEmitter fast-path first")
In the added test case, the QualType is a LValueReferenceType.
Fixes: #69979