diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 60e9e05206289fe7ef2d7cf7096eb0581f28197d..eb34d5af004554396f301c53785fa80a672208d3 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1111,6 +1111,8 @@ c_cpp_builtins (cpp_reader *pfile)
       if (cxx_dialect >= cxx11 && strcmp (thread_model, "single") != 0)
 	cpp_define (pfile, "__STDCPP_THREADS__=1");
 #endif
+      if (flag_implicit_constexpr)
+	cpp_define (pfile, "__cpp_implicit_constexpr=20211111L");
     }
   /* Note that we define this for C as well, so that we know if
      __attribute__((cleanup)) will interface with EH.  */
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 0225cba7a4bfbc0b67dc87738a8cdadeff0f8855..62f58295c119cd2ac8453c51c2fbbd1c824d364b 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -1052,6 +1052,9 @@ c_common_post_options (const char **pfilename)
       && flag_strong_eval_order == -1)
     flag_strong_eval_order = (cxx_dialect >= cxx17 ? 2 : 1);
 
+  if (flag_implicit_constexpr && cxx_dialect < cxx14)
+    flag_implicit_constexpr = false;
+
   /* Global sized deallocation is new in C++14.  */
   if (flag_sized_deallocation == -1)
     flag_sized_deallocation = (cxx_dialect >= cxx14);
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 06457ac739e4ed7deeb49b2a208dc1c84cdae360..8a4cd634f77e71dec62c1023150270f61e38e0cf 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1712,6 +1712,10 @@ fimplement-inlines
 C++ ObjC++ Var(flag_implement_inlines) Init(1)
 Export functions even if they can be inlined.
 
+fimplicit-constexpr
+C++ ObjC++ Var(flag_implicit_constexpr)
+Make inline functions constexpr by default.
+
 fimplicit-inline-templates
 C++ ObjC++ Var(flag_implicit_inline_templates) Init(1)
 Emit implicit instantiations of inline templates.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 84694249b873244eb598bfb6e7de7b64f2292561..de1fc0249e67d9a2af51fa39335768a598a078a8 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -221,7 +221,7 @@ check-c++17:
 
 # Run the testsuite in all standard conformance levels.
 check-c++-all:
-	$(MAKE) RUNTESTFLAGS="$(RUNTESTFLAGS) --stds=98,11,14,17,2a,concepts" check-g++
+	$(MAKE) RUNTESTFLAGS="$(RUNTESTFLAGS) --stds=98,11,14,17,20,23,impcx" check-g++
 
 # Run the testsuite with garbage collection at every opportunity.
 check-g++-strict-gc:
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index bf92300a1789c8e9187e0a855d31ba4f9358f23c..c30a44f039b2428063eba8fbba83459d94995894 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5547,10 +5547,16 @@ type_has_constexpr_destructor (tree t)
 static bool
 type_maybe_constexpr_destructor (tree t)
 {
+  /* Until C++20, only trivial destruction is constexpr.  */
+  if (TYPE_HAS_TRIVIAL_DESTRUCTOR (t))
+    return true;
+  if (cxx_dialect < cxx20)
+    return false;
   if (CLASS_TYPE_P (t) && CLASSTYPE_LAZY_DESTRUCTOR (t))
     /* Assume it's constexpr.  */
     return true;
-  return type_has_constexpr_destructor (t);
+  tree fn = CLASSTYPE_DESTRUCTOR (t);
+  return (fn && maybe_constexpr_fn (fn));
 }
 
 /* Returns true iff class TYPE has a virtual destructor.  */
@@ -5823,8 +5829,7 @@ finalize_literal_type_property (tree t)
   if (cxx_dialect < cxx11)
     CLASSTYPE_LITERAL_P (t) = false;
   else if (CLASSTYPE_LITERAL_P (t)
-	   && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
-	   && (cxx_dialect < cxx20 || !type_maybe_constexpr_destructor (t)))
+	   && !type_maybe_constexpr_destructor (t))
     CLASSTYPE_LITERAL_P (t) = false;
   else if (CLASSTYPE_LITERAL_P (t) && LAMBDA_TYPE_P (t))
     CLASSTYPE_LITERAL_P (t) = (cxx_dialect >= cxx17);
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index c92db5d413c2d4d350f4c4f0ca24f82d52268dc0..69d9d3daeca7e651eb1c6469da944a75ae4c566c 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "stor-layout.h"
 #include "cgraph.h"
 #include "opts.h"
+#include "stringpool.h"
+#include "attribs.h"
 
 static bool verify_constant (tree, bool, bool *, bool *);
 #define VERIFY_CONSTANT(X)						\
@@ -220,6 +222,17 @@ is_valid_constexpr_fn (tree fun, bool complain)
 	inform (DECL_SOURCE_LOCATION (fun),
 		"lambdas are implicitly %<constexpr%> only in C++17 and later");
     }
+  else if (DECL_DESTRUCTOR_P (fun))
+    {
+      if (cxx_dialect < cxx20)
+	{
+	  ret = false;
+	  if (complain)
+	    error_at (DECL_SOURCE_LOCATION (fun),
+		      "%<constexpr%> destructors only available"
+		      " with %<-std=c++20%> or %<-std=gnu++20%>");
+	}
+    }
   else if (!DECL_CONSTRUCTOR_P (fun))
     {
       tree rettype = TREE_TYPE (TREE_TYPE (fun));
@@ -865,12 +878,31 @@ void
 maybe_save_constexpr_fundef (tree fun)
 {
   if (processing_template_decl
-      || !DECL_DECLARED_CONSTEXPR_P (fun)
       || cp_function_chain->invalid_constexpr
       || (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun)))
     return;
 
-  bool complain = !DECL_GENERATED_P (fun);
+  /* With -fimplicit-constexpr, try to make inlines constexpr.  We'll
+     actually set DECL_DECLARED_CONSTEXPR_P below if the checks pass.  */
+  bool implicit = false;
+  if (flag_implicit_constexpr)
+    {
+      if (DECL_DELETING_DESTRUCTOR_P (fun)
+	  && decl_implicit_constexpr_p (DECL_CLONED_FUNCTION (fun)))
+	/* Don't inherit implicit constexpr from the non-deleting
+	   destructor.  */
+	DECL_DECLARED_CONSTEXPR_P (fun) = false;
+
+      if (!DECL_DECLARED_CONSTEXPR_P (fun)
+	  && DECL_DECLARED_INLINE_P (fun)
+	  && !lookup_attribute ("noinline", DECL_ATTRIBUTES (fun)))
+	implicit = true;
+    }
+
+  if (!DECL_DECLARED_CONSTEXPR_P (fun) && !implicit)
+    return;
+
+  bool complain = !DECL_GENERATED_P (fun) && !implicit;
 
   if (!is_valid_constexpr_fn (fun, complain))
     return;
@@ -878,7 +910,7 @@ maybe_save_constexpr_fundef (tree fun)
   tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
   if (massaged == NULL_TREE || massaged == error_mark_node)
     {
-      if (!DECL_CONSTRUCTOR_P (fun))
+      if (!DECL_CONSTRUCTOR_P (fun) && complain)
 	error ("body of %<constexpr%> function %qD not a return-statement",
 	       fun);
       return;
@@ -907,6 +939,21 @@ maybe_save_constexpr_fundef (tree fun)
   if (!potential && complain)
     return;
 
+  if (implicit)
+    {
+      if (potential)
+	{
+	  DECL_DECLARED_CONSTEXPR_P (fun) = true;
+	  DECL_LANG_SPECIFIC (fun)->u.fn.implicit_constexpr = true;
+	  if (DECL_CONSTRUCTOR_P (fun))
+	    TYPE_HAS_CONSTEXPR_CTOR (DECL_CONTEXT (fun)) = true;
+	}
+      else
+	/* Don't bother keeping the pre-generic body of unsuitable functions
+	   not explicitly declared constexpr.  */
+	return;
+    }
+
   constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE};
   bool clear_ctx = false;
   if (DECL_RESULT (fun) && DECL_CONTEXT (DECL_RESULT (fun)) == NULL_TREE)
@@ -2404,7 +2451,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 					   lval, non_constant_p, overflow_p);
   if (DECL_THUNK_P (fun))
     return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p);
