nwilson updated this revision to Diff 82194.
nwilson added a comment.

- Remove the call to `setImplicitlyInline()` within `setImplicitlyConstexpr()` 
and call `setImplicitlyInline()` directly for function concepts.


https://reviews.llvm.org/D26882

Files:
  include/clang/AST/Decl.h
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp

Index: test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp
===================================================================
--- test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp
+++ test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp
@@ -11,3 +11,30 @@
 };
 
 template<typename T> concept constexpr bool FCC() { return true; } // expected-error {{function concept cannot be declared 'constexpr'}}
+
+template <typename T> concept bool FCSizeOf() { return sizeof(T) == 8; }
+static_assert(FCSizeOf<char[8]>(), "");
+static_assert(FCSizeOf<char[9]>(), "size of argument not equal to expected (8)"); // expected-error {{static_assert failed "size of argument not equal to expected (8)"}}
+
+struct TestType {};
+template <typename T, typename U> concept bool FCSameType() { return __is_same(T, U); }
+static_assert(FCSameType<TestType, TestType>(), "");
+
+template <typename T>
+struct remove_reference { typedef T type; };
+template <typename T>
+struct remove_reference<T &> { typedef T type; };
+template <typename T>
+struct remove_reference<T &&> { typedef T type; };
+
+template <typename T>
+constexpr T &&forward(typename remove_reference<T>::type &t) noexcept { return static_cast<T &&>(t); }
+template <typename T>
+constexpr T &&forward(typename remove_reference<T>::type &&t) noexcept { return static_cast<T &&>(t); }
+
+template <typename F, typename... Args>
+constexpr decltype(auto) CFFwdCall(F &&func, Args &&... args) {
+  return forward<F>(func)(forward<Args>(args)...);
+}
+
+static_assert(CFFwdCall(FCSameType<short, short int>), "");
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -7086,7 +7086,7 @@
     // C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr
     // function can differ from the template declaration with respect to
     // the constexpr specifier.
-    Specialization->setConstexpr(FD->isConstexpr());
+    Specialization->setImplicitlyConstexpr(FD->isConstexpr());
   }
 
   // FIXME: Check if the prior specialization has a point of instantiation.
Index: lib/Sema/SemaLambda.cpp
===================================================================
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -1619,7 +1619,7 @@
       !CallOperator->isConstexpr() &&
       !Class->getDeclContext()->isDependentContext()) {
     TentativeAnalysisScope DiagnosticScopeGuard(*this);
-    CallOperator->setConstexpr(
+    CallOperator->setImplicitlyConstexpr(
         CheckConstexprFunctionDecl(CallOperator) &&
         CheckConstexprFunctionBody(CallOperator, CallOperator->getBody()));
   }
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -6253,7 +6253,7 @@
   if (First) {
     //  -- it is implicitly considered to be constexpr if the implicit
     //     definition would be,
-    MD->setConstexpr(Constexpr);
+    MD->setImplicitlyConstexpr(Constexpr);
 
     //  -- it is implicitly considered to have the same exception-specification
     //     as if it had been implicitly declared,
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -8082,7 +8082,8 @@
       }
 
       // C++ Concepts TS [dcl.spec.concept]p2: Every concept definition is
-      // implicity defined to be a constexpr declaration (implicitly inline)
+      // implicity defined to be a constexpr declaration
+      NewFD->setImplicitlyConstexpr(true);
       NewFD->setImplicitlyInline();
 
       // C++ Concepts TS [dcl.spec.concept]p2: A concept definition shall not
@@ -9104,7 +9105,7 @@
   if (FD->isConstexpr()) {
     Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_main)
       << FixItHint::CreateRemoval(DS.getConstexprSpecLoc());
-    FD->setConstexpr(false);
+    FD->setImplicitlyConstexpr(false);
   }
 
   if (getLangOpts().OpenCL) {
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -1624,6 +1624,7 @@
   unsigned HasImplicitReturnZero : 1;
   unsigned IsLateTemplateParsed : 1;
   unsigned IsConstexpr : 1;
+  unsigned IsConstexprSpecified : 1;
 
   /// \brief Indicates if the function uses __try.
   unsigned UsesSEHTry : 1;
@@ -1718,6 +1719,7 @@
         IsDeleted(false), IsTrivial(false), IsDefaulted(false),
         IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
         IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
+        IsConstexprSpecified(isConstexprSpecified),
         UsesSEHTry(false), HasSkippedBody(false), WillHaveBody(false),
         EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(),
         DNLoc(NameInfo.getInfo()) {}
@@ -1907,7 +1909,19 @@
 
   /// Whether this is a (C++11) constexpr function or constexpr constructor.
   bool isConstexpr() const { return IsConstexpr; }
-  void setConstexpr(bool IC) { IsConstexpr = IC; }
+
+  /// Set whether the "constexpr" keyword was specified for this function.
+  void setConstexprSpecified(bool IC) {
+    IsConstexprSpecified = IC;
+    IsConstexpr = IC;
+  }
+
+  /// Flag that this function as implicitly constexpr
+  /// C++11 [dcl.constexpr]p2: constexpr functions and constexpr constructors
+  /// are implicitly inline functions (7.1.2).
+  void setImplicitlyConstexpr(bool IC) {
+    IsConstexpr = IC;
+  }
 
   /// \brief Indicates the function uses __try.
   bool usesSEHTry() const { return UsesSEHTry; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to