[PATCH] D42776: [Sema] Fix an assertion failure in constant expression evaluation of calls to functions with default arguments

Richard Smith - zygoloid via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 12 15:37:32 PST 2018


rsmith added inline comments.


================
Comment at: lib/AST/APValue.cpp:27
+    APValue::LValueBase Base;
+    bool IsOnePastTheEnd;
     CharUnits Offset;
----------------
Move this to the end so it can share space with `IsNullPtr`.


================
Comment at: lib/AST/ExprConstant.cpp:589-598
+    /// Keep track of the version of MTEs that are used by CXXDefaultArgExpr.
+    /// The version number is updated every time VisitCXXDefaultArgExpr is
+    /// called.
+    unsigned getDefaultArgNum() const { return CurDefaultArgNum; }
+    void setDefaultArgNum() {
+      assert(CurDefaultArgNum == 0 && "CurDefaultArgNum hasn't been cleared");
+      CurDefaultArgNum = ++NextDefaultArgNum;
----------------
This seems extremely similar to the purpose of the existing `CallIndex` parameter. Have you thought about ways the two might be unified?

If there's no reasonable path to unifying the two (which I suspect there may not be), it would make more sense to me to store a current version number on the `CallStackFrame` rather than globally in the `EvalInfo`, and to restart the numbering in each new call frame. That also emphasizes something else: this version number should be kept with the `CallIndex`. (We could achieve that by either moving the `CallIndex` into the `LValueBase` or moving the `Version` out of it.)


================
Comment at: lib/AST/ExprConstant.cpp:597
+    }
+    void clearDefaultArgNum() { CurDefaultArgNum = 0; }
+    unsigned CurDefaultArgNum = 0, NextDefaultArgNum = 0;
----------------
This is wrong: these scopes can nest, so you can't just reset the number to 0 when you're done. You should restore the prior number when you're done here, to divide up evaluation into CXXDefaultArgExpr scopes. (Technically, I think it would also be correct to leave the number alone when you leave one of these scopes, but only because a scope for a particular parameter's default argument can't nest within another scope for the same default argument expression -- and even that might not be true in the presence of template instantiation.)


================
Comment at: lib/AST/ExprConstant.cpp:4595
+  }
   bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
     // The initializer may not have been parsed yet, or might be erroneous.
----------------
We need the same handling for `CXXDefaultInitExpr`, too.


https://reviews.llvm.org/D42776





More information about the cfe-commits mailing list