-  if (!DECL_DECLARED_CONSTEXPR_P (fun))
+  if (!maybe_constexpr_fn (fun))
     {
       if (TREE_CODE (t) == CALL_EXPR
 	  && cxx_replaceable_global_alloc_fn (fun)
@@ -5229,7 +5276,9 @@ bool
 maybe_constexpr_fn (tree t)
 {
   return (DECL_DECLARED_CONSTEXPR_P (t)
-	  || (cxx_dialect >= cxx17 && LAMBDA_FUNCTION_P (t)));
+	  || (cxx_dialect >= cxx17 && LAMBDA_FUNCTION_P (t))
+	  || (flag_implicit_constexpr
+	      && DECL_DECLARED_INLINE_P (STRIP_TEMPLATE (t))));
 }
 
 /* True if T was declared in a function that might be constexpr: either a
@@ -5238,11 +5287,8 @@ maybe_constexpr_fn (tree t)
 bool
 var_in_maybe_constexpr_fn (tree t)
 {
-  if (cxx_dialect >= cxx17
-      && DECL_FUNCTION_SCOPE_P (t)
-      && LAMBDA_FUNCTION_P (DECL_CONTEXT (t)))
-    return true;
-  return var_in_constexpr_fn (t);
+  return (DECL_FUNCTION_SCOPE_P (t)
+	  && maybe_constexpr_fn (DECL_CONTEXT (t)));
 }
 
 /* We're assigning INIT to TARGET.  In do_build_copy_constructor and
@@ -8219,7 +8265,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 	      {
 		if (builtin_valid_in_constant_expr_p (fun))
 		  return true;
-		if (!DECL_DECLARED_CONSTEXPR_P (fun)
+		if (!maybe_constexpr_fn (fun)
 		    /* Allow any built-in function; if the expansion
 		       isn't constant, we'll deal with that then.  */
 		    && !fndecl_built_in_p (fun)
@@ -9257,6 +9303,23 @@ is_nondependent_static_init_expression (tree t)
 	  && !instantiation_dependent_expression_p (t));
 }
 
+/* True iff FN is an implicitly constexpr function.  */
+
+bool
+decl_implicit_constexpr_p (tree fn)
+{
+  if (!(flag_implicit_constexpr
+	&& TREE_CODE (fn) == FUNCTION_DECL
+	&& DECL_DECLARED_CONSTEXPR_P (fn)))
+    return false;
+
+  if (DECL_CLONED_FUNCTION_P (fn))
+    fn = DECL_CLONED_FUNCTION (fn);
+
+  return (DECL_LANG_SPECIFIC (fn)
+	  && DECL_LANG_SPECIFIC (fn)->u.fn.implicit_constexpr);
+}
+
 /* Finalize constexpr processing after parsing.  */
 
 void
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f387b5036d27f7efd8eef0f7cc845b33618b035f..acc98c9c452a1aa063c8326fe7d9bddaf63910cf 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2868,8 +2868,9 @@ struct GTY(()) lang_decl_fn {
   unsigned immediate_fn_p : 1;
   unsigned maybe_deleted : 1;
   unsigned coroutine_p : 1;
+  unsigned implicit_constexpr : 1;
 
-  unsigned spare : 10;
+  unsigned spare : 9;
 
   /* 32-bits padding on 64-bit host.  */
 
@@ -8315,6 +8316,7 @@ extern vec<tree> cx_error_context               (void);
 extern tree fold_sizeof_expr			(tree);
 extern void clear_cv_and_fold_caches		(void);
 extern tree unshare_constructor			(tree CXX_MEM_STAT_INFO);
+extern bool decl_implicit_constexpr_p		(tree);
 
 /* An RAII sentinel used to restrict constexpr evaluation so that it
    doesn't do anything that causes extra DECL_UID generation.  */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index eed478199ea5833c45c29490d8a6c34b27a4612b..2ddf0e4a5247e78fdc90d44ea6f86d7ac6099102 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1290,6 +1290,12 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl)
     }
   if (TREE_CODE (old_decl) == FUNCTION_DECL)
     {
+      /* With -fimplicit-constexpr, ignore changes in the constexpr
+	 keyword.  */
+      if (flag_implicit_constexpr
+	  && (DECL_IMMEDIATE_FUNCTION_P (new_decl)
+	      == DECL_IMMEDIATE_FUNCTION_P (old_decl)))
+	return true;
       if (fndecl_built_in_p (old_decl))
 	{
 	  /* Hide a built-in declaration.  */
@@ -14863,7 +14869,7 @@ grok_special_member_properties (tree decl)
       if (is_list_ctor (decl))
 	TYPE_HAS_LIST_CTOR (class_type) = 1;
 
-      if (DECL_DECLARED_CONSTEXPR_P (decl)
+      if (maybe_constexpr_fn (decl)
 	  && !ctor && !move_fn_p (decl))
 	TYPE_HAS_CONSTEXPR_CTOR (class_type) = 1;
     }
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 012a4ecddf44661f12d8df1d5e474614b5de3d39..872479369ab226ee97c1bf4990a9c6972a84c5d2 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1686,7 +1686,8 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
   exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t));
 
   /* Likewise for the constexpr specifier, in case t is a specialization.  */
-  constexpr_p = DECL_DECLARED_CONSTEXPR_P (t);
+  constexpr_p = (DECL_DECLARED_CONSTEXPR_P (t)
+		 && !decl_implicit_constexpr_p (t));
 
   /* Pretty print template instantiations only.  */
   if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag16.C b/gcc/testsuite/g++.dg/abi/abi-tag16.C
