PR51105: look through ConstantExpr when looking for a braced string literal initializ...
authorRichard Smith <richard@metafoo.co.uk>
Wed, 25 Aug 2021 18:01:45 +0000 (11:01 -0700)
committerRichard Smith <richard@metafoo.co.uk>
Wed, 25 Aug 2021 18:36:11 +0000 (11:36 -0700)
clang/lib/AST/Expr.cpp
clang/lib/AST/ExprConstant.cpp
clang/lib/Sema/SemaInit.cpp
clang/test/CodeGenCXX/const-init.cpp

index 11f10d4..3173393 100644 (file)
@@ -2308,7 +2308,7 @@ bool InitListExpr::isStringLiteralInit() const {
   const Expr *Init = getInit(0);
   if (!Init)
     return false;
-  Init = Init->IgnoreParens();
+  Init = Init->IgnoreParenImpCasts();
   return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init);
 }
 
index f49a144..a3879db 100644 (file)
@@ -10473,13 +10473,17 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E,
   // C++11 [dcl.init.string]p1: A char array [...] can be initialized by [...]
   // an appropriately-typed string literal enclosed in braces.
   if (E->isStringLiteralInit()) {
-    auto *SL = dyn_cast<StringLiteral>(E->getInit(0)->IgnoreParens());
+    auto *SL = dyn_cast<StringLiteral>(E->getInit(0)->IgnoreParenImpCasts());
     // FIXME: Support ObjCEncodeExpr here once we support it in
     // ArrayExprEvaluator generally.
     if (!SL)
       return Error(E);
     return VisitStringLiteral(SL, AllocType);
   }
+  // Any other transparent list init will need proper handling of the
+  // AllocType; we can't just recurse to the inner initializer.
+  assert(!E->isTransparent() &&
+         "transparent array list initialization is not string literal init?");
 
   bool Success = true;
 
index 78574e3..111d93b 100644 (file)
@@ -2899,7 +2899,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
     // We're modifying a string literal init; we have to decompose the string
     // so we can modify the individual characters.
     ASTContext &Context = SemaRef.Context;
-    Expr *SubExpr = StructuredList->getInit(0)->IgnoreParens();
+    Expr *SubExpr = StructuredList->getInit(0)->IgnoreParenImpCasts();
 
     // Compute the character type
     QualType CharTy = AT->getElementType();
index f5c9dae..ca53db0 100644 (file)
@@ -84,6 +84,13 @@ int arr[2];
 // CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*)
 int &pastEnd = arr[2];
 
+// CHECK: @[[WCHAR_STR:.*]] = internal global [2 x i32] [i32 112, i32 0],
+// CHECK: @PR51105_a = global i32* {{.*}} @[[WCHAR_STR]],
+wchar_t *PR51105_a = (wchar_t[2]){ (L"p") };
+// CHECK: @[[CHAR_STR:.*]] = internal global [5 x i8] c"p\00\00\00\00",
+// CHECK: @PR51105_b = global i8* {{.*}} @[[CHAR_STR]],
+char *PR51105_b = (char [5]){ ("p") };
+
 struct X {
   long n : 8;
 };