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 {