PR47555: Inheriting constructors are implicitly definable.
authorRichard Smith <richard@metafoo.co.uk>
Thu, 17 Sep 2020 01:08:03 +0000 (18:08 -0700)
committerRichard Smith <richard@metafoo.co.uk>
Thu, 17 Sep 2020 01:11:18 +0000 (18:11 -0700)
Don't forget to define them if they're constexpr and used inside a
template; we might try to evaluate a call to them before the template is
instantiated.

clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/cxx11-inheriting-ctors.cpp

index 9a4b3e3..c82febd 100644 (file)
@@ -16582,8 +16582,13 @@ static OdrUseContext isOdrUseContext(Sema &SemaRef) {
 }
 
 static bool isImplicitlyDefinableConstexprFunction(FunctionDecl *Func) {
-  return Func->isConstexpr() &&
-         (Func->isImplicitlyInstantiable() || !Func->isUserProvided());
+  if (!Func->isConstexpr())
+    return false;
+
+  if (Func->isImplicitlyInstantiable() || !Func->isUserProvided())
+    return true;
+  auto *CCD = dyn_cast<CXXConstructorDecl>(Func);
+  return CCD && CCD->getInheritedConstructor();
 }
 
 /// Mark a function referenced, and check whether it is odr-used
index 7d6f4f0..5be4284 100644 (file)
@@ -133,3 +133,12 @@ namespace implicit_member_srcloc {
     S0<int> s0;
   }
 }
+
+namespace PR47555 {
+  struct A { constexpr A(int) {} };
+  struct B : A { using A::A; };
+  template<typename> void f() {
+    constexpr B b = 0;
+  };
+  template void f<int>();
+}