c++: Add -fimplicit-constexpr
With each successive C++ standard the restrictions on the use of the constexpr keyword for functions get weaker and weaker; it recently occurred to me that it is heading toward the same fate as the C register keyword, which was once useful for optimization but became obsolete. Similarly, it seems to me that we should be able to just treat inlines as constexpr functions and not make people add the extra keyword everywhere. There were a lot of testcase changes needed; many disabling errors about non-constexpr functions that are now constexpr, and many disabling implicit constexpr so that the tests can check the same thing as before, whether that's mangling or whatever. gcc/c-family/ChangeLog: * c.opt: Add -fimplicit-constexpr. * c-cppbuiltin.c: Define __cpp_implicit_constexpr. * c-opts.c (c_common_post_options): Disable below C++14. gcc/cp/ChangeLog: * cp-tree.h (struct lang_decl_fn): Add implicit_constexpr. (decl_implicit_constexpr_p): New. * class.c (type_maybe_constexpr_destructor): Use TYPE_HAS_TRIVIAL_DESTRUCTOR and maybe_constexpr_fn. (finalize_literal_type_property): Simplify. * constexpr.c (is_valid_constexpr_fn): Check for dtor. (maybe_save_constexpr_fundef): Try to set DECL_DECLARED_CONSTEXPR_P on inlines. (cxx_eval_call_expression): Use maybe_constexpr_fn. (maybe_constexpr_fn): Handle flag_implicit_constexpr. (var_in_maybe_constexpr_fn): Use maybe_constexpr_fn. (potential_constant_expression_1): Likewise. (decl_implicit_constexpr_p): New. * decl.c (validate_constexpr_redeclaration): Allow change with -fimplicit-constexpr. (grok_special_member_properties): Use maybe_constexpr_fn. * error.c (dump_function_decl): Don't print 'constexpr' if it's implicit. * Make-lang.in (check-c++-all): Update. libstdc++-v3/ChangeLog: * testsuite/20_util/to_address/1_neg.cc: Adjust error. * testsuite/26_numerics/random/concept.cc: Adjust asserts. gcc/testsuite/ChangeLog: * lib/g++-dg.exp: Handle "impcx". * lib/target-supports.exp (check_effective_target_implicit_constexpr): New. * g++.dg/abi/abi-tag16.C: * g++.dg/abi/abi-tag18a.C: * g++.dg/abi/guard4.C: * g++.dg/abi/lambda-defarg1.C: * g++.dg/abi/mangle26.C: * g++.dg/cpp0x/constexpr-diag3.C: * g++.dg/cpp0x/constexpr-ex1.C: * g++.dg/cpp0x/constexpr-ice5.C: * g++.dg/cpp0x/constexpr-incomplete2.C: * g++.dg/cpp0x/constexpr-memfn1.C: * g++.dg/cpp0x/constexpr-neg3.C: * g++.dg/cpp0x/constexpr-specialization.C: * g++.dg/cpp0x/inh-ctor19.C: * g++.dg/cpp0x/inh-ctor30.C: * g++.dg/cpp0x/lambda/lambda-mangle3.C: * g++.dg/cpp0x/lambda/lambda-mangle5.C: * g++.dg/cpp1y/auto-fn12.C: * g++.dg/cpp1y/constexpr-loop5.C: * g++.dg/cpp1z/constexpr-lambda7.C: * g++.dg/cpp2a/constexpr-dtor3.C: * g++.dg/cpp2a/constexpr-new13.C: * g++.dg/cpp2a/constinit11.C: * g++.dg/cpp2a/constinit12.C: * g++.dg/cpp2a/constinit14.C: * g++.dg/cpp2a/constinit15.C: * g++.dg/cpp2a/spaceship-constexpr1.C: * g++.dg/cpp2a/spaceship-eq3.C: * g++.dg/cpp2a/udlit-class-nttp-neg2.C: * g++.dg/debug/dwarf2/auto1.C: * g++.dg/debug/dwarf2/cdtor-1.C: * g++.dg/debug/dwarf2/lambda1.C: * g++.dg/debug/dwarf2/pr54508.C: * g++.dg/debug/dwarf2/pubnames-2.C: * g++.dg/debug/dwarf2/pubnames-3.C: * g++.dg/ext/is_literal_type3.C: * g++.dg/ext/visibility/template7.C: * g++.dg/gcov/gcov-12.C: * g++.dg/gcov/gcov-2.C: * g++.dg/ipa/devirt-35.C: * g++.dg/ipa/devirt-36.C: * g++.dg/ipa/devirt-37.C: * g++.dg/ipa/devirt-44.C: * g++.dg/ipa/imm-devirt-1.C: * g++.dg/lookup/builtin5.C: * g++.dg/lto/inline-crossmodule-1_0.C: * g++.dg/modules/enum-1_a.C: * g++.dg/modules/fn-inline-1_c.C: * g++.dg/modules/pmf-1_b.C: * g++.dg/modules/used-1_c.C: * g++.dg/tls/thread_local11.C: * g++.dg/tls/thread_local11a.C: * g++.dg/tm/pr46653.C: * g++.dg/ubsan/pr70035.C: * g++.old-deja/g++.other/delete6.C: * g++.dg/modules/pmf-1_a.H: Adjust for implicit constexpr.
This commit is contained in:
parent
29e4163a09
commit
87c2080b05
68 changed files with 211 additions and 103 deletions
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"))) {
|
||||
|
|
|
@ -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" } }
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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; }(),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 } } }
|
||||
|
||||
// --------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 } } }
|
||||
};
|
||||
|
|
|
@ -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 } } }
|
||||
|
|
|
@ -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 } } }
|
||||
};
|
||||
|
|
|
@ -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 } } }
|
||||
|
|
|
@ -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 } } }
|
||||
|
|
|
@ -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 } } }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 } } }
|
||||
}
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 } } }
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 } } }
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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 } } }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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* } } } }
|
||||
|
|
|
@ -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" } }
|
||||
|
|
|
@ -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" } }
|
||||
|
|
|
@ -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" } }
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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_" } }
|
||||
|
|
|
@ -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" } */
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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" } } */
|
||||
|
||||
|
|
|
@ -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" } } */
|
||||
|
||||
|
|
|
@ -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 } } } } */
|
||||
|
|
|
@ -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();}
|
||||
|
|
|
@ -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" } } */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// PR c++/37276
|
||||
|
||||
// { dg-additional-options -fno-inline }
|
||||
// { dg-final { scan-assembler "_ZSt5atanhd" } }
|
||||
|
||||
namespace std
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
|
|
|
@ -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" }
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// { dg-additional-options "-fmodules-ts" }
|
||||
// { dg-additional-options "-fmodules-ts -fno-inline" }
|
||||
import bob;
|
||||
|
||||
int main ()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// { dg-additional-options -fmodule-header }
|
||||
// { dg-additional-options "-fmodule-header -fno-implicit-constexpr" }
|
||||
// { dg-module-cmi {} }
|
||||
|
||||
#include "pmf-1.h"
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// { dg-additional-options -fmodules-ts }
|
||||
// { dg-additional-options "-fmodules-ts -fno-inline" }
|
||||
|
||||
import "used-1_b.H";
|
||||
|
||||
|
|
|
@ -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" } }
|
||||
|
|
|
@ -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" } }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// { dg-do compile }
|
||||
// { dg-options "-fgnu-tm -O" }
|
||||
// { dg-options "-fgnu-tm -O -fno-implicit-constexpr" }
|
||||
|
||||
class shared_count
|
||||
{
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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'" }
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 { } {
|
||||
|
|
|
@ -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 "" }
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue