[PATCH] D33610: Stop asserting on constexpr explicit MS constructor calls.

Tim Northover via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri May 26 15:28:11 PDT 2017


t.p.northover created this revision.
Herald added a subscriber: mcrosier.

When trying to switch to C++14 by default, some extra expressions become constexpr and this is one case we can't handle.

Technically I believe weakening the assert would be enough to fix the problem, but defaulted default constructors are extremely close to being allowed through which would lead to incorrect code (all of isDefaulted, isTrivial and hasFields contribute to the exclusion, as well as the fact that unions don't have default constructors). So I decided to explicitly check that we are dealing with a copy/move before executing that block.


https://reviews.llvm.org/D33610

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/CodeGenCXX/constructor-direct-call.cpp


Index: clang/test/CodeGenCXX/constructor-direct-call.cpp
===================================================================
--- clang/test/CodeGenCXX/constructor-direct-call.cpp
+++ clang/test/CodeGenCXX/constructor-direct-call.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - -std=gnu++11| FileCheck %s
 
 class Test1 {
 public:
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -4184,18 +4184,27 @@
 
   CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
 
+  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee);
+  bool IsCopyOrMove = MD && MD->isCopyAssignmentOperator();
+  IsCopyOrMove |= MD && MD->isMoveAssignmentOperator();
+
+  // We support explicit constructor calls as an MS extension. These can be
+  // constexpr by C++11 rules.
+  auto CD = dyn_cast_or_null<CXXConstructorDecl>(MD);
+  IsCopyOrMove |= CD && CD->isCopyConstructor();
+  IsCopyOrMove |= CD && CD->isMoveConstructor();
+
   // For a trivial copy or move assignment, perform an APValue copy. This is
   // essential for unions, where the operations performed by the assignment
   // operator cannot be represented as statements.
   //
   // Skip this for non-union classes with no fields; in that case, the defaulted
   // copy/move does not actually read the object.
-  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee);
-  if (MD && MD->isDefaulted() &&
+  if (MD && MD->isDefaulted() && IsCopyOrMove &&
       (MD->getParent()->isUnion() ||
        (MD->isTrivial() && hasFields(MD->getParent())))) {
-    assert(This &&
-           (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
+    assert(This);
+
     LValue RHS;
     RHS.setFrom(Info.Ctx, ArgValues[0]);
     APValue RHSValue;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33610.100483.patch
Type: text/x-patch
Size: 2017 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170526/467407ba/attachment-0001.bin>


More information about the cfe-commits mailing list