diff options
Diffstat (limited to 'gcc')
66 files changed, 202 insertions, 102 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 { } { |