================
@@ -2103,6 +2103,91 @@ static bool isOneByteCharacterType(QualType T) {
   return T->isCharType() || T->isChar8Type();
 }
 
+static bool interp__builtin_load8(InterpState &S, CodePtr OpPC,
+                                  const InterpFrame *Frame,
+                                  const CallExpr *Call, bool IsBigEndian,
+                                  bool IsAligned) {
+  Pointer Ptr = S.Stk.pop<Pointer>();
+
+  if (Ptr.isZero()) {
+    S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_null)
+        << AK_Read;
+    return false;
+  }
+
+  if (!isReadable(Ptr) && !Ptr.isOnePastEnd())
+    return false;
+
+  if (IsAligned) {
+    CharUnits RequiredAlign =
+        S.getASTContext().getTypeAlignInChars(Call->getType());
+    APValue AV = Ptr.toAPValue(S.getASTContext());
+    CharUnits BaseAlignment =
+        GetBaseAlignment(S.getASTContext(), AV.getLValueBase());
+    CharUnits PtrAlign = BaseAlignment.alignmentAtOffset(AV.getLValueOffset());
+    if (PtrAlign < RequiredAlign) {
+      S.FFDiag(S.Current->getSource(OpPC), 
diag::note_constexpr_load8_unaligned)
+          << S.getASTContext().BuiltinInfo.getQuotedName(
+                 Call->getBuiltinCallee())
+          << RequiredAlign.getQuantity() << PtrAlign.getQuantity();
+      return false;
+    }
+  }
+
+  // A string pointer has no Descriptor; treat it as an array of its
+  // character type.
+  bool IsArray;
+  QualType ElemTy;
+  if (Ptr.isStringPointer()) {
+    IsArray = true;
+    ElemTy = getElemType(Ptr);
+  } else {
+    const Descriptor *Desc = Ptr.getFieldDesc();
+    IsArray = Desc->isArray();
+    ElemTy = IsArray ? Desc->getElemQualType() : Desc->getType();
+  }
+
+  if (IsArray)
+    Ptr = Ptr.expand();
----------------
chaitanyav wrote:

Added tests  in `clang/test/Sema/constexpr-builtin-stdc-load8.c`:

- Array of structs: `struct_arr_fail` and `struct_arr_n8_fail` (L122-L125)
- Union: `union_n8_fail` (L223)

Both interpreters reject them.

```
np4.c:5:33: error: constexpr variable 'struct_arr_fail' must be initialized by 
a constant expression
np4.c:5:68: note: this conversion is not allowed in a constant expression
    5 | constexpr __UINT_LEAST32_TYPE__ struct_arr_fail = 
stdc_load8_leu32((const unsigned char *)non_char_arr);
      |                                                                    ^
np4.c:6:32: error: constexpr variable 'struct_arr_n8_fail' must be initialized 
by a constant expression
np4.c:6:69: note: this conversion is not allowed in a constant expression
    6 | constexpr __UINT_LEAST8_TYPE__ struct_arr_n8_fail = 
stdc_load8_leu8((const unsigned char *)non_char_arr);
      |                                                                     ^
np4.c:9:32: error: constexpr variable 'union_n8_fail' must be initialized by a 
constant expression
np4.c:9:64: note: this conversion is not allowed in a constant expression
    9 | constexpr __UINT_LEAST8_TYPE__ union_n8_fail = stdc_load8_leu8((const 
unsigned char *)&field_u);
      |                                                                ^

```

```
np4.c:5:33: error: constexpr variable 'struct_arr_fail' must be initialized by 
a constant expression
    5 | constexpr __UINT_LEAST32_TYPE__ struct_arr_fail = 
stdc_load8_leu32((const unsigned char *)non_char_arr);
      |                                 ^                 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
np4.c:5:68: note: this conversion is not allowed in a constant expression
    5 | constexpr __UINT_LEAST32_TYPE__ struct_arr_fail = 
stdc_load8_leu32((const unsigned char *)non_char_arr);
      |                                                                    
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
np4.c:6:32: error: constexpr variable 'struct_arr_n8_fail' must be initialized 
by a constant expression
    6 | constexpr __UINT_LEAST8_TYPE__ struct_arr_n8_fail = 
stdc_load8_leu8((const unsigned char *)non_char_arr);
      |                                ^                    
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
np4.c:6:69: note: this conversion is not allowed in a constant expression
    6 | constexpr __UINT_LEAST8_TYPE__ struct_arr_n8_fail = 
stdc_load8_leu8((const unsigned char *)non_char_arr);
      |                                                                     
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
np4.c:9:32: error: constexpr variable 'union_n8_fail' must be initialized by a 
constant expression
    9 | constexpr __UINT_LEAST8_TYPE__ union_n8_fail = stdc_load8_leu8((const 
unsigned char *)&field_u);
      |                                ^               
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
np4.c:9:64: note: this conversion is not allowed in a constant expression
    9 | constexpr __UINT_LEAST8_TYPE__ union_n8_fail = stdc_load8_leu8((const 
unsigned char *)&field_u);
      |                                                                
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 errors generated.
```

https://github.com/llvm/llvm-project/pull/203666
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to