@@ -243,7 +243,7 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC,
243243 unsigned ID = Func->getBuiltinID ();
244244 const Pointer &StrPtr = getParam<Pointer>(Frame, 0 );
245245
246- if (ID == Builtin::BIstrlen)
246+ if (ID == Builtin::BIstrlen || ID == Builtin::BIwcslen )
247247 diagnoseNonConstexprBuiltin (S, OpPC, ID);
248248
249249 if (!CheckArray (S, OpPC, StrPtr))
@@ -256,6 +256,12 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC,
256256 return false ;
257257
258258 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+ }
259265
260266 size_t Len = 0 ;
261267 for (size_t I = StrPtr.getIndex ();; ++I, ++Len) {
@@ -264,7 +270,20 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC,
264270 if (!CheckRange (S, OpPC, ElemPtr, AK_Read))
265271 return false ;
266272
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+ }
268287 if (Val == 0 )
269288 break ;
270289 }
@@ -1859,6 +1878,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
18591878 break ;
18601879 case Builtin::BI__builtin_strlen:
18611880 case Builtin::BIstrlen:
1881+ case Builtin::BI__builtin_wcslen:
1882+ case Builtin::BIwcslen:
18621883 if (!interp__builtin_strlen (S, OpPC, Frame, F, Call))
18631884 return false ;
18641885 break ;
0 commit comments