@@ -1862,10 +1862,10 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18621862 }
18631863
18641864 QualType ElemType;
1865- if (SrcPtr .getFieldDesc ()->isArray ())
1866- ElemType = SrcPtr .getFieldDesc ()->getElemQualType ();
1865+ if (DestPtr .getFieldDesc ()->isArray ())
1866+ ElemType = DestPtr .getFieldDesc ()->getElemQualType ();
18671867 else
1868- ElemType = SrcPtr .getType ();
1868+ ElemType = DestPtr .getType ();
18691869
18701870 unsigned ElemSize =
18711871 S.getASTContext ().getTypeSizeInChars (ElemType).getQuantity ();
@@ -1876,6 +1876,18 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18761876 return false ;
18771877 }
18781878
1879+ QualType SrcElemType;
1880+ if (SrcPtr.getFieldDesc ()->isArray ())
1881+ SrcElemType = SrcPtr.getFieldDesc ()->getElemQualType ();
1882+ else
1883+ SrcElemType = SrcPtr.getType ();
1884+
1885+ if (!S.getASTContext ().hasSameUnqualifiedType (ElemType, SrcElemType)) {
1886+ S.FFDiag (S.Current ->getSource (OpPC), diag::note_constexpr_memcpy_type_pun)
1887+ << Move << SrcElemType << ElemType;
1888+ return false ;
1889+ }
1890+
18791891 // Check for overlapping memory regions.
18801892 if (!Move && Pointer::pointToSameBlock (SrcPtr, DestPtr)) {
18811893 unsigned SrcIndex = SrcPtr.getIndex () * SrcPtr.elemSize ();
@@ -1893,8 +1905,8 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18931905 // As a last resort, reject dummy pointers.
18941906 if (DestPtr.isDummy () || SrcPtr.isDummy ())
18951907 return false ;
1896-
1897- if (!DoBitCastPtr (S, OpPC, SrcPtr, DestPtr, Size.getZExtValue ()))
1908+ assert (Size. getZExtValue () % ElemSize == 0 );
1909+ if (!DoMemcpy (S, OpPC, SrcPtr, DestPtr, Bytes ( Size.getZExtValue ()). toBits ()))
18981910 return false ;
18991911
19001912 S.Stk .push <Pointer>(DestPtr);
0 commit comments