[PATCH] D12169: Relax constexpr rules to improve __builtin_object_size's accuracy

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 20 17:11:04 PDT 2015


rsmith added inline comments.

================
Comment at: lib/AST/ExprConstant.cpp:4763
@@ +4762,3 @@
+  /// arithmetic.
+  bool UseStrictCastingRules;
+
----------------
This should be handled as an `EvaluationMode`.

================
Comment at: lib/AST/ExprConstant.cpp:4879-4907
@@ +4878,31 @@
+  // We need to adjust the array index we're handing off in that case.
+  QualType ArrayTy = Result.Designator.MostDerivedType;
+  if (!ArrayTy.isNull() && !ArrayTy->isIncompleteType() && ArrayTy != Pointee) {
+    CharUnits PointeeEltSize;
+    if (!HandleSizeof(Info, PExp->getExprLoc(), Pointee, PointeeEltSize))
+      return false;
+
+    CharUnits ArrayEltSize;
+    if (!HandleSizeof(Info, PExp->getExprLoc(), ArrayTy, ArrayEltSize))
+      return false;
+
+    // Additionally, because LValuePathEntry wasn't made to really handle byte
+    // offsets, we need to keep the LValue Offset up-to-date (so casting e.g.
+    // BaseToDerived works as intended), but we also need to lie a bit about the
+    // array index.
+    //
+    // Example:
+    // (char*)Foo.Bar[1] + 2 // (assuming sizeof(Foo.Bar[1]) > 2)
+    // Will have an index of 1 and an offset of offsetof(Foo.Bar[1]) + 2.
+    if (PointeeEltSize != ArrayEltSize) {
+      CharUnits ByteOffset = IndexOffset * PointeeEltSize + AddedOffset;
+      CharUnits Rem = CharUnits::fromQuantity(ByteOffset % ArrayEltSize);
+      Result.Offset += Rem - AddedOffset;
+      AddedOffset = Rem;
+      IndexOffset = ByteOffset / ArrayEltSize;
+    }
+
+    // HandleLValueArrayAdjustment takes the type of the array
+    Pointee = ArrayTy;
+  }
+
----------------
We should not do this except in your special new mode, and I'm not entirely convinced we should support this case at all. Just discarding the designator (as we would do anyway in constant-folding mode) seems like an acceptable response here. We really don't know what subobject is being referenced any more.

================
Comment at: lib/AST/ExprConstant.cpp:6355-6356
@@ +6354,4 @@
+bool OutermostMemberEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
+  Result = E->getType();
+  return true;
+}
----------------
I think handling this through the normal pointer evaluator, but with a different `EvaluationMode`, is a better approach. (We need some representation for an `LValueBase` to represent "unknown base", but everything else should fall through pretty naturally.)


http://reviews.llvm.org/D12169





More information about the cfe-commits mailing list