@@ -243,7 +243,7 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC,
243
243
unsigned ID = Func->getBuiltinID ();
244
244
const Pointer &StrPtr = getParam<Pointer>(Frame, 0 );
245
245
246
- if (ID == Builtin::BIstrlen)
246
+ if (ID == Builtin::BIstrlen || ID == Builtin::BIwcslen )
247
247
diagnoseNonConstexprBuiltin (S, OpPC, ID);
248
248
249
249
if (!CheckArray (S, OpPC, StrPtr))
@@ -256,6 +256,12 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC,
256
256
return false ;
257
257
258
258
assert (StrPtr.getFieldDesc ()->isPrimitiveArray ());
259
+ unsigned ElemSize = StrPtr.getFieldDesc ()->getElemSize ();
260
+
261
+ if (ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) {
262
+ const ASTContext &AC = S.getASTContext ();
263
+ assert (ElemSize == AC.getTypeSizeInChars (AC.getWCharType ()).getQuantity ());
264
+ }
259
265
260
266
size_t Len = 0 ;
261
267
for (size_t I = StrPtr.getIndex ();; ++I, ++Len) {
@@ -264,7 +270,20 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC,
264
270
if (!CheckRange (S, OpPC, ElemPtr, AK_Read))
265
271
return false ;
266
272
267
- uint8_t Val = ElemPtr.deref <uint8_t >();
273
+ uint32_t Val;
274
+ switch (ElemSize) {
275
+ case 1 :
276
+ Val = ElemPtr.deref <uint8_t >();
277
+ break ;
278
+ case 2 :
279
+ Val = ElemPtr.deref <uint16_t >();
280
+ break ;
281
+ case 4 :
282
+ Val = ElemPtr.deref <uint32_t >();
283
+ break ;
284
+ default :
285
+ llvm_unreachable (" Unsupported char size" );
286
+ }
268
287
if (Val == 0 )
269
288
break ;
270
289
}
@@ -1859,6 +1878,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
1859
1878
break ;
1860
1879
case Builtin::BI__builtin_strlen:
1861
1880
case Builtin::BIstrlen:
1881
+ case Builtin::BI__builtin_wcslen:
1882
+ case Builtin::BIwcslen:
1862
1883
if (!interp__builtin_strlen (S, OpPC, Frame, F, Call))
1863
1884
return false ;
1864
1885
break ;
0 commit comments