index d4fa142762a8cef0e57c0cad4828b22fcd8ed40d..3027d7906f51fb02a889b3f5ab95a4e8946bbdb4 100644
--- a/gcc/testsuite/g++.dg/abi/abi-tag16.C
+++ b/gcc/testsuite/g++.dg/abi/abi-tag16.C
@@ -1,4 +1,4 @@
-// { dg-options -Wabi=9 }
+// { dg-options "-Wabi=9 -fno-implicit-constexpr" }
 // { dg-final { scan-assembler "_ZGVZN1N1FEvE4NameB5cxx11" } }
 namespace std {
   __extension__ inline namespace __cxx11 __attribute__((abi_tag("cxx11"))) {
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag18a.C b/gcc/testsuite/g++.dg/abi/abi-tag18a.C
index 95e192ae6f4a0a1b715ce20f5160783f03b72566..c6fb1607a418c1c8eb526365b33a42b19d09bacf 100644
--- a/gcc/testsuite/g++.dg/abi/abi-tag18a.C
+++ b/gcc/testsuite/g++.dg/abi/abi-tag18a.C
@@ -1,5 +1,5 @@
 // { dg-skip-if "PR 70349" { hppa*-*-hpux* && { ! lp64 } } }
-// { dg-options -fabi-version=9 }
+// { dg-options "-fabi-version=9 -fno-implicit-constexpr" }
 // { dg-final { scan-assembler "_Z1fB7__test1v" } }
 // { dg-final { scan-assembler "_ZZ1fB7__test1vEN1T1gB7__test2Ev" } }
 // { dg-final { scan-assembler "_ZZZ1fB7__test1vEN1T1gEvE1x" } }
diff --git a/gcc/testsuite/g++.dg/abi/guard4.C b/gcc/testsuite/g++.dg/abi/guard4.C
index 537c90524f3c55bf39faeb8b1a648d64b364c584..71e6744e3810d5c5ced91c7eb11c9bac3afc579d 100644
--- a/gcc/testsuite/g++.dg/abi/guard4.C
+++ b/gcc/testsuite/g++.dg/abi/guard4.C
@@ -3,9 +3,10 @@
 
 namespace x {
   struct s {
-    s() {}
+    s();
     static int a;
   };
+  s::s() {}
   // { dg-final { scan-assembler {.weak[^\n]*_ZGVN1x1bE} } }
   struct s __attribute__((weak)) b = s();
 }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-defarg1.C b/gcc/testsuite/g++.dg/abi/lambda-defarg1.C
index 8c53858124069645d5b054315f5c47391ef27326..79e4fa64ac57245c6a483550ec683c40a3ac994d 100644
--- a/gcc/testsuite/g++.dg/abi/lambda-defarg1.C
+++ b/gcc/testsuite/g++.dg/abi/lambda-defarg1.C
@@ -1,5 +1,6 @@
 // PR c++/91241
 // { dg-do compile { target c++11 } }
+// { dg-additional-options -fkeep-inline-functions }
 
 struct A {
   int *b(const int & = []() -> int { return 0; }(),
diff --git a/gcc/testsuite/g++.dg/abi/mangle26.C b/gcc/testsuite/g++.dg/abi/mangle26.C
index 5d1609596b909ba28bdc0203865a58e6743ec6dc..2041d778b9a63638d34a72e63dc5ed6c821b7bed 100644
--- a/gcc/testsuite/g++.dg/abi/mangle26.C
+++ b/gcc/testsuite/g++.dg/abi/mangle26.C
@@ -1,7 +1,7 @@
 // Test of std mangling
 
 // { dg-do compile }
-// { dg-options "-fno-inline" }
+// { dg-options "-fno-inline -fno-implicit-constexpr" }
 
 namespace std {
   struct A {
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C
index 1c43569615c5f5fb81603e8604549a1d77756370..c167bb1d8bc1bb8787385de4b0a33b413ca40fe9 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C
@@ -13,7 +13,7 @@ int main()
 
 // --------------------
 
-struct complex 			// { dg-message "no .constexpr. constructor" }
+struct complex 			// { dg-message "no .constexpr. constructor" "" { target { ! implicit_constexpr } } }
 {
   complex(double r, double i) : re(r), im(i) { }
   constexpr double real() const { return re; } // { dg-error "not a literal type" "" { target c++11_only } }
@@ -24,23 +24,23 @@ private:
   double im;
 };
 
-constexpr complex co1(0, 1);	   // { dg-error "19:the type .const complex. of .constexpr. variable .co1. is not literal" }
-constexpr double dd2 = co1.real(); // { dg-error "|in .constexpr. expansion of " }
+constexpr complex co1(0, 1);	   // { dg-error "19:the type .const complex. of .constexpr. variable .co1. is not literal" "" { target { ! implicit_constexpr } } }
+constexpr double dd2 = co1.real(); // { dg-error "|in .constexpr. expansion of " "" { target { ! implicit_constexpr } } }
 
 // --------------------
 
-struct base		       // { dg-message "no .constexpr. constructor" }
+struct base		       // { dg-message "no .constexpr. constructor" "" { target { ! implicit_constexpr } } }
 {
   int _M_i;
   base() : _M_i(5) { }
 };
 
-struct derived : public base	// { dg-message "base class" }
+struct derived : public base	// { dg-message "base class" "" { target { ! implicit_constexpr } } }
 {
-  constexpr derived(): base() { } // { dg-error "non-.constexpr. function" }
+  constexpr derived(): base() { } // { dg-error "non-.constexpr. function" "" { target { ! implicit_constexpr } } }
 };
 
-constexpr derived obj;		// { dg-error "not literal" }
+constexpr derived obj;		// { dg-error "not literal" "" { target { ! implicit_constexpr } } }
 
 // --------------------
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C
index e5e58bddab0b2fa8a37cd0395cb853a957250518..1d5c58b4090b1f1c55d647e8ea7b2c6f4101684b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C
@@ -87,7 +87,7 @@ struct resource {
   }
 };
 constexpr resource f(resource d)
-{ return d; }                  // { dg-error "non-.constexpr." }
-constexpr resource d = f(9);   // { dg-message ".constexpr." }
+{ return d; }                  // { dg-error "non-.constexpr." "" { target { ! implicit_constexpr } } }
+constexpr resource d = f(9);   // { dg-message ".constexpr." "" { target { ! implicit_constexpr } } }
 
 // 4.4 floating-point constant expressions
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C
index 51b328e2598098f6d330e96751674920426ec8fb..e934421c2f4880b82ce1bb90da3e97293c0954d6 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C
@@ -9,5 +9,5 @@ struct A
 struct B
 {
   A a[1];
-  constexpr B() : a() {} // { dg-error "non-constant|non-.constexpr." }
+  constexpr B() : a() {} // { dg-error "non-constant|non-.constexpr." "" { target { ! implicit_constexpr } } }
 };
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete2.C
index a04f1d51d22c7666312fd1d87497cf6dea74879b..c018eded1de1fe9b59336a451d3421952581414c 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete2.C
@@ -28,4 +28,4 @@ struct D
   C<D> c;
 };
 
-constexpr D d {};		// { dg-error "non-.constexpr. function" }
+constexpr D d {};		// { dg-error "non-.constexpr. function" "" { target { ! implicit_constexpr } } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C
index d58e2ec6b15f840ab142e65e315c4a2449b3b9f8..37255282ded7bddb3e5f48f41328955f7934038f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C
@@ -13,6 +13,6 @@ constexpr X X::g(X x) { return x; }
 struct Y
 {
   Y() { }
-  constexpr Y f(Y y) { return y; }  // { dg-error "constexpr" }
-  static constexpr Y g(Y y) { return y; } // { dg-error "constexpr" }
+  constexpr Y f(Y y) { return y; }  // { dg-error "constexpr" "" { target { ! implicit_constexpr } } }
+  static constexpr Y g(Y y) { return y; } // { dg-error "constexpr" "" { target { ! implicit_constexpr } } }
 };
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg3.C
index 55bb838a2bfb5033c5e21b0ebfa7cb8dea132c8a..89559d7605882908ee5629bde65f13af2febc1c3 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg3.C
@@ -9,7 +9,7 @@ struct A
 template<typename> struct B
 {
   A a;
-  constexpr int bar() { return a.foo(); } // { dg-error "foo" }
+  constexpr int bar() { return a.foo(); } // { dg-error "foo" "" { target { ! implicit_constexpr } } }
 };
 
-constexpr int i = B<void>().bar(); // { dg-error "bar" }
+constexpr int i = B<void>().bar(); // { dg-error "bar" "" { target { ! implicit_constexpr } } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-specialization.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-specialization.C
index 64d8f4ec2666d1e5cbe86897940d7ae02128c440..acda6e0bcbfd42f6791d370ddd3cf3b6f40fd767 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-specialization.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-specialization.C
@@ -3,10 +3,10 @@
 
 template<typename T> constexpr int foo(T);
 template<> int foo(int);
-template<> int foo(int);            // { dg-message "previous declaration 'int foo" }
-template<> constexpr int foo(int);  // { dg-error "redeclaration 'constexpr int foo" }
+template<> int foo(int);            // { dg-message "previous declaration 'int foo" "" { target { ! implicit_constexpr } } }
+template<> constexpr int foo(int);  // { dg-error "redeclaration 'constexpr int foo" "" { target { ! implicit_constexpr } } }
 
 template<typename T> int bar(T);
 template<> constexpr int bar(int);
-template<> constexpr int bar(int);  // { dg-message "previous declaration 'constexpr int bar" }
-template<> int bar(int);            // { dg-error "redeclaration 'int bar" }
+template<> constexpr int bar(int);  // { dg-message "previous declaration 'constexpr int bar" "" { target { ! implicit_constexpr } } }
+template<> int bar(int);            // { dg-error "redeclaration 'int bar" "" { target { ! implicit_constexpr } } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor19.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor19.C
index 7e2d58b422efc245652eb0b7c97ee52fb701d5da..3476f9607ac004f4c426bebe2d2ca4620ec59be4 100644
--- a/gcc/testsuite/g++.dg/cpp0x/inh-ctor19.C
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor19.C
@@ -11,4 +11,4 @@ struct B : A
   using A::A;
 };
 
-constexpr B b;  // { dg-error "literal" }
+constexpr B b;  // { dg-error "literal" "" { target { ! implicit_constexpr } } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor30.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor30.C
index 04c58636d8d5a53d8eda42d49cb53af289a7f726..c978f0c376164df662409358ec49fe555a9753c8 100644
--- a/gcc/testsuite/g++.dg/cpp0x/inh-ctor30.C
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor30.C
@@ -1,6 +1,7 @@
 // PR c++/81860
 // { dg-do compile { target c++11 } }
 // { dg-final { scan-assembler "_ZN1AIjEC\[12\]Ev" } }
+// { dg-additional-options -fno-implicit-constexpr }
 
 template <typename T>
 struct A
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle3.C
index 5f17a21cac484e208e67a6d87d0d31fedd675af6..2120d8c72fe9d0543e70f1a4d836096444a5eb08 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle3.C
@@ -1,6 +1,7 @@
 // PR c++/51818
 // { dg-do compile { target c++11 } }
 // { dg-final { scan-assembler "_ZN1AC1IN3foo3barMUlvE_EEET_" } }
+// { dg-additional-options -fno-implicit-constexpr }
 
 struct A
 {
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle5.C
index dd95894755c97611be4fb01d21bc03f27ef2c346..23df3a2b41675b882c3155f2eac5326352309500 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle5.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle5.C
@@ -1,4 +1,5 @@
 // { dg-do compile { target c++11 } }
+// { dg-additional-options -fkeep-inline-functions }
 // { dg-final { scan-assembler "_ZZN1AIiEC4IiEET_S2_Ed_NKUlvE_clEv" } }
 
 template <class T> struct A
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
index 224f2789bcd8f98811c13f553ac9e3660b9a5671..98885799de989ce1d1fa5f158afeeb9205451100 100644
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
@@ -1,5 +1,6 @@
 // { dg-do compile { target c++14 } }
 // { dg-final { scan-assembler "_ZN1AIiEcvDaEv" } }
+// { dg-additional-options -fno-implicit-constexpr }
 
 template <class T>
 struct A {
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-loop5.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-loop5.C
index 02f372d98887ed7b100133238daea6427a197667..150aadfe6094b12d2c4e10cb61c553286e6701c9 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-loop5.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-loop5.C
@@ -9,11 +9,11 @@ template<typename>
 constexpr int count()
 {
     auto item = thing {};
-    for(; (item.foo(), false);); // { dg-error "foo" }
+    for(; (item.foo(), false);); // { dg-error "foo" "" { target { ! implicit_constexpr } } }
     return 0;
 }
 
 int main()
 {
-    static_assert( count<int>() == 0, "" ); // { dg-error "" }
+    static_assert( count<int>() == 0, "" ); // { dg-error "" "" { target { ! implicit_constexpr } } }
 }
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda7.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda7.C
index 474ce88f81f3151b9711e2f67fbc2d1414934d5c..faac00ca9974f3ec3cec51c040c15cb091278aaf 100644
--- a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda7.C
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda7.C
@@ -8,5 +8,5 @@ struct NonLiteral {
   int n;
 };
 
-static_assert( ID (NonLiteral{3}).n == 3); // { dg-error "non-literal" }
+static_assert( ID (NonLiteral{3}).n == 3); // { dg-error "non-literal" "" { target { ! implicit_constexpr } } }
 // { dg-prune-output "static assertion" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor3.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor3.C
index 69fe9e26654f83983d5ce9d47074ee5e440396d4..a68a6b4af8bc517e7dbc3444509109e01b869f02 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor3.C
@@ -7,16 +7,16 @@ struct S
   constexpr ~S () {}
   int s;
 };
-struct T	// { dg-message "'T' is not literal because" }
-{		// { dg-message "'T' does not have 'constexpr' destructor" "" { target *-*-* } .-1 }
+struct T	// { dg-message "'T' is not literal because" "" { target { ! implicit_constexpr } } }
+{		// { dg-message "'T' does not have 'constexpr' destructor" "" { target { ! implicit_constexpr } } .-1 }
   constexpr T () : t (0) {}
-  ~T () {}	// { dg-message "defaulted destructor calls non-'constexpr' 'T::~T\\(\\)'" }
+  ~T () {}	// { dg-message "defaulted destructor calls non-'constexpr' 'T::~T\\(\\)'" "" { target { ! implicit_constexpr } } }
   int t;
 };
 struct U : public S
 {
   constexpr U () : u (0) {}
-  constexpr ~U () = default;	// { dg-error "explicitly defaulted function 'constexpr U::~U\\(\\)' cannot be declared 'constexpr' because the implicit declaration is not 'constexpr'" }
+  constexpr ~U () = default;	// { dg-error "explicitly defaulted function 'constexpr U::~U\\(\\)' cannot be declared 'constexpr' because the implicit declaration is not 'constexpr'" "" { target { ! implicit_constexpr } } }
   int u;
   T t;
 };
@@ -100,11 +100,11 @@ struct W8
 struct X : public T
 {
   constexpr X () : x (0) {}
-  constexpr ~X () = default;	// { dg-error "explicitly defaulted function 'constexpr X::~X\\(\\)' cannot be declared 'constexpr' because the implicit declaration is not 'constexpr'" }
+  constexpr ~X () = default;	// { dg-error "explicitly defaulted function 'constexpr X::~X\\(\\)' cannot be declared 'constexpr' because the implicit declaration is not 'constexpr'" "" { target { ! implicit_constexpr } } }
   int x;
 };
 constexpr S s;
-constexpr T t;	// { dg-error "the type 'const T' of 'constexpr' variable 't' is not literal" }
+constexpr T t;	// { dg-error "the type 'const T' of 'constexpr' variable 't' is not literal" "" { target { ! implicit_constexpr } } }
 constexpr W0 w1;
 constexpr W0 w2 = 12;
 constexpr W1 w3 = 5;	// { dg-message "in 'constexpr' expansion of" }
@@ -167,19 +167,19 @@ constexpr int x5 = f5 ();	// { dg-message "in 'constexpr' expansion of" }
 void
 f6 ()
 {
-  constexpr T t2;	// { dg-error "the type 'const T' of 'constexpr' variable 't2' is not literal" }
+  constexpr T t2;	// { dg-error "the type 'const T' of 'constexpr' variable 't2' is not literal" "" { target { ! implicit_constexpr } } }
 }
 
 constexpr int
 f7 ()
 {
-  constexpr T t3;	// { dg-error "the type 'const T' of 'constexpr' variable 't3' is not literal" }
+  constexpr T t3;	// { dg-error "the type 'const T' of 'constexpr' variable 't3' is not literal" "" { target { ! implicit_constexpr } } }
   return 0;
 }
 
 constexpr int
 f8 ()
 {
-  T t4;			// { dg-error "variable 't4' of non-literal type 'T' in 'constexpr' function only available with" "" { target c++20_down } }
+  T t4;			// { dg-error "variable 't4' of non-literal type 'T' in 'constexpr' function only available with" "" { target { c++20_down && { ! implicit_constexpr } } } }
   return 0;
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new13.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new13.C
index 6762c24a34271fcc5caf149f75c9518595eb9568..7eed50c7f4cfdbd1313d8b505df92fe54a3d69de 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-new13.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new13.C
@@ -9,7 +9,7 @@ struct A {
 
 struct B : A {
   constexpr B () : b (0) {}
-  virtual int foo () { return 0 + b * 4; }	// { dg-message "declared here" }
+  virtual int foo () { return 0 + b * 4; }	// { dg-message "declared here" "" { target { ! implicit_constexpr } } }
   int b;
 };
 
@@ -18,7 +18,7 @@ foo ()
 {
   A *a = new B ();
   a->a = 4;
-  int r = a->foo ();	// { dg-error "call to non-.constexpr. function" }
+  int r = a->foo ();	// { dg-error "call to non-.constexpr. function" "" { target { ! implicit_constexpr } } }
   delete a;
   return r;
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit11.C b/gcc/testsuite/g++.dg/cpp2a/constinit11.C
index e8b3bcb570b7dd0e3d6f5876b73de275ee357782..b090277181411dadb3f3f2904c512138e165a8a2 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constinit11.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constinit11.C
@@ -39,9 +39,9 @@ constinit thread_local const int &r2 = gl;
 constinit const int &r3 // { dg-error "variable .r3. does not have a constant initializer" }
   = foo (); // { dg-error "call to non-.constexpr. function" }
 constinit const literal &r4 = 42;
-constinit const nonliteral &r5 // { dg-error "variable .r5. does not have a constant initializer" }
-  = 42; // { dg-error "call to non-.constexpr. function" }
-constinit const int &r6 = nonliteral(2).m; // { dg-error "variable .r6. does not have a constant initializer|call to non-.constexpr. function" }
+constinit const nonliteral &r5 // { dg-error "variable .r5. does not have a constant initializer" "" { target { ! implicit_constexpr } } }
+  = 42; // { dg-error "call to non-.constexpr. function" "" { target { ! implicit_constexpr } } }
+constinit const int &r6 = nonliteral(2).m; // { dg-error "variable .r6. does not have a constant initializer|call to non-.constexpr. function" "" { target { ! implicit_constexpr } } }
 
 constinit pod p1;
 constinit pod p2 = { 42 };
@@ -64,8 +64,8 @@ constinit thread_local literal l11{};
 pod S::p;
 constinit pod S::pc(S::p); // { dg-error "variable .S::pc. does not have a constant initializer|not usable" }
 
-constinit const nonliteral S::n(42); // { dg-error "variable .S::n. does not have a constant initializer|call to non-.constexpr. function" }
-constinit int n1 = nonliteral{42}.m; // { dg-error "variable .n1. does not have a constant initializer|temporary of non-literal type" }
+constinit const nonliteral S::n(42); // { dg-error "variable .S::n. does not have a constant initializer|call to non-.constexpr. function" "" { target { ! implicit_constexpr } } }
+constinit int n1 = nonliteral{42}.m; // { dg-error "variable .n1. does not have a constant initializer|temporary of non-literal type" "" { target { ! implicit_constexpr } } }
 constinit int n2 = literal{42}.m;
 
 void
diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit12.C b/gcc/testsuite/g++.dg/cpp2a/constinit12.C
index cc6569b2277b241235372c485f220339e2e8d53d..faa1b430cee96b3266a002f3d2e9b8b27e8b9bcf 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constinit12.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constinit12.C
@@ -8,7 +8,7 @@ struct S {
 template <class T>
 struct U {
   T m;
-  constexpr U(int i) : m(i) { } // { dg-error "call to non-.constexpr. function" }
+  constexpr U(int i) : m(i) { } // { dg-error "call to non-.constexpr. function" "" { target { ! implicit_constexpr } } }
 };
 
-constinit U<S> u(42); // { dg-error "does not have a constant initializer|called in a constant expression" }
+constinit U<S> u(42); // { dg-error "does not have a constant initializer|called in a constant expression" "" { target { ! implicit_constexpr } } }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit14.C b/gcc/testsuite/g++.dg/cpp2a/constinit14.C
index 86a058b632cccccdb0f8ad1d65251f09307490ce..06c4cb46722f6f4049fd7a9e0aafaac7a6f462a6 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constinit14.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constinit14.C
@@ -2,7 +2,7 @@
 // { dg-do compile { target c++20 } }
 
 struct Value {
-  Value() : v{new int{42}} {}
+  Value() : v{new int{42}} {}	// { dg-error "result of 'operator new'" "" { target implicit_constexpr } }
   int* v;
 };
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit15.C b/gcc/testsuite/g++.dg/cpp2a/constinit15.C
index 29e8b51326d4b07424c1176e13b6689610c93a48..b6215587badb54343e965481ff9732a02f378794 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constinit15.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constinit15.C
@@ -6,7 +6,7 @@ struct B {
 };
 
 struct A {
-    constinit static inline B b1{}; // { dg-error "does not have a constant initializer|call to non-.constexpr. function" }
+    constinit static inline B b1{}; // { dg-error "does not have a constant initializer|call to non-.constexpr. function" "" { target { ! implicit_constexpr } } }
 };
 
 int main() {
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C
index 6ccc7e8507bda90a2b02cde7e884c05f419ddad2..dff59271a1e67fdf6485c28fc2ed713fdb896bd5 100644
--- a/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C
@@ -9,7 +9,7 @@ struct A
 struct B
 {
   A a;
-  bool operator==(const B&) const = default; // { dg-error "A::operator==" }
+  bool operator==(const B&) const = default; // { dg-error "A::operator==" "" { target { ! implicit_constexpr } } }
 };
 
-constexpr bool x = B() == B();	// { dg-error "non-.constexpr" }
+constexpr bool x = B() == B();	// { dg-error "non-.constexpr" "" { target { ! implicit_constexpr } } }
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C
index d31faef095d0dac0cf9feb883fb5807fa4914f34..7a517a8016c4f1c15e3e343aaddbf64ddb507667 100644
--- a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C
@@ -12,5 +12,5 @@ struct D
 };
 
 constexpr D d{A()};
-static_assert (d == d);		// { dg-error "non-constant|constexpr" }
-static_assert (!(d != d));	// { dg-error "non-constant|constexpr" }
+static_assert (d == d);		// { dg-error "constant|constexpr" }
+static_assert (!(d != d));	// { dg-error "constant|constexpr" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg2.C b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg2.C
index 62cb86ae6954f1e6ef5152293d816d674818fa6d..ab7c012f5f47c481b95baa965a0b1ff40526026f 100644
--- a/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg2.C
+++ b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg2.C
@@ -9,5 +9,5 @@ struct non_literal_class {
   // auto operator<=> (const non_literal_fixed_string&) = default;
 };
 
-template <non_literal_class> // { dg-error "11:is not a valid type for a template non-type parameter because it is not structural" }
-int operator"" _udl();       // { dg-error "5:literal operator template .int operator\"\"_udl\\(\\). has invalid parameter list" }
+template <non_literal_class> // { dg-error "11:is not a valid type for a template non-type parameter because it is not structural" "" { target { ! implicit_constexpr } } }
+int operator"" _udl();       // { dg-error "5:literal operator template .int operator\"\"_udl\\(\\). has invalid parameter list" "" { target { ! implicit_constexpr } } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C b/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C
index 5daf3cd5c879bd8befa6c4fdb3e0a7eadc48d808..3e5867d258c8fb4ec0979192215211600bbbeecd 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C
@@ -1,6 +1,6 @@
 // PR c++/53756
 // { dg-do compile { target c++14 } }
-// { dg-options "-gdwarf-2 -dA -fno-debug-types-section" }
+// { dg-options "-gdwarf-2 -dA -fno-debug-types-section -fno-inline" }
 // We're looking for something like
 
 // .uleb128 0x3    # (DIE (0x33) DW_TAG_subprogram)
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/cdtor-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/cdtor-1.C
index c0d3d2251870a57b6330eb085dbc08da32d1d6dd..b211c02c894095722eb92f0862717c85f8ec7030 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/cdtor-1.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/cdtor-1.C
@@ -1,5 +1,5 @@
 // origin PR debug/49047
-// { dg-options "-gdwarf-2 -dA -fno-merge-debug-strings" }
+// { dg-options "-gdwarf-2 -dA -fno-merge-debug-strings -fno-implicit-constexpr" }
 // { dg-do compile }
 
 struct K
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lambda1.C b/gcc/testsuite/g++.dg/debug/dwarf2/lambda1.C
index bd3ce5dc807b99061b6fea721609b395d4e375db..b2566c7aa7a060a5b6733e61a0058d404569f9c1 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/lambda1.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lambda1.C
@@ -1,6 +1,6 @@
 // PR c++/43912
 // { dg-do compile { target c++11 } }
-// { dg-options "-gdwarf-2 -dA -fno-merge-debug-strings -gno-strict-dwarf" }
+// { dg-options "-gdwarf-2 -dA -fno-merge-debug-strings -gno-strict-dwarf -fno-inline" }
 
 // Check for the local alias variables that point to the members of the closure.
 // { dg-final { scan-assembler-times "DW_TAG_variable\[^.\]*\.ascii \"j.0\"" 4 { xfail { powerpc-ibm-aix* } } } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C b/gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C
index e7a6aa41c0d25a47ed742fed90a418e5d57c48c2..0a3721ee6b1bc302cb7e173836411b9b3d84b672 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C
@@ -1,6 +1,6 @@
 // PR debug/54508
 // { dg-do compile }
-// { dg-options "-gdwarf-2 -g2 -dA -fno-merge-debug-strings" }
+// { dg-options "-gdwarf-2 -g2 -dA -fno-merge-debug-strings -fno-inline" }
 
 // { dg-final { scan-assembler "\"cbase\\\\0\"\[ \t\]+\[#;/!|@\]+ +DW_AT_name" } }
 // { dg-final { scan-assembler "\"OPCODE\\\\0\"\[ \t\]+\[#;/!|@\]+ +DW_AT_name" } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C
index af0f6f1b95cf284b0004ab7dd81c813dec51e1d0..1fb5004df4012fc61de85fb7ea1268778d6dedb8 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C
@@ -1,6 +1,6 @@
 // { dg-do compile { target c++11 } }
 // { dg-skip-if "" { powerpc-ibm-aix* } }
-// { dg-options "-gpubnames -gdwarf-4 -fno-debug-types-section -dA" }
+// { dg-options "-gpubnames -gdwarf-4 -fno-debug-types-section -dA -fno-inline" }
 // { dg-final { scan-assembler-times "\.section\[\t \]\[^\n\]*debug_pubnames" 1 } }
 // { dg-final { scan-assembler "\"\\(anonymous namespace\\)\\\\0\"+\[ \t\]+\[#;/|@!]+\[ \t\]+external name" } }
 // { dg-final { scan-assembler "\"one\\\\0\"+\[ \t\]+\[#;/|@!]+\[ \t\]+external name" } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C
index 63b870bc8e7ba8d40fa24580c09e71f4537217c5..37e04fb6c972c603cb822dd620b2ea3c6b9e0e83 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C
@@ -1,6 +1,6 @@
 // { dg-do compile { target c++11 } }
 // { dg-skip-if "" { powerpc-ibm-aix* } }
-// { dg-options "-gpubnames -gdwarf-4 -fdebug-types-section -dA" }
+// { dg-options "-gpubnames -gdwarf-4 -fdebug-types-section -dA -fno-inline" }
 // { dg-final { scan-assembler-times "\.section\[\t \]\[^\n\]*debug_pubnames" 1 } }
 // { dg-final { scan-assembler "\"\\(anonymous namespace\\)\\\\0\"+\[ \t\]+\[#;/|@!]+\[ \t\]+external name" } }
 // { dg-final { scan-assembler "\"one\\\\0\"+\[ \t\]+\[#;/|@!]+\[ \t\]+external name" } }
diff --git a/gcc/testsuite/g++.dg/ext/is_literal_type3.C b/gcc/testsuite/g++.dg/ext/is_literal_type3.C
index 22d8494a2b47a913caca3d1efc1c61d8ea6c321a..4fede879a42a13c6b54dffba6fc10fc5e6f5d2f3 100644
--- a/gcc/testsuite/g++.dg/ext/is_literal_type3.C
+++ b/gcc/testsuite/g++.dg/ext/is_literal_type3.C
@@ -6,7 +6,11 @@ struct S {
   int n;
 };
 
+#if __cpp_implicit_constexpr
+static_assert(__is_literal_type(S), "");
+#else
 static_assert(!__is_literal_type(S), "");
+#endif
 
 #ifdef __cpp_constexpr_dynamic_alloc
 struct T {
diff --git a/gcc/testsuite/g++.dg/ext/visibility/template7.C b/gcc/testsuite/g++.dg/ext/visibility/template7.C
index 5197fb1c960398cd347ba2aa8a9b252f6351d1b3..f1490fa3d32dd145109a261d8694311273de71f6 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/template7.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/template7.C
@@ -1,6 +1,6 @@
 // PR c++/35688
 // { dg-require-visibility "" }
-// { dg-options "-fvisibility=hidden" }
+// { dg-options "-fvisibility=hidden -fno-inline" }
 
 // { dg-final { scan-hidden "_ZN1s6vectorI1AEC1Ev" } }
 // { dg-final { scan-hidden "_ZN1s3fooI1AEEvT_" } }
diff --git a/gcc/testsuite/g++.dg/gcov/gcov-12.C b/gcc/testsuite/g++.dg/gcov/gcov-12.C
index c4708e40726b7ce813064c15d9df1d49e24beb15..9f2b29b4da501fe5cd35bd67145b6491a6cb447e 100644
--- a/gcc/testsuite/g++.dg/gcov/gcov-12.C
+++ b/gcc/testsuite/g++.dg/gcov/gcov-12.C
@@ -1,5 +1,5 @@
 /* PR 51113 */
-/* { dg-options "-fprofile-arcs -ftest-coverage -fpic" } */
+/* { dg-options "-fprofile-arcs -ftest-coverage -fpic -fno-implicit-constexpr" } */
 /* { dg-do run { target native } } */
 /* { dg-additional-sources "gcovpart-12b.C" } */
 
diff --git a/gcc/testsuite/g++.dg/gcov/gcov-2.C b/gcc/testsuite/g++.dg/gcov/gcov-2.C
index 2b4cdd844e95c7871ca02c9e2c3d4eb24c5ae41a..05db15de7cc5896dfb96739efd3dd8c0f8b51ec7 100644
--- a/gcc/testsuite/g++.dg/gcov/gcov-2.C
+++ b/gcc/testsuite/g++.dg/gcov/gcov-2.C
@@ -1,6 +1,6 @@
 /* Verify line coverage counts for simple member functions. */
 
-/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-options "-fprofile-arcs -ftest-coverage -fno-implicit-constexpr" } */
 /* { dg-do run { target native } } */
 
 class C {
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-35.C b/gcc/testsuite/g++.dg/ipa/devirt-35.C
index 87f72b89984e8d9148a993871fa28972a12e1e56..ca9ccb7a1334d8f45addb881435aa9b3edddff11 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-35.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-35.C
@@ -15,7 +15,6 @@ m(struct B *b)
                   //  test2 may change the type of A by placement new.
                   // C++ standard is bit imprecise about this.
 }
-/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t"  "fre1"  } } */
-/* { dg-final { scan-ipa-dump "to virtual int B::t"  "devirt"  } } */
+/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t"  "fre1" { target { ! implicit_constexpr } } } } */
+/* { dg-final { scan-ipa-dump "to virtual int B::t"  "devirt" { target { ! implicit_constexpr } } } } */
 /* { dg-final { scan-ipa-dump "1 speculatively devirtualized"  "devirt"  } } */
-
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-36.C b/gcc/testsuite/g++.dg/ipa/devirt-36.C
index 067a2bb8ca19336d156fbdaeb078269a0e6beee8..60b830186bb7553c8a1415fd71261158f0a611a8 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-36.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-36.C
@@ -18,7 +18,7 @@ m(struct B *b)
                   //  test2 may change the type of A by placement new.
                   // C++ standard is bit imprecise about this.
 }
-/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t"  "fre1"  } } */
-/* { dg-final { scan-ipa-dump "to virtual int B::t"  "devirt"  } } */
+/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t"  "fre1" { target { ! implicit_constexpr } } } } */
+/* { dg-final { scan-ipa-dump "to virtual int B::t"  "devirt" { target { ! implicit_constexpr } } } } */
 /* { dg-final { scan-ipa-dump "1 speculatively devirtualized"  "devirt"  } } */
 
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-37.C b/gcc/testsuite/g++.dg/ipa/devirt-37.C
index b7f52a0a5e9d350b22d76a1cf8c85f24ac926d6f..df5ab901f82a7604b7cbde021ff71371f5421f43 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-37.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-37.C
@@ -33,4 +33,4 @@ t()
 /* { dg-final { scan-tree-dump "No dynamic type change found."  "fre3"  } } */
 /* { dg-final { scan-tree-dump "Checking vtbl store:"  "fre3"  } } */
 /* { dg-final { scan-tree-dump "Function call may change dynamic type:extcall"  "fre3"  } } */
-/* { dg-final { scan-tree-dump "converting indirect call to function virtual void"  "fre3"  } } */
+/* { dg-final { scan-tree-dump "converting indirect call to function virtual void"  "fre3" { target { ! implicit_constexpr } } } } */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-44.C b/gcc/testsuite/g++.dg/ipa/devirt-44.C
index 5de761412d0560b15bfaf01bad184ee70e5990ef..ed211e1173997eb10bf895d7bb0404ccf85b25ef 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-44.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-44.C
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O3 -fno-ipa-cp -fdump-ipa-inline-details -fno-early-inlining" } */
+/* { dg-options "-O3 -fno-ipa-cp -fdump-ipa-inline-details -fno-early-inlining -fno-implicit-constexpr" } */
 struct A {
   virtual int foo () {return 1;}
   void wrapfoo () {foo();}
diff --git a/gcc/testsuite/g++.dg/ipa/imm-devirt-1.C b/gcc/testsuite/g++.dg/ipa/imm-devirt-1.C
index 00ac61e7f3848152d3e342e88397453dcafb9f21..fa31cfbae5452929375a82ace2acaa8b65d03978 100644
--- a/gcc/testsuite/g++.dg/ipa/imm-devirt-1.C
+++ b/gcc/testsuite/g++.dg/ipa/imm-devirt-1.C
@@ -60,7 +60,7 @@ int main (int argc, char *argv[])
 
 /* middleman_2 gets early inlined and the virtual call should get turned to
    a direct call.  */
-/* { dg-final { scan-tree-dump "Inlining int middleman_1" "einline"  } } */
-/* { dg-final { scan-tree-dump "Inlining int middleman_2" "einline"  } } */
+/* { dg-final { scan-tree-dump "Inlining int middleman_1" "einline" { target { ! implicit_constexpr } } } } */
+/* { dg-final { scan-tree-dump "Inlining int middleman_2" "einline" { target { ! implicit_constexpr } } } } */
 /* { dg-final { scan-tree-dump "B::foo \\(" "einline"  } } */
 /* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 2 "einline"  } } */
diff --git a/gcc/testsuite/g++.dg/lookup/builtin5.C b/gcc/testsuite/g++.dg/lookup/builtin5.C
index 1bd67dce5ac608db67253d33e3d66177659162dd..652e3f58b67831c2dbe2556ceb01dbc294ea2593 100644
--- a/gcc/testsuite/g++.dg/lookup/builtin5.C
+++ b/gcc/testsuite/g++.dg/lookup/builtin5.C
@@ -1,5 +1,5 @@
 // PR c++/37276
-
+// { dg-additional-options -fno-inline }
 // { dg-final { scan-assembler "_ZSt5atanhd" } }
 
 namespace std
diff --git a/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C b/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C
index adbc43ea2534db913d3925de0aec9f87244c5ae3..0294dcc4bfb7000c6a3338f855f541d0760be27d 100644
--- a/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C
+++ b/gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C
@@ -1,5 +1,5 @@
 // { dg-lto-do link }
-/* { dg-lto-options { "-O2 -fno-early-inlining -flto -fdump-ipa-inline-details" } } */
+/* { dg-lto-options { "-O2 -fno-early-inlining -fno-implicit-constexpr -flto -fdump-ipa-inline-details" } } */
 #include "inline-crossmodule-1.h"
 int a::key ()
 {
diff --git a/gcc/testsuite/g++.dg/modules/enum-1_a.C b/gcc/testsuite/g++.dg/modules/enum-1_a.C
index 53e2ac88f2082c8501388a9b582a618085caa651..24cad2864648476d63a86a6e824d53062cbf9788 100644
--- a/gcc/testsuite/g++.dg/modules/enum-1_a.C
+++ b/gcc/testsuite/g++.dg/modules/enum-1_a.C
@@ -1,5 +1,5 @@
 // { dg-module-do run }
-// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid" }
+// { dg-additional-options "-fmodules-ts -fdump-lang-module-uid -fno-implicit-constexpr" }
 export module enUm;
 // { dg-module-cmi "enUm" }
 
diff --git a/gcc/testsuite/g++.dg/modules/fn-inline-1_c.C b/gcc/testsuite/g++.dg/modules/fn-inline-1_c.C
index 55a7aaa26b46c225c90b656255dd0ffdc5fee663..2b8bbdcd1af96b30483be01c2de61d5e9c15f055 100644
--- a/gcc/testsuite/g++.dg/modules/fn-inline-1_c.C
+++ b/gcc/testsuite/g++.dg/modules/fn-inline-1_c.C
@@ -1,4 +1,4 @@
-// { dg-additional-options "-fmodules-ts" }
+// { dg-additional-options "-fmodules-ts -fno-inline" }
 import bob;
 
 int main ()
diff --git a/gcc/testsuite/g++.dg/modules/pmf-1_a.H b/gcc/testsuite/g++.dg/modules/pmf-1_a.H
index c597db1fe8abc899ca522fa94a283d63b4f41ab9..a7b3fc370ecdf80089f65a90e49954e8a1679a2c 100644
--- a/gcc/testsuite/g++.dg/modules/pmf-1_a.H
+++ b/gcc/testsuite/g++.dg/modules/pmf-1_a.H
@@ -1,4 +1,4 @@
-// { dg-additional-options -fmodule-header }
+// { dg-additional-options "-fmodule-header -fno-implicit-constexpr" }
 // { dg-module-cmi {} }
 
 #include "pmf-1.h"
diff --git a/gcc/testsuite/g++.dg/modules/pmf-1_b.C b/gcc/testsuite/g++.dg/modules/pmf-1_b.C
index 0b086107045383bb2843a9edca9668cff948ffa2..cb2a35bbc3b1a998c056f3b9fb210d682bf0a871 100644
--- a/gcc/testsuite/g++.dg/modules/pmf-1_b.C
+++ b/gcc/testsuite/g++.dg/modules/pmf-1_b.C
@@ -1,4 +1,4 @@
-// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias" }
+// { dg-additional-options "-fmodules-ts -fno-module-lazy -fdump-lang-module-alias -fno-implicit-constexpr" }
 
 #include "pmf-1.h"
 import "pmf-1_a.H";
diff --git a/gcc/testsuite/g++.dg/modules/used-1_c.C b/gcc/testsuite/g++.dg/modules/used-1_c.C
index 0d1514e031cae0936cca8998d4513e13827e4f1e..b51a19fb8d754f5520a749a654bd38dffed05ff3 100644
--- a/gcc/testsuite/g++.dg/modules/used-1_c.C
+++ b/gcc/testsuite/g++.dg/modules/used-1_c.C
@@ -1,4 +1,4 @@
-// { dg-additional-options -fmodules-ts }
+// { dg-additional-options "-fmodules-ts -fno-inline" }
 
 import "used-1_b.H";
 
diff --git a/gcc/testsuite/g++.dg/tls/thread_local11.C b/gcc/testsuite/g++.dg/tls/thread_local11.C
index 273ee03d70256a6cb0118041ee294b99060d5bcb..7e83a4537543a41efb7ea7ffb9194985f7687cd1 100644
--- a/gcc/testsuite/g++.dg/tls/thread_local11.C
+++ b/gcc/testsuite/g++.dg/tls/thread_local11.C
@@ -2,7 +2,7 @@
 // { dg-do compile { target c++11 } }
 // { dg-add-options tls }
 // { dg-require-effective-target tls_runtime }
-// { dg-additional-options "-fdump-tree-gimple" }
+// { dg-additional-options "-fdump-tree-gimple -fno-implicit-constexpr" }
 // { dg-final { scan-tree-dump-times "_ZTW2s1" 2 "gimple" } }
 // { dg-final { scan-tree-dump-times "_ZTW2s2" 2 "gimple" } }
 // { dg-final { scan-tree-dump-times "_ZTW2s3" 2 "gimple" } }
diff --git a/gcc/testsuite/g++.dg/tls/thread_local11a.C b/gcc/testsuite/g++.dg/tls/thread_local11a.C
index d8c4a6dc0ab85513a18fc49df1449023c6a4f437..a6283984eb79d58e9e8d55d199e2478af7bd1a02 100644
--- a/gcc/testsuite/g++.dg/tls/thread_local11a.C
+++ b/gcc/testsuite/g++.dg/tls/thread_local11a.C
@@ -3,7 +3,7 @@
 // { dg-add-options tls }
 // { dg-require-alias "" }
 // { dg-require-effective-target tls_runtime }
-// { dg-additional-options "-fdump-tree-gimple" }
+// { dg-additional-options "-fdump-tree-gimple -fno-implicit-constexpr" }
 // { dg-final { scan-tree-dump-times "_ZTH2s1" 1 "gimple" } }
 // { dg-final { scan-tree-dump-times "_ZTH2s2" 1 "gimple" } }
 // { dg-final { scan-tree-dump-times "_ZTH2s3" 1 "gimple" } }
diff --git a/gcc/testsuite/g++.dg/tm/pr46653.C b/gcc/testsuite/g++.dg/tm/pr46653.C
index f8f3a1d3117fa6b43408f22b95cf408216e7f56c..a4649eb5ffc941f15b80204f9afe37f7c135331c 100644
--- a/gcc/testsuite/g++.dg/tm/pr46653.C
+++ b/gcc/testsuite/g++.dg/tm/pr46653.C
@@ -1,5 +1,5 @@
 // { dg-do compile }
-// { dg-options "-fgnu-tm -O" }
+// { dg-options "-fgnu-tm -O -fno-implicit-constexpr" }
 
 class shared_count
 {
diff --git a/gcc/testsuite/g++.dg/ubsan/pr70035.C b/gcc/testsuite/g++.dg/ubsan/pr70035.C
index a1d3dc2ec1698a9ab0667e18571989ec35f523eb..521dcb8d8c022cd9dc8d8c4d3bbba5e6cd4ac942 100644
--- a/gcc/testsuite/g++.dg/ubsan/pr70035.C
+++ b/gcc/testsuite/g++.dg/ubsan/pr70035.C
@@ -1,7 +1,7 @@
 // PR c++/70035
 // { dg-do run }
 // { dg-shouldfail "ubsan" }
-// { dg-options "-fsanitize=vptr -fno-sanitize-recover=undefined" }
+// { dg-options "-fsanitize=vptr -fno-sanitize-recover=undefined -fno-implicit-constexpr" }
 
 struct A {
   A (int) {}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/delete6.C b/gcc/testsuite/g++.old-deja/g++.other/delete6.C
index 733a6e22cb9b9b2a14718931c7775c90021e417c..56cfa000e8d531562a6f576a75aa3ecea15942ba 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/delete6.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/delete6.C
@@ -25,4 +25,4 @@ inline void A::operator delete(void*p)
 
 int main()
 {A *ap=new A;
-delete ap;}
+delete ap;}			// { dg-prune-output "unallocated object 'i'" }
diff --git a/gcc/testsuite/lib/g++-dg.exp b/gcc/testsuite/lib/g++-dg.exp
index c360770a7a20251f19d7d7003abb12dbba2d4676..fd06d278faafaf3d657842ca135c564e22cebefc 100644
--- a/gcc/testsuite/lib/g++-dg.exp
+++ b/gcc/testsuite/lib/g++-dg.exp
@@ -57,7 +57,8 @@ proc g++-dg-runtest { testcases flags default-extra-flags } {
 	    set option_list { }
 	    foreach x $std_list {
 		# Handle "concepts" as C++17 plus Concepts TS.
-		if { $x eq "concepts" } then { set x "17 -fconcepts" }
+		if { $x eq "concepts" } then { set x "17 -fconcepts"
+		} elseif { $x eq "impcx" } then { set x "23 -fimplicit-constexpr" }
 		lappend option_list "${std_prefix}$x"
 	    }
 	} else {
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 8cbda192fe0fae59ea208ee43696b4d22c43e61e..c928d99a14be1192b5f4154a833b9fef5c8cf0e7 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -10232,6 +10232,10 @@ proc check_effective_target_concepts { } {
     return [check-flags { "" { } { -fconcepts } }]
 }
 
+proc check_effective_target_implicit_constexpr { } {
+    return [check-flags { "" { } { -fimplicit-constexpr } }]
+}
+
 # Return 1 if expensive testcases should be run.
 
 proc check_effective_target_run_expensive_tests { } {
diff --git a/libstdc++-v3/testsuite/20_util/to_address/1_neg.cc b/libstdc++-v3/testsuite/20_util/to_address/1_neg.cc
index ff3a1fbcb5dd6ba70e3c5e547a9ae419212e8ae2..5030f89b345287a7d604778d6ebdac5512641321 100644
--- a/libstdc++-v3/testsuite/20_util/to_address/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/to_address/1_neg.cc
@@ -32,5 +32,5 @@ struct P
 void test01()
 {
   P p;
-  std::to_address(p); // { dg-error "required from here" }
+  std::to_address(p); // { dg-error "" }
 }
diff --git a/libstdc++-v3/testsuite/26_numerics/random/concept.cc b/libstdc++-v3/testsuite/26_numerics/random/concept.cc
index 1adc0c11baaa6d32f05b6434e2eca0a11f4e8020..0a0cbbf7c4e1f624cc482d65fd5e87df9609bc5a 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/concept.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/concept.cc
@@ -227,7 +227,11 @@ struct N12
   static constexpr unsigned max() { return 1; }
 };
 
+#if __cpp_implicit_constexpr
+static_assert( std::uniform_random_bit_generator<N12> ); // LWG 3150
+#else
 static_assert( ! std::uniform_random_bit_generator<N12> ); // LWG 3150
+#endif
 
 struct N13
 {
@@ -236,7 +240,11 @@ struct N13
   static unsigned max() { return 1; } // not constexpr
 };
 
+#if __cpp_implicit_constexpr
+static_assert( std::uniform_random_bit_generator<N13> ); // LWG 3150
+#else
 static_assert( ! std::uniform_random_bit_generator<N13> ); // LWG 3150
+#endif
 
 struct N14
 {