@@ -319,6 +319,25 @@ namespace {
319
319
return false ;
320
320
}
321
321
322
+ // / Get the range of valid index adjustments in the form
323
+ // / {maximum value that can be subtracted from this pointer,
324
+ // / maximum value that can be added to this pointer}
325
+ std::pair<uint64_t , uint64_t > validIndexAdjustments () {
326
+ if (Invalid || isMostDerivedAnUnsizedArray ())
327
+ return {0 , 0 };
328
+
329
+ // [expr.add]p4: For the purposes of these operators, a pointer to a
330
+ // nonarray object behaves the same as a pointer to the first element of
331
+ // an array of length one with the type of the object as its element type.
332
+ bool IsArray = MostDerivedPathLength == Entries.size () &&
333
+ MostDerivedIsArrayElement;
334
+ uint64_t ArrayIndex =
335
+ IsArray ? Entries.back ().ArrayIndex : (uint64_t )IsOnePastTheEnd;
336
+ uint64_t ArraySize =
337
+ IsArray ? getMostDerivedArraySize () : (uint64_t )1 ;
338
+ return {ArrayIndex, ArraySize - ArrayIndex};
339
+ }
340
+
322
341
// / Check that this refers to a valid subobject.
323
342
bool isValidSubobject () const {
324
343
if (Invalid)
@@ -329,6 +348,14 @@ namespace {
329
348
// / relevant diagnostic and set the designator as invalid.
330
349
bool checkSubobject (EvalInfo &Info, const Expr *E, CheckSubobjectKind CSK);
331
350
351
+ // / Get the type of the designated object.
352
+ QualType getType (ASTContext &Ctx) const {
353
+ assert (!Invalid && " invalid designator has no subobject type" );
354
+ return MostDerivedPathLength == Entries.size ()
355
+ ? MostDerivedType
356
+ : Ctx.getRecordType (getAsBaseClass (Entries.back ()));
357
+ }
358
+
332
359
// / Update this designator to refer to the first element within this array.
333
360
void addArrayUnchecked (const ConstantArrayType *CAT) {
334
361
PathEntry Entry;
@@ -1706,6 +1733,54 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
1706
1733
}
1707
1734
}
1708
1735
1736
+ static const ValueDecl *GetLValueBaseDecl (const LValue &LVal) {
1737
+ return LVal.Base .dyn_cast <const ValueDecl*>();
1738
+ }
1739
+
1740
+ static bool IsLiteralLValue (const LValue &Value) {
1741
+ if (Value.getLValueCallIndex ())
1742
+ return false ;
1743
+ const Expr *E = Value.Base .dyn_cast <const Expr*>();
1744
+ return E && !isa<MaterializeTemporaryExpr>(E);
1745
+ }
1746
+
1747
+ static bool IsWeakLValue (const LValue &Value) {
1748
+ const ValueDecl *Decl = GetLValueBaseDecl (Value);
1749
+ return Decl && Decl->isWeak ();
1750
+ }
1751
+
1752
+ static bool isZeroSized (const LValue &Value) {
1753
+ const ValueDecl *Decl = GetLValueBaseDecl (Value);
1754
+ if (Decl && isa<VarDecl>(Decl)) {
1755
+ QualType Ty = Decl->getType ();
1756
+ if (Ty->isArrayType ())
1757
+ return Ty->isIncompleteType () ||
1758
+ Decl->getASTContext ().getTypeSize (Ty) == 0 ;
1759
+ }
1760
+ return false ;
1761
+ }
1762
+
1763
+ static bool HasSameBase (const LValue &A, const LValue &B) {
1764
+ if (!A.getLValueBase ())
1765
+ return !B.getLValueBase ();
1766
+ if (!B.getLValueBase ())
1767
+ return false ;
1768
+
1769
+ if (A.getLValueBase ().getOpaqueValue () !=
1770
+ B.getLValueBase ().getOpaqueValue ()) {
1771
+ const Decl *ADecl = GetLValueBaseDecl (A);
1772
+ if (!ADecl)
1773
+ return false ;
1774
+ const Decl *BDecl = GetLValueBaseDecl (B);
1775
+ if (!BDecl || ADecl->getCanonicalDecl () != BDecl->getCanonicalDecl ())
1776
+ return false ;
1777
+ }
1778
+
1779
+ return IsGlobalLValue (A.getLValueBase ()) ||
1780
+ (A.getLValueCallIndex () == B.getLValueCallIndex () &&
1781
+ A.getLValueVersion () == B.getLValueVersion ());
1782
+ }
1783
+
1709
1784
static void NoteLValueLocation (EvalInfo &Info, APValue::LValueBase Base) {
1710
1785
assert (Base && " no location for a null lvalue" );
1711
1786
const ValueDecl *VD = Base.dyn_cast <const ValueDecl*>();
@@ -1917,33 +1992,6 @@ CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type,
1917
1992
return true ;
1918
1993
}
1919
1994
1920
- static const ValueDecl *GetLValueBaseDecl (const LValue &LVal) {
1921
- return LVal.Base .dyn_cast <const ValueDecl*>();
1922
- }
1923
-
1924
- static bool IsLiteralLValue (const LValue &Value) {
1925
- if (Value.getLValueCallIndex ())
1926
- return false ;
1927
- const Expr *E = Value.Base .dyn_cast <const Expr*>();
1928
- return E && !isa<MaterializeTemporaryExpr>(E);
1929
- }
1930
-
1931
- static bool IsWeakLValue (const LValue &Value) {
1932
- const ValueDecl *Decl = GetLValueBaseDecl (Value);
1933
- return Decl && Decl->isWeak ();
1934
- }
1935
-
1936
- static bool isZeroSized (const LValue &Value) {
1937
- const ValueDecl *Decl = GetLValueBaseDecl (Value);
1938
- if (Decl && isa<VarDecl>(Decl)) {
1939
- QualType Ty = Decl->getType ();
1940
- if (Ty->isArrayType ())
1941
- return Ty->isIncompleteType () ||
1942
- Decl->getASTContext ().getTypeSize (Ty) == 0 ;
1943
- }
1944
- return false ;
1945
- }
1946
-
1947
1995
static bool EvalPointerValueAsBool (const APValue &Value, bool &Result) {
1948
1996
// A null base expression indicates a null pointer. These are always
1949
1997
// evaluatable, and they are false unless the offset is zero.
@@ -6117,6 +6165,130 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
6117
6165
return ZeroInitialization (E);
6118
6166
}
6119
6167
6168
+ case Builtin::BImemcpy:
6169
+ case Builtin::BImemmove:
6170
+ case Builtin::BIwmemcpy:
6171
+ case Builtin::BIwmemmove:
6172
+ if (Info.getLangOpts ().CPlusPlus11 )
6173
+ Info.CCEDiag (E, diag::note_constexpr_invalid_function)
6174
+ << /* isConstexpr*/ 0 << /* isConstructor*/ 0
6175
+ << (std::string (" '" ) + Info.Ctx .BuiltinInfo .getName (BuiltinOp) + " '" );
6176
+ else
6177
+ Info.CCEDiag (E, diag::note_invalid_subexpr_in_const_expr);
6178
+ LLVM_FALLTHROUGH;
6179
+ case Builtin::BI__builtin_memcpy:
6180
+ case Builtin::BI__builtin_memmove:
6181
+ case Builtin::BI__builtin_wmemcpy:
6182
+ case Builtin::BI__builtin_wmemmove: {
6183
+ bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
6184
+ BuiltinOp == Builtin::BIwmemmove ||
6185
+ BuiltinOp == Builtin::BI__builtin_wmemcpy ||
6186
+ BuiltinOp == Builtin::BI__builtin_wmemmove;
6187
+ bool Move = BuiltinOp == Builtin::BImemmove ||
6188
+ BuiltinOp == Builtin::BIwmemmove ||
6189
+ BuiltinOp == Builtin::BI__builtin_memmove ||
6190
+ BuiltinOp == Builtin::BI__builtin_wmemmove;
6191
+
6192
+ // The result of mem* is the first argument.
6193
+ if (!Visit (E->getArg (0 )) || Result.Designator .Invalid )
6194
+ return false ;
6195
+ LValue Dest = Result;
6196
+
6197
+ LValue Src;
6198
+ if (!EvaluatePointer (E->getArg (1 ), Src, Info) || Src.Designator .Invalid )
6199
+ return false ;
6200
+
6201
+ APSInt N;
6202
+ if (!EvaluateInteger (E->getArg (2 ), N, Info))
6203
+ return false ;
6204
+ assert (!N.isSigned () && " memcpy and friends take an unsigned size" );
6205
+
6206
+ // If the size is zero, we treat this as always being a valid no-op.
6207
+ // (Even if one of the src and dest pointers is null.)
6208
+ if (!N)
6209
+ return true ;
6210
+
6211
+ // We require that Src and Dest are both pointers to arrays of
6212
+ // trivially-copyable type. (For the wide version, the designator will be
6213
+ // invalid if the designated object is not a wchar_t.)
6214
+ QualType T = Dest.Designator .getType (Info.Ctx );
6215
+ QualType SrcT = Src.Designator .getType (Info.Ctx );
6216
+ if (!Info.Ctx .hasSameUnqualifiedType (T, SrcT)) {
6217
+ Info.FFDiag (E, diag::note_constexpr_memcpy_type_pun) << Move << SrcT << T;
6218
+ return false ;
6219
+ }
6220
+ if (!T.isTriviallyCopyableType (Info.Ctx )) {
6221
+ Info.FFDiag (E, diag::note_constexpr_memcpy_nontrivial) << Move << T;
6222
+ return false ;
6223
+ }
6224
+
6225
+ // Figure out how many T's we're copying.
6226
+ uint64_t TSize = Info.Ctx .getTypeSizeInChars (T).getQuantity ();
6227
+ if (!WChar) {
6228
+ uint64_t Remainder;
6229
+ llvm::APInt OrigN = N;
6230
+ llvm::APInt::udivrem (OrigN, TSize, N, Remainder);
6231
+ if (Remainder) {
6232
+ Info.FFDiag (E, diag::note_constexpr_memcpy_unsupported)
6233
+ << Move << WChar << 0 << T << OrigN.toString (10 , /* Signed*/ false )
6234
+ << (unsigned )TSize;
6235
+ return false ;
6236
+ }
6237
+ }
6238
+
6239
+ // Check that the copying will remain within the arrays, just so that we
6240
+ // can give a more meaningful diagnostic. This implicitly also checks that
6241
+ // N fits into 64 bits.
6242
+ uint64_t RemainingSrcSize = Src.Designator .validIndexAdjustments ().second ;
6243
+ uint64_t RemainingDestSize = Dest.Designator .validIndexAdjustments ().second ;
6244
+ if (N.ugt (RemainingSrcSize) || N.ugt (RemainingDestSize)) {
6245
+ Info.FFDiag (E, diag::note_constexpr_memcpy_unsupported)
6246
+ << Move << WChar << (N.ugt (RemainingSrcSize) ? 1 : 2 ) << T
6247
+ << N.toString (10 , /* Signed*/ false );
6248
+ return false ;
6249
+ }
6250
+ uint64_t NElems = N.getZExtValue ();
6251
+ uint64_t NBytes = NElems * TSize;
6252
+
6253
+ // Check for overlap.
6254
+ int Direction = 1 ;
6255
+ if (HasSameBase (Src, Dest)) {
6256
+ uint64_t SrcOffset = Src.getLValueOffset ().getQuantity ();
6257
+ uint64_t DestOffset = Dest.getLValueOffset ().getQuantity ();
6258
+ if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
6259
+ // Dest is inside the source region.
6260
+ if (!Move) {
6261
+ Info.FFDiag (E, diag::note_constexpr_memcpy_overlap) << WChar;
6262
+ return false ;
6263
+ }
6264
+ // For memmove and friends, copy backwards.
6265
+ if (!HandleLValueArrayAdjustment (Info, E, Src, T, NElems - 1 ) ||
6266
+ !HandleLValueArrayAdjustment (Info, E, Dest, T, NElems - 1 ))
6267
+ return false ;
6268
+ Direction = -1 ;
6269
+ } else if (!Move && SrcOffset >= DestOffset &&
6270
+ SrcOffset - DestOffset < NBytes) {
6271
+ // Src is inside the destination region for memcpy: invalid.
6272
+ Info.FFDiag (E, diag::note_constexpr_memcpy_overlap) << WChar;
6273
+ return false ;
6274
+ }
6275
+ }
6276
+
6277
+ while (true ) {
6278
+ APValue Val;
6279
+ if (!handleLValueToRValueConversion (Info, E, T, Src, Val) ||
6280
+ !handleAssignment (Info, E, Dest, T, Val))
6281
+ return false ;
6282
+ // Do not iterate past the last element; if we're copying backwards, that
6283
+ // might take us off the start of the array.
6284
+ if (--NElems == 0 )
6285
+ return true ;
6286
+ if (!HandleLValueArrayAdjustment (Info, E, Src, T, Direction) ||
6287
+ !HandleLValueArrayAdjustment (Info, E, Dest, T, Direction))
6288
+ return false ;
6289
+ }
6290
+ }
6291
+
6120
6292
default :
6121
6293
return visitNonBuiltinCallExpr (E);
6122
6294
}
@@ -8357,27 +8529,6 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
8357
8529
}
8358
8530
}
8359
8531
8360
- static bool HasSameBase (const LValue &A, const LValue &B) {
8361
- if (!A.getLValueBase ())
8362
- return !B.getLValueBase ();
8363
- if (!B.getLValueBase ())
8364
- return false ;
8365
-
8366
- if (A.getLValueBase ().getOpaqueValue () !=
8367
- B.getLValueBase ().getOpaqueValue ()) {
8368
- const Decl *ADecl = GetLValueBaseDecl (A);
8369
- if (!ADecl)
8370
- return false ;
8371
- const Decl *BDecl = GetLValueBaseDecl (B);
8372
- if (!BDecl || ADecl->getCanonicalDecl () != BDecl->getCanonicalDecl ())
8373
- return false ;
8374
- }
8375
-
8376
- return IsGlobalLValue (A.getLValueBase ()) ||
8377
- (A.getLValueCallIndex () == B.getLValueCallIndex () &&
8378
- A.getLValueVersion () == B.getLValueVersion ());
8379
- }
8380
-
8381
8532
// / Determine whether this is a pointer past the end of the complete
8382
8533
// / object referred to by the lvalue.
8383
8534
static bool isOnePastTheEndOfCompleteObject (const ASTContext &Ctx,
0 commit comments