Skip to content

[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

Merged
merged 3 commits into from
Oct 30, 2023

Conversation

nickdesaulniers
Copy link
Member

@nickdesaulniers nickdesaulniers commented Oct 26, 2023

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

…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'
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Oct 26, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 26, 2023

@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Nick Desaulniers (nickdesaulniers)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/70366.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+3)
  • (modified) clang/test/CodeGenCXX/const-init-cxx11.cpp (+6)
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)

@@ -1358,6 +1359,8 @@ class ConstExprEmitter :
}

llvm::Constant *VisitStringLiteral(StringLiteral *E, QualType T) {
if (!isa<ConstantArrayType>(T.getDesugaredType(CGM.getContext())))
Copy link
Member Author

@nickdesaulniers nickdesaulniers Oct 26, 2023

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 ?

@efriedma-quic
Copy link
Collaborator

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().)

@nickdesaulniers nickdesaulniers changed the title [CGExprConstant] stop evaluating StringLiterals for non-ConstantArrayTypes [CGExprConstant] stop calling into ConstExprEmitter for Reference type destinations Oct 27, 2023
@nickdesaulniers
Copy link
Member Author

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

Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@nickdesaulniers nickdesaulniers merged commit d9b15b0 into llvm:main Oct 30, 2023
@nickdesaulniers nickdesaulniers deleted the const_string_literal branch October 30, 2023 15:48
@berolinux
Copy link

Might be good to backport this to 17.x, given the regression was introduced on the 17 branch after 17.0.0

@nickdesaulniers
Copy link
Member Author

Might be good to backport this to 17.x, given the regression was introduced on the 17 branch after 17.0.0

llvm/llvm-project-release-prs#765

tru pushed a commit that referenced this pull request Nov 13, 2023
…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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Assertion `AllowOversized && "Elems are oversized"' failed.
4 participants