aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c-family/c-cppbuiltin.c2
-rw-r--r--gcc/c-family/c-opts.c3
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/cp/Make-lang.in2
-rw-r--r--gcc/cp/class.c11
-rw-r--r--gcc/cp/constexpr.c85
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/decl.c8
-rw-r--r--gcc/cp/error.c3
-rw-r--r--gcc/testsuite/g++.dg/abi/abi-tag16.C2
-rw-r--r--gcc/testsuite/g++.dg/abi/abi-tag18a.C2
-rw-r--r--gcc/testsuite/g++.dg/abi/guard4.C3
-rw-r--r--gcc/testsuite/g++.dg/abi/lambda-defarg1.C1
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle26.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ice5.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-neg3.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-specialization.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor19.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor30.C1
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle3.C1
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle5.C1
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/auto-fn12.C1
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-loop5.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-lambda7.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-dtor3.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-new13.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constinit11.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constinit12.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constinit14.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constinit15.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-constexpr1.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg2.C4
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/auto1.C2
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/cdtor-1.C2
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/lambda1.C2
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/pr54508.C2
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C2
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/is_literal_type3.C4
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/template7.C2
-rw-r--r--gcc/testsuite/g++.dg/gcov/gcov-12.C2
-rw-r--r--gcc/testsuite/g++.dg/gcov/gcov-2.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-35.C5
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-36.C4
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-37.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-44.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/imm-devirt-1.C4
-rw-r--r--gcc/testsuite/g++.dg/lookup/builtin5.C2
-rw-r--r--gcc/testsuite/g++.dg/lto/inline-crossmodule-1_0.C2
-rw-r--r--gcc/testsuite/g++.dg/modules/enum-1_a.C2
-rw-r--r--gcc/testsuite/g++.dg/modules/fn-inline-1_c.C2
-rw-r--r--gcc/testsuite/g++.dg/modules/pmf-1_a.H2
-rw-r--r--gcc/testsuite/g++.dg/modules/pmf-1_b.C2
-rw-r--r--gcc/testsuite/g++.dg/modules/used-1_c.C2
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local11.C2
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local11a.C2
-rw-r--r--gcc/testsuite/g++.dg/tm/pr46653.C2
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr70035.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/delete6.C2
-rw-r--r--gcc/testsuite/lib/g++-dg.exp3
-rw-r--r--gcc/testsuite/lib/target-supports.exp4
-rw-r--r--libstdc++-v3/testsuite/20_util/to_address/1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/concept.cc8
68 files changed, 211 insertions, 103 deletions
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 60e9e05..eb34d5a 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 0225cba..62f5829 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 06457ac..8a4cd63 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 8469424..de1fc02 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 bf92300..c30a44f 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 c92db5d..69d9d3d 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 f387b50..acc98c9 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 eed4781..2ddf0e4 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 012a4ec..8724793 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 d4fa142..3027d79 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 95e192a..c6fb160 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 537c905..71e6744 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 8c53858..79e4fa6 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 5d16095..2041d77 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 1c43569..c167bb1 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 e5e58bd..1d5c58b 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 51b328e..e934421 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 a04f1d5..c018ede 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 d58e2ec..3725528 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 55bb838..89559d7 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 64d8f4e..acda6e0 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 7e2d58b..3476f96 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 04c5863..c978f0c 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 5f17a21..2120d8c 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 dd95894..23df3a2 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 224f278..9888579 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 02f372d..150aadf 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 474ce88..faac00c 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 69fe9e2..a68a6b4 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 6762c24..7eed50c 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 e8b3bcb..b090277 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 cc6569b..faa1b43 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 86a058b..06c4cb4 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 29e8b51..b621558 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 6ccc7e8..dff5927 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 d31faef..7a517a8 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 62cb86a..ab7c012 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 5daf3cd..3e5867d 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 c0d3d22..b211c02 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 bd3ce5d..b2566c7 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 e7a6aa4..0a3721e 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 af0f6f1..1fb5004 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 63b870b..37e04fb 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 22d8494..4fede87 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 5197fb1..f1490fa 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 c4708e4..9f2b29b 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 2b4cdd8..05db15d 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 87f72b8..ca9ccb7 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 067a2bb..60b8301 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 b7f52a0..df5ab90 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 5de7614..ed211e1 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 00ac61e7..fa31cfb 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 1bd67dc..652e3f5 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 adbc43e..0294dcc 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 53e2ac8..24cad28 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 55a7aaa..2b8bbdc 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 c597db1..a7b3fc3 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 0b08610..cb2a35b 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 0d1514e..b51a19f 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 273ee03..7e83a45 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 d8c4a6d..a628398 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 f8f3a1d..a4649eb 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 a1d3dc2..521dcb8 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 733a6e2..56cfa00 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 c360770..fd06d27 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 8cbda19..c928d99 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 ff3a1fb..5030f89 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 1adc0c1..0a0cbbf 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
{