llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

We need to recurse once more here and move the array case into the bigger if 
chain.

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


3 Files Affected:

- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+33-31) 
- (modified) clang/lib/AST/ByteCode/Compiler.h (+1-1) 
- (modified) clang/test/AST/ByteCode/cxx20.cpp (+25) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 3524ab5f86de8..6c846c01fc848 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3650,7 +3650,7 @@ bool Compiler<Emitter>::VisitCXXUuidofExpr(const 
CXXUuidofExpr *E) {
 
   assert(V.isStruct());
   assert(V.getStructNumBases() == 0);
-  if (!this->visitAPValueInitializer(V, E))
+  if (!this->visitAPValueInitializer(V, E, E->getType()))
     return false;
 
   return this->emitFinishInit(E);
@@ -4637,48 +4637,27 @@ bool Compiler<Emitter>::visitAPValue(const APValue 
&Val, PrimType ValType,
 
 template <class Emitter>
 bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val,
-                                                const Expr *E) {
-
+                                                const Expr *E, QualType T) {
   if (Val.isStruct()) {
-    const Record *R = this->getRecord(E->getType());
+    const Record *R = this->getRecord(T);
     assert(R);
     for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
       const APValue &F = Val.getStructField(I);
       const Record::Field *RF = R->getField(I);
+      QualType FieldType = RF->Decl->getType();
 
-      if (F.isInt() || F.isFloat() || F.isLValue() || F.isMemberPointer()) {
-        PrimType T = classifyPrim(RF->Decl->getType());
-        if (!this->visitAPValue(F, T, E))
-          return false;
-        if (!this->emitInitField(T, RF->Offset, E))
-          return false;
-      } else if (F.isArray()) {
-        assert(RF->Desc->isPrimitiveArray());
-        const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
-        PrimType ElemT = classifyPrim(ArrType->getElementType());
-        assert(ArrType);
-
-        if (!this->emitGetPtrField(RF->Offset, E))
+      if (std::optional<PrimType> PT = classify(FieldType)) {
+        if (!this->visitAPValue(F, *PT, E))
           return false;
-
-        for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) {
-          if (!this->visitAPValue(F.getArrayInitializedElt(A), ElemT, E))
-            return false;
-          if (!this->emitInitElem(ElemT, A, E))
-            return false;
-        }
-
-        if (!this->emitPopPtr(E))
+        if (!this->emitInitField(*PT, RF->Offset, E))
           return false;
-      } else if (F.isStruct() || F.isUnion()) {
+      } else {
         if (!this->emitGetPtrField(RF->Offset, E))
           return false;
-        if (!this->visitAPValueInitializer(F, E))
+        if (!this->visitAPValueInitializer(F, E, FieldType))
           return false;
         if (!this->emitPopPtr(E))
           return false;
-      } else {
-        assert(false && "I don't think this should be possible");
       }
     }
     return true;
@@ -4692,6 +4671,28 @@ bool Compiler<Emitter>::visitAPValueInitializer(const 
APValue &Val,
     if (!this->visitAPValue(F, T, E))
       return false;
     return this->emitInitField(T, RF->Offset, E);
+  } else if (Val.isArray()) {
+    const auto *ArrType = T->getAsArrayTypeUnsafe();
+    QualType ElemType = ArrType->getElementType();
+    for (unsigned A = 0, AN = Val.getArraySize(); A != AN; ++A) {
+      const APValue &Elem = Val.getArrayInitializedElt(A);
+      if (std::optional<PrimType> ElemT = classify(ElemType)) {
+        if (!this->visitAPValue(Elem, *ElemT, E))
+          return false;
+        if (!this->emitInitElem(*ElemT, A, E))
+          return false;
+      } else {
+        if (!this->emitConstUint32(A, E))
+          return false;
+        if (!this->emitArrayElemPtrUint32(E))
+          return false;
+        if (!this->visitAPValueInitializer(Elem, E, ElemType))
+          return false;
+        if (!this->emitPopPtr(E))
+          return false;
+      }
+    }
+    return true;
   }
   // TODO: Other types.
 
@@ -6374,7 +6375,8 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, 
const Expr *E) {
           return false;
         return this->emitInitGlobal(*T, *Index, E);
       }
-      return this->visitAPValueInitializer(TPOD->getValue(), E);
+      return this->visitAPValueInitializer(TPOD->getValue(), E,
+                                           TPOD->getType());
     }
     return false;
   }
diff --git a/clang/lib/AST/ByteCode/Compiler.h 
b/clang/lib/AST/ByteCode/Compiler.h
index 902da8ffdd330..256e917728886 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -290,7 +290,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, 
bool>,
   VarCreationState visitDecl(const VarDecl *VD);
   /// Visit an APValue.
   bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E);
-  bool visitAPValueInitializer(const APValue &Val, const Expr *E);
+  bool visitAPValueInitializer(const APValue &Val, const Expr *E, QualType T);
   /// Visit the given decl as if we have a reference to it.
   bool visitDeclRef(const ValueDecl *D, const Expr *E);
 
diff --git a/clang/test/AST/ByteCode/cxx20.cpp 
b/clang/test/AST/ByteCode/cxx20.cpp
index 06501de64916a..42e6ae33e92e4 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -964,3 +964,28 @@ namespace PseudoDtor {
   static_assert(f3() == 0);
 #endif
 }
+
+namespace NastyChar {
+  struct nasty_char {
+    template <typename T> friend auto operator<=>(T, T) = delete;
+    template <typename T> friend void operator+(T &&) = delete;
+    template <typename T> friend void operator-(T &&) = delete;
+    template <typename T> friend void operator&(T &&) = delete;
+
+    char c;
+  };
+
+
+  template <unsigned N> struct ToNastyChar {
+    constexpr ToNastyChar(const char (&r)[N]) {
+      for (unsigned I = 0; I != N; ++I)
+        text[I] = nasty_char{r[I]};
+    }
+    nasty_char text[N];
+  };
+
+  template <unsigned N> ToNastyChar(const char (&)[N]) -> ToNastyChar<N>;
+
+  template <ToNastyChar t> constexpr auto to_nasty_char() { return t; }
+  constexpr auto result = to_nasty_char<"12345">();
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/131983
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to