diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 364695b762c66027d76e96490404e4910f6bd0b9..3079561f2e88730421e998f24749435c72802526 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -9179,8 +9179,12 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 	  }
 	else if (fun)
           {
-	    if (RECUR (fun, rval))
-	      /* Might end up being a constant function pointer.  */;
+	    if (RECUR (fun, FUNCTION_POINTER_TYPE_P (fun) ? rval : any))
+	      /* Might end up being a constant function pointer.  But it
+		 could also be a function object with constexpr op(), so
+		 we pass 'any' so that the underlying VAR_DECL is deemed
+		 as potentially-constant even though it wasn't declared
+		 constexpr.  */;
 	    else
 	      return false;
           }
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ74.C b/gcc/testsuite/g++.dg/cpp1y/var-templ74.C
index 4e2e800a6ebb8f1ef921bf7580625e38d22a7d80..c76a7d949ac99ab62d404e3b1e5e6bf6b83746f3 100644
--- a/gcc/testsuite/g++.dg/cpp1y/var-templ74.C
+++ b/gcc/testsuite/g++.dg/cpp1y/var-templ74.C
@@ -9,7 +9,7 @@ struct Q {
 extern const Q q;
 
 template<int>
-constexpr const Q* p = q(0); // { dg-bogus "not usable" "PR107939" { xfail *-*-* } }
+constexpr const Q* p = q(0);
 
 void
 g ()
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ77.C b/gcc/testsuite/g++.dg/cpp1y/var-templ77.C
new file mode 100644
index 0000000000000000000000000000000000000000..0c56d70a03425365222a1e4017ac4ad48ffd8dca
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/var-templ77.C
@@ -0,0 +1,32 @@
+// PR c++/107939
+// { dg-do compile { target c++14 } }
+
+struct Q {
+  struct P {
+    const Q* p;
+  };
+  int n;
+  constexpr P operator()(int) const { return {this}; }
+};
+
+extern const Q q;
+template<int>
+constexpr auto p = q(0);
+static_assert(p<0>.p == &q, "");
+
+constexpr int
+fn (int)
+{
+  return 42;
+}
+
+struct Sur {
+  using FN = int(int);
+  constexpr operator FN*() const { return &fn; }
+};
+
+extern const Sur sur;
+template<int>
+constexpr int aja = sur (0);
+static_assert(aja<0> == 42, "");
+static_assert(sur(1) == 42, "");