Age | Commit message (Collapse) | Author | Files | Lines |
|
My r16-2065 adding missed errors for auto in a template arg in a lambda
parameter also introduced a bogus error on this testcase, where the auto is
both in a lambda parameter and in a template arg, but in the other order,
which is OK. So we should clear in_template_argument_list_p for lambdas
like we do so many other parser flags.
PR c++/121012
PR c++/120917
gcc/cp/ChangeLog:
* parser.cc (cp_parser_lambda_expression): Clear
parser->in_template_argument_list_p.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/lambda-targ17.C: New test.
|
|
In r16-970 I changed finish_this_expr to look at current_class_type rather
than current_class_ptr to accommodate explicit object lambdas. But here in
a lambda in the noexcept-spec, the closure type doesn't yet have the
function as its context, so lambda_expr_this_capture can't find the function
and gives up. But in this context current_class_ptr refers to the
function's 'this', so let's go back to using it in that case.
PR c++/121008
PR c++/113563
gcc/cp/ChangeLog:
* semantics.cc (finish_this_expr): Do check current_class_ref for
non-lambda.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/lambda-uneval28.C: New test.
|
|
Found while working on Reflection where we currently reject:
constexpr auto r = ^^::template C<int>::type;
which should work, because "::template C<int>::" should match the
nested-name-specifier template(opt) simple-template-id ::
production where the template is optional. This bug is not limited
to Reflection as demonstrated by the attached test case, so I'm
submitting it separately.
The check_template_keyword_in_nested_name_spec call should ensure that
we're dealing with a template-id if we've seen "template".
PR c++/119838
gcc/cp/ChangeLog:
* parser.cc (cp_parser_nested_name_specifier_opt): New global_p
parameter. Look for "template" when global_p is true.
(cp_parser_simple_type_specifier): Pass global_p to
cp_parser_nested_name_specifier_opt.
gcc/testsuite/ChangeLog:
* g++.dg/parse/template32.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
|
|
While working on Reflection I noticed that we reject:
union U { int i; };
constexpr auto r = ^^typename ::U;
which is due to PR83469. Andrew P. posted a patch in 2021:
https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586344.html
for which I had some comments but an updated patch never came.
~~
There are a few issues here with typenames and unions (and even struct
keywords with unions). First in cp_parser_check_class_key,
we need to allow typenames to name union types and union key
to be able to use with typenames.
The next issue is we need to record if we had a union key,
right now we just record it was a struct/class/typename one
which is wrong.
~~
This patch is an updated and cleaned up version; I've also addressed
a missing bit in pt.cc.
PR c++/83469
PR c++/93809
gcc/cp/ChangeLog:
* cp-tree.h (UNION_TYPE_P): Define.
(TYPENAME_IS_UNION_P): Define.
* decl.cc (struct typename_info): Add union_p field.
(struct typename_hasher::equal): Compare union_p field.
(build_typename_type): Use ti.union_p for union_type. Set
TYPENAME_IS_UNION_P.
* error.cc (dump_type) <case TYPENAME_TYPE>: Handle
TYPENAME_IS_UNION_P.
* module.cc (trees_out::type_node): Likewise.
* parser.cc (cp_parser_check_class_key): Allow typename key for union
types and allow union keyword for typename types.
* pt.cc (tsubst) <case TYPENAME_TYPE>: Don't conflate unions with
class_type. For TYPENAME_IS_CLASS_P, check NON_UNION_CLASS_TYPE_P
rather than CLASS_TYPE_P. Add TYPENAME_IS_UNION_P handling.
gcc/testsuite/ChangeLog:
* g++.dg/template/error45.C: Adjust dg-error.
* g++.dg/warn/Wredundant-tags-3.C: Remove xfail.
* g++.dg/parse/union1.C: New test.
* g++.dg/parse/union2.C: New test.
* g++.dg/parse/union3.C: New test.
* g++.dg/parse/union4.C: New test.
* g++.dg/parse/union5.C: New test.
* g++.dg/parse/union6.C: New test.
Co-authored-by: Andrew Pinski <quic_apinski@quicinc.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
The following patch implements the constexpr structured bindings part of
the P2686R4 paper, so the [dcl.pre], [dcl.struct.bind], [dcl.constinit]
and first hunk in [dcl.constexpr] changes.
The paper doesn't have a feature test macro and the constexpr structured
binding part of it seems more-less self-contained, so I think it is useful
to get this in independently from the rest.
Of course, automatic constexpr/constinit structured bindings in the
tuple cases or automatic constexpr/constinit structured bindings with auto &
will not really work for now.
Another reason for the split is that for C++ < 26, I think what the patch
implements is basically what the users will see, i.e. we can accept
constexpr or constinit structured binding with pedwarn, but I think we can't
change the constant expression rules in C++ < 26.
I plan to look at the rest of the paper.
2025-07-08 Jakub Jelinek <jakub@redhat.com>
PR c++/117784
* decl.cc: Implement part of C++26 P2686R4 - constexpr structured
bindings.
(cp_finish_decl): Pedwarn for C++23 and older on constinit on
structured bindings except for static/thread_local where it uses
earlier error.
(grokdeclarator): Pedwarn on constexpr structured bindings for
C++23 and older instead of emitting error always, don't clear
constexpr_p in that case.
* parser.cc (cp_parser_decomposition_declaration): Copy over
DECL_DECLARED_CONSTEXPR_P and DECL_DECLARED_CONSTINIT_P flags.
* g++.dg/cpp1z/decomp3.C (test): For constexpr structured binding
initialize from constexpr var instead of non-constexpr and expect
just a pedwarn for C++23 and older instead of error always.
* g++.dg/cpp26/decomp9.C (foo): Likewise.
* g++.dg/cpp26/decomp22.C: New test.
* g++.dg/cpp26/decomp23.C: New test.
* g++.dg/cpp26/decomp24.C: New test.
* g++.dg/cpp26/decomp25.C: New test.
|
|
|
|
Add logic for the case of two FMV annotated functions with identical
signature other than the return type.
Previously this was ignored, this changes the behavior to emit a diagnostic.
gcc/cp/ChangeLog:
PR c++/119498
* decl.cc (duplicate_decls): Change logic to not always exclude FMV
annotated functions in cases of return type non-ambiguation.
gcc/testsuite/ChangeLog:
PR c++/119498
* g++.target/aarch64/pr119498.C: New test.
|
|
In r14-1659 I added a missing error for a Concepts TS feature that we were
failing to diagnose, but this PR requests a way to disable that error for
code written thinking it was valid. Which seems reasonable, since it
doesn't require any work beyond that and is a plausible extension by itself.
While looking at this, I also noticed we were still not giving the
diagnostic in a few cases, and fixing that affected a few of our old
concepts testcases.
PR c++/120917
gcc/ChangeLog:
* doc/invoke.texi: Add -Wno-abbreviated-auto-in-template-arg.
gcc/c-family/ChangeLog:
* c.opt: Add -Wno-abbreviated-auto-in-template-arg.
* c.opt.urls: Regenerate.
gcc/cp/ChangeLog:
* parser.cc (cp_parser_simple_type_specifier): Attach
auto in targ in parameter to -Wabbreviated-auto-in-template-arg.
(cp_parser_placeholder_type_specifier): Diagnose constrained auto in
template arg.
gcc/testsuite/ChangeLog:
* g++.dg/concepts/auto7a.C: Add diagnostic.
* g++.dg/concepts/auto7b.C: New test.
* g++.dg/concepts/auto7c.C: New test.
* g++.dg/cpp1y/pr85076.C: Expect 'auto' error.
* g++.dg/concepts/pr67249.C: Likewise.
* g++.dg/cpp1y/lambda-generic-variadic.C: Likewise.
* g++.dg/cpp2a/concepts-pr67210.C: Likewise.
* g++.dg/concepts/pr67249a.C: New test.
* g++.dg/cpp1y/lambda-generic-variadic-a.C: New test.
* g++.dg/cpp2a/concepts-pr67210a.C: New test.
|
|
https://eel.is/c++draft/stmt.ranged#2
says that in for-range-declaration only type-specifier or constexpr
can appear. As the following testcases show, we've emitted some
diagnostics in most cases, but not for static/thread_local (the patch
handles __thread too) and register in the non-sb case.
For extern there was an error that it is both extern and has an
initializer (again, non-sb only, sb errors on extern).
The following patch diagnoses those cases with pedwarn.
I've used for-range-declaration in the diagnostics wording (there was
already a case of that for the typedef), so that in the future
we don't need to differentiate it between range for and expansion
statements.
2025-07-07 Jakub Jelinek <jakub@redhat.com>
PR c++/84009
* parser.cc (cp_parser_decomposition_declaration): Pedwarn
on thread_local, __thread or static in decl_specifiers for
for-range-declaration.
(cp_parser_init_declarator): Likewise, and also for extern
or register.
* g++.dg/cpp0x/range-for40.C: New test.
* g++.dg/cpp0x/range-for41.C: New test.
* g++.dg/cpp0x/range-for42.C: New test.
* g++.dg/cpp0x/range-for43.C: New test.
|
|
|
|
Here we were asserting non-zero errorcount, which is not the case if the
parse error was reduced to a warning (or silenced) in a template body. So
check seen_error instead.
PR c++/120575
PR c++/116064
gcc/cp/ChangeLog:
* parser.cc (cp_parser_abort_tentative_parse): Check seen_error
instead of errorcount.
gcc/testsuite/ChangeLog:
* g++.dg/template/permissive-error3.C: New test.
|
|
|
|
In this testcase there is nothing in the lambda except a static_assert which
mentions a variable from the enclosing scope but does not odr-use it, so we
want prune_lambda_captures to remove its capture. Since the lambda is so
empty, there's nothing in the body except the DECL_EXPR of the capture
proxy, so pop_stmt_list moves that into the enclosing STATEMENT_LIST and
passes the 'body' STATEMENT_LIST to free_stmt_list. As a result, passing
'body' to prune_lambda_captures is wrong; we should instead pass the
enclosing scope, i.e. cur_stmt_list.
PR c++/120716
gcc/cp/ChangeLog:
* lambda.cc (finish_lambda_function): Pass cur_stmt_list to
prune_lambda_captures.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/lambda/lambda-constexpr3.C: New test.
* g++.dg/cpp0x/lambda/lambda-constexpr3a.C: New test.
|
|
This testcase was crashing from infinite recursion in the diagnostic
machinery, trying to print the lambda signature, which referred to the
__this capture field in the lambda, which wanted to print the lambda again.
But we don't want the signature to refer to the capture field; 'this' in an
unevaluated context refers to the 'this' from the enclosing function, not
the capture.
After fixing that, we still wrongly rejected the B case because
THIS_FORBIDDEN is set in a default (template) argument. Since we don't
distinguish between THIS_FORBIDDEN being set for a default argument and it
being set for a static member function, let's just ignore it if
cp_unevaluated_operand; we'll give a better diagnostic for the static memfn
case in finish_this_expr.
PR c++/120748
gcc/cp/ChangeLog:
* lambda.cc (lambda_expr_this_capture): Don't return a FIELD_DECL.
* parser.cc (cp_parser_primary_expression): Ignore THIS_FORBIDDEN
if cp_unevaluated_operand.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/lambda-targ16.C: New test.
* g++.dg/cpp0x/this1.C: Adjust diagnostics.
|
|
No idea how this slipped in, I'm terribly sorry.
Strangely nothing in the testsuite has caught this, so I've added
a new test for that.
2025-07-03 Jakub Jelinek <jakub@redhat.com>
PR c++/120940
* typeck.cc (cp_build_array_ref): Fix a pasto.
* g++.dg/parse/pr120940.C: New test.
* g++.dg/warn/Wduplicated-branches9.C: New test.
|
|
In r15-7532 for PR118856 I introduced a TARGET_EXPR with a
TARGET_EXPR_INITIAL of void_node to express that no initialization is done.
And indeed evaluating that doesn't store a value for the TARGET_EXPR_SLOT
variable.
But then at the end of the full-expression, destroy_value stores void_node
to express that its lifetime has ended. If we evaluate the same
full-expression again, global_ctx->values still holds the void_node, causing
confusion when we try to destroy it again. So clear out any value before
evaluating a TARGET_EXPR_INITIAL of void_type.
PR c++/120684
PR c++/118856
gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_constant_expression) [TARGET_EXPR]: Clear
the value first if is_complex.
gcc/testsuite/ChangeLog:
* g++.dg/cpp23/range-for10.C: New test.
|
|
|
|
The following testcase is miscompiled since the introduction of UBSan,
cp_build_array_ref COND_EXPR handling replaces
(cond ? a : b)[idx] with cond ? a[idx] : b[idx], but if there are
SAVE_EXPRs inside of idx, they will be evaluated just in one of the
branches and the other uses uninitialized temporaries.
Fixed by keeping doing what it did if idx doesn't have side effects
and is invariant. Otherwise if op1/op2 are ARRAY_TYPE arrays with
invariant addresses or pointers with invariant values, use
SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0> as a new condition
and SAVE_EXPR <idx> instead of idx for the recursive calls.
Otherwise punt, but if op1/op2 are ARRAY_TYPE, furthermore call
cp_default_conversion on array, so that COND_EXPR with ARRAY_TYPE doesn't
survive in the IL until expansion.
2025-07-01 Jakub Jelinek <jakub@redhat.com>
PR c++/120471
gcc/
* tree.h (address_invariant_p): New function.
* tree.cc (address_invariant_p): New function.
(tree_invariant_p_1): Use it for ADDR_EXPR handling. Formatting
tweak.
gcc/cp/
* typeck.cc (cp_build_array_ref) <case COND_EXPR>: If idx is not
INTEGER_CST, don't optimize the case (but cp_default_conversion on
array early if it has ARRAY_TYPE) or use
SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0> as new op0 depending
on flag_strong_eval_order and whether op1 and op2 are arrays with
invariant address or tree invariant pointers. Formatting fixes.
gcc/testsuite/
* g++.dg/ubsan/pr120471.C: New test.
* g++.dg/parse/pr120471.C: New test.
|
|
|
|
Modules streaming needs to handle these differently from other unnamed
FIELD_DECLs that are streamed for internal RECORD_DECLs, and there
doesn't seem to be a good way to detect this case otherwise.
This matters only to allow for compiler-generated type definitions that
build FIELD_DECLs with no name, as otherwise they get confused.
Currently the only such types left I hadn't earlier fixed by giving
names to are contextless, for which we have an early check to mark their
fields as MK_unique anyway, but there may be other cases in the future.
gcc/cp/ChangeLog:
* module.cc (trees_out::walking_bit_field_unit): New flag.
(trees_out::trees_out): Initialize it.
(trees_out::core_vals): Set it.
(trees_out::get_merge_kind): Use it, move previous ad-hoc check
into assertion.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
template [PR120644]
We were erroring because the TEMPLATE_DECL of the existing partial
specialisation has an undeduced return type, but the imported
declaration did not.
The root cause is similar to what was fixed in r13-2744-g4fac53d6522189,
where modules streaming code assumes that a TEMPLATE_DECL and its
DECL_TEMPLATE_RESULT will always have the same TREE_TYPE. That commit
fixed the issue by ensuring that when the type of a variable is deduced
the TEMPLATE_DECL is updated as well, but missed handling partial
specialisations. This patch ensures that the same adjustment is made
there as well.
PR c++/120644
gcc/cp/ChangeLog:
* decl.cc (cp_finish_decl): Also propagate type to partial
templates.
* module.cc (trees_out::decl_value): Add assertion that the
TREE_TYPE of a streamed template decl matches its inner.
(trees_in::is_matching_decl): Clarify function return type
deduction should only occur for non-TEMPLATE_DECL.
* pt.cc (template_for_substitution): Handle partial specs.
gcc/testsuite/ChangeLog:
* g++.dg/modules/auto-7.h: New test.
* g++.dg/modules/auto-7_a.H: New test.
* g++.dg/modules/auto-7_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
|
|
Here we end up with "error reporting routines re-entered" because
resolve_nondeduced_context isn't passing complain to mark_used.
PR c++/120756
gcc/cp/ChangeLog:
* pt.cc (resolve_nondeduced_context): Pass complain to mark_used.
gcc/testsuite/ChangeLog:
* g++.dg/warn/deprecated-22.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
The following patch implements the C++26
P3533R2 - constexpr virtual inheritance
paper.
The changes include not rejecting it for C++26, tweaking the
error wording to show that it is valid in C++26, adjusting
synthesized_method_walk not to make synthetized cdtors non-constexpr
just because of virtual base classes in C++26 and various tweaks in
constexpr.cc so that it can deal with the expressions used for
virtual base member accesses or cdtor calls which need __in_chrg
and/or __vtt_parm arguments to be passed in some cases implicitly when
they aren't passed explicitly. And dynamic_cast constant evaluation
tweaks so that it handles also expressions with types with virtual bases.
2025-06-27 Jakub Jelinek <jakub@redhat.com>
PR c++/120777
gcc/
* gimple-fold.cc (gimple_get_virt_method_for_vtable): Revert
2018-09-18 changes.
gcc/c-family/
* c-cppbuiltin.cc (c_cpp_builtins): Predefine
__cpp_constexpr_virtual_inheritance=202506L for C++26.
gcc/cp/
* constexpr.cc: Implement C++26 P3533R2 - constexpr virtual
inheritance.
(is_valid_constexpr_fn): Don't reject constexpr cdtors in classes
with virtual bases for C++26, adjust error wording.
(cxx_bind_parameters_in_call): Add ORIG_FUN argument, add
values for __in_chrg and __vtt_parm arguments when needed.
(cxx_eval_dynamic_cast_fn): Adjust function comment, HINT -1
should be possible. For C++26 if obj is cast from POINTER_PLUS_EXPR,
attempt to use cxx_fold_indirect_ref to simplify it and if successful,
build ADDR_EXPR of that.
(cxx_eval_call_expression): Add orig_fun variable, set it to
fun before looking through clones, pass it to
cxx_bind_parameters_in_call.
(reduced_constant_expression_p): Add SZ argument, pass DECL_SIZE
of FIELD_DECL e.index to recursive calls and don't return false
if SZ is non-NULL and there are unfilled fields with bit position
at or above SZ.
(cxx_fold_indirect_ref_1): Handle reading of vtables using
ptrdiff_t dynamic type instead of some pointer type. Set el_sz
to DECL_SIZE_UNIT value rather than TYPE_SIZE_UNIT of
DECL_FIELD_IS_BASE fields in classes with virtual bases.
(cxx_fold_indirect_ref): In canonicalize_obj_off lambda look
through COMPONENT_REFs with DECL_FIELD_IS_BASE in classes with
virtual bases and adjust off correspondingly. Remove assertion that
off is integer_zerop, pass tree_to_uhwi (off) instead of 0 to the
cxx_fold_indirect_ref_1 call.
* cp-tree.h (publicly_virtually_derived_p): Declare.
(reduced_constant_expression_p): Add another tree argument defaulted
to NULL_TREE.
* method.cc (synthesized_method_walk): Don't clear *constexpr_p
if there are virtual bases for C++26.
* class.cc (build_base_path): Compute fixed_type_p and
virtual_access before checks for build_simple_base_path instead of
after that and conditional cp_build_addr_expr. Use build_simple_path
if !virtual_access even when v_binfo is non-NULL.
(layout_virtual_bases): For build_base_field calls use
access_public_node rather than access_private_node if
publicly_virtually_derived_p.
(build_vtbl_initializer): Revert 2018-09-18 and 2018-12-11 changes.
(publicly_virtually_derived_p): New function.
gcc/testsuite/
* g++.dg/cpp26/constexpr-virt-inherit1.C: New test.
* g++.dg/cpp26/constexpr-virt-inherit2.C: New test.
* g++.dg/cpp26/constexpr-virt-inherit3.C: New test.
* g++.dg/cpp26/feat-cxx26.C: Add __cpp_constexpr_virtual_inheritance
tersts.
* g++.dg/cpp2a/constexpr-dtor3.C: Don't expect one error for C++26.
* g++.dg/cpp2a/constexpr-dtor16.C: Don't expect errors for C++26.
* g++.dg/cpp2a/constexpr-dynamic10.C: Likewise.
* g++.dg/cpp0x/constexpr-ice21.C: Likewise.
* g++.dg/cpp0x/constexpr-ice4.C: Likewise.
* g++.dg/abi/mangle1.C: Guard the test on c++23_down.
* g++.dg/abi/mangle81.C: New test.
* g++.dg/ipa/ipa-icf-4.C (A::A): For
__cpp_constexpr_virtual_inheritance >= 202506L add user provided
non-constexpr constructor.
|
|
With Jakub's constexpr virtual base patch,
23_containers/vector/bool/cmp_c++20.cc failed the assert I add to
fixed_type_or_null, meaning that it returned the wrong value. Let's fix the
result as well as adding the assert, and fix cp_parser_binary_expression to
properly wrap any class-type calls in the operands in TARGET_EXPR even
within a decltype so we don't hit the assert.
gcc/cp/ChangeLog:
* class.cc (fixed_type_or_null): Handle class-type CALL_EXPR.
* parser.cc (cp_parser_binary_expression): Fix decltype_p handling.
|
|
[PR98375,PR118904]
The frontend creates some variables that need to be given unique names
for the TU so that they can unambiguously be accessed. Historically
this has been done with a global counter local to each place that needs
an internal label, but this doesn't work with modules as depending on
what declarations have been imported, some counter values may have
already been used.
This patch reworks the situation to instead have a single collection of
counters for the TU, and a new function 'generate_internal_label' that
gets the next label with given prefix using that counter. Modules
streaming can then use this function to regenerate new names on
stream-in for any such decls, guaranteeing uniqueness within the TU.
These labels should only be used for internal entities so there should
be no issues with the names differing from TU to TU; we will need to
handle this if we ever start checking ODR of definitions we're merging
but that's an issue for later.
For proof of concept, this patch makes use of the new API for
__builtin_source_location and ubsan; there are probably other places
in the frontend where this change will need to be made as well.
One other change this exposes is that both of these components rely
on the definition of the VAR_DECLs they create, so stream that too
for uncontexted variables.
PR c++/98735
PR c++/118904
gcc/cp/ChangeLog:
* cp-gimplify.cc (source_location_id): Remove.
(fold_builtin_source_location): Use generate_internal_label.
* module.cc (enum tree_tag): Add 'tt_internal_id' enumerator.
(trees_out::tree_value): Adjust assertion, write definitions
of uncontexted VAR_DECLs.
(trees_in::tree_value): Read variable definitions.
(trees_out::tree_node): Write internal labels, adjust assert.
(trees_in::tree_node): Read internal labels.
gcc/ChangeLog:
* tree.cc (struct identifier_hash): New type.
(struct identifier_count_traits): New traits.
(internal_label_nums): New hash map.
(generate_internal_label): New function.
(prefix_for_internal_label): New function.
* tree.h (IDENTIFIER_INTERNAL_P): New macro.
(generate_internal_label): Declare.
(prefix_for_internal_label): Declare.
* ubsan.cc (ubsan_ids): Remove.
(ubsan_type_descriptor): Use generate_internal_label.
(ubsan_create_data): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/modules/src-loc-1.h: New test.
* g++.dg/modules/src-loc-1_a.H: New test.
* g++.dg/modules/src-loc-1_b.C: New test.
* g++.dg/modules/src-loc-1_c.C: New test.
* g++.dg/modules/ubsan-1_a.C: New test.
* g++.dg/modules/ubsan-1_b.C: New test.
* g++.dg/ubsan/module-1-aux.cc: New test.
* g++.dg/ubsan/module-1.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
This type currently has a DECL_NAME of an IDENTIFIER_DECL. Although the
documentation indicates this is legal, this confuses modules streaming
which expects all RECORD_TYPEs to have a TYPE_DECL, which is used to
determine the context and merge key, etc.
PR c++/120040
gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_constant_expression): Handle TYPE_NAME
now being a TYPE_DECL rather than just an IDENTIFIER_NODE.
* init.cc (build_new_constexpr_heap_type): Build a TYPE_DECL for
the returned type; mark the type as artificial.
* module.cc (trees_out::type_node): Add some assertions.
gcc/testsuite/ChangeLog:
* g++.dg/modules/pr120040_a.C: New test.
* g++.dg/modules/pr120040_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
Currently, most declarations must have a DECL_CONTEXT for modules
streaming to behave correctly, so that they can have an appropriate
merge key generated and be correctly deduplicated on import.
There are a few exceptions, however, for internally generated
declarations that will never be merged and don't necessarily have an
appropriate parent to key off for the context. One case that's come up
a few times is TYPE_DECLs, especially temporary RECORD_TYPEs used as
intermediaries within expressions.
Previously I've tried to give all such types a DECL_CONTEXT, but in some
cases that has ended up being infeasible, such as with the types
generated by UBSan (which are shared with the C frontend and don't know
their context, especially when created at global scope). Additionally,
these types often don't have many of the parts that a normal struct
declaration created via parsing user code would have, which confuses
module streaming.
Given that these types are typically intended to be one-off and unique
anyway, this patch instead adds support for by-value streaming of
uncontexted TYPE_DECLs. The patch only support streaming the bare
minimum amount of fields needed for the cases I've come across so far;
in general the preference should still be to ensure that DECL_CONTEXT is
set where possible.
PR c++/98735
PR c++/120040
gcc/cp/ChangeLog:
* module.cc (trees_out::tree_value): Write TYPE_DECLs.
(trees_in::tree_value): Read TYPE_DECLs.
(trees_out::tree_node): Support uncontexted TYPE_DECLs, and
ensure that all parts of a by-value decl are marked for
streaming.
(trees_out::get_merge_kind): Treat members of uncontexted types
as always unique.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
This patch adds a note to help users unfamiliar with modules terminology
understand how to declare main in a named module since P3618.
There doesn't appear to be an easy robust location available for "the
start of this declaration" that I could find to attach a fixit to, but
the explanation should suffice.
gcc/cp/ChangeLog:
* decl.cc (grokfndecl): Add explanation of how to attach to
global module.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
No functional change intended.
gcc/ada/ChangeLog:
* gcc-interface/misc.cc (gnat_init): Use
diagnostic_context::set_internal_error_callback.
gcc/c-family/ChangeLog:
* c-opts.cc (c_common_diagnostics_set_defaults): Use
diagnostic_context::set_permissive_option.
gcc/cp/ChangeLog:
* error.cc (cxx_initialize_diagnostics): Use
diagnostic_context::set_adjust_diagnostic_info_callback.
gcc/ChangeLog:
* diagnostic.h (diagnostic_context::set_permissive_option): New.
(diagnostic_context::set_fatal_errors): New.
(diagnostic_context::set_internal_error_callback): New.
(diagnostic_context::set_adjust_diagnostic_info_callback): New.
(diagnostic_context::inhibit_notes): New.
(diagnostic_context::m_opt_permissive): Make private.
(diagnostic_context::m_fatal_errors): Likewise.
(diagnostic_context::m_internal_error): Likewise.
(diagnostic_context::m_adjust_diagnostic_info): Likewise.
(diagnostic_context::m_inhibit_notes_p): Likewise.
(diagnostic_inhibit_notes): Delete.
* opts.cc (common_handle_option): Use
diagnostic_context::set_fatal_errors.
* toplev.cc (internal_error_function): Use
diagnostic_context::set_internal_error_callback.
(general_init): Likewise.
(process_options): Use diagnostic_context::inhibit_notes.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
The following patch attempts to implement the C++26 P2830R10 - Constexpr Type
Ordering paper, with a minor change that std::type_order<T, U> class template
doesn't derive from integer_constant, because std::strong_ordering is not
a structural type (except in MSVC), so instead it is just a class template
with static constexpr strong_ordering value member and also value_type,
type and 2 operators.
The paper mostly talks about using something other than mangled names for
the ordering, but given that the mangler is part of the GCC C++ FE, using
the mangler seems to be the best ordering choice to me.
2025-06-26 Jakub Jelinek <jakub@redhat.com>
gcc/cp/
* cp-trait.def: Implement C++26 P2830R10 - Constexpr Type Ordering.
(TYPE_ORDER): New.
* method.cc (type_order_value): Define.
* cp-tree.h (type_order_value): Declare.
* semantics.cc (trait_expr_value): Use gcc_unreachable also
for CPTK_TYPE_ORDER, adjust comment.
(finish_trait_expr): Handle CPTK_TYPE_ORDER.
* constraint.cc (diagnose_trait_expr): Likewise.
gcc/testsuite/
* g++.dg/cpp26/type-order1.C: New test.
* g++.dg/cpp26/type-order2.C: New test.
* g++.dg/cpp26/type-order3.C: New test.
libstdc++-v3/
* include/bits/version.def (type_order): New.
* include/bits/version.h: Regenerate.
* libsupc++/compare: Define __glibcxx_want_type_order before
including bits/version.h.
(std::type_order, std::type_order_v): New trait and template variable.
* src/c++23/std.cc.in (std::type_order, std::type_order_v): Export.
* testsuite/18_support/comparisons/type_order/1.cc: New test.
|
|
|
|
When building GCC with clang, it warns that the private member suffix
in class cp_coroutine_transform (defined in gcc/cp/coroutines.h) is
not used which indeed looks like it is the case. This patch therefore
removes it.
gcc/cp/ChangeLog:
2025-06-24 Martin Jambor <mjambor@suse.cz>
* coroutines.h (class cp_coroutine_transform): Remove member
orig_fn_body.
|
|
|
|
[PR120773]
The following patch implements the P3618R0 paper by tweaking pedwarn
condition, adjusting pedwarn wording, adjusting one testcase and adding 4
new ones. The paper was voted in as DR, so it isn't guarded on C++ version.
2025-06-24 Jakub Jelinek <jakub@redhat.com>
PR c++/120773
* decl.cc (grokfndecl): Implement C++26 P3618R0 - Allow attaching
main to the global module. Only pedwarn for current_lang_name
other than lang_name_cplusplus and adjust pedwarn wording.
* g++.dg/parse/linkage5.C: Don't expect error on
extern "C++" int main ();.
* g++.dg/parse/linkage7.C: New test.
* g++.dg/parse/linkage8.C: New test.
* g++.dg/modules/main-2.C: New test.
* g++.dg/modules/main-3.C: New test.
|
|
|
|
OpenACC 3.0 added the 'if' clause to four directives; this patch only adds
it to 'acc wait'.
gcc/c-family/ChangeLog:
* c-omp.cc (c_finish_oacc_wait): Handle if clause.
gcc/c/ChangeLog:
* c-parser.cc (OACC_WAIT_CLAUSE_MASK): Add if clause.
gcc/cp/ChangeLog:
* parser.cc (OACC_WAIT_CLAUSE_MASK): Ass if clause.
gcc/fortran/ChangeLog:
* openmp.cc (OACC_WAIT_CLAUSES): Add if clause.
* trans-openmp.cc (gfc_trans_oacc_wait_directive): Handle it.
gcc/testsuite/ChangeLog:
* c-c++-common/goacc/acc-wait-1.c: New test.
* gfortran.dg/goacc/acc-wait-1.f90: New test.
|
|
|
|
This implements the final piece of the revised CWG2563 wording;
"It exits the scope of promise only if the coroutine completed
without suspending."
Considering the coroutine to be made up of two components; a
'ramp' and a 'body' where the body represents the user's original
code and the ramp is responsible for setup of that and for
returning some object to the original caller.
Coroutine state, and responsibility for its release.
A coroutine has some state that persists across suspensions.
The state has two components:
* State that is specified by the standard and persists for the entire
life of the coroutine.
* Local state that is constructed/destructed as scopes in the original
function body are entered/exited. The destruction of local state is
always the responsibility of the body code.
The persistent state (and the overall storage for the state) must be
managed in two places:
* The ramp function (which allocates and builds this - and can, in some
cases, be responsible for destroying it)
* The re-written function body which can destroy it when that body
completes its final suspend - or when the handle.destroy () is called.
In all cases the ramp holds responsibility for constructing the standard-
mandated persistent state.
There are four ways in which the ramp might be re-entered after starting
the function body:
A The body could suspend (one might expect that to be the 'normal' case
for most coroutines).
B The body might complete either synchronously or via continuations.
C An exception might be thrown during the setup of the initial await
expression, before the initial awaiter resumes.
D An exception might be processed by promise.unhandled_exception () and
that, in turn, might re-throw it (or throw something else). In this
case, the coroutine is considered suspended at the final suspension
point.
Once the coroutine has passed initial suspend (i.e. the initial awaiter
await_resume() has been called) the body is considered to have a use of
the state.
Until the ramp return value has been constructed, the ramp is considered
to have a use of the state.
To manage these interacting conditions we allocate a reference counter
for the frame state. This is initialised to 1 by the ramp as part of its
startup (note that failures/exceptions in the startup code are handled
locally to the ramp).
When the body returns (either normally, or by exception) the ramp releases
its use.
Once the rewritten coroutine body is started, the body is considered to
have a use of the frame. This use (potentially) needs to be released if
an exception is thrown from the body. We implement this using an eh-only
cleanup around the initial await. If we have the case D above, then we
do not release the body use.
In case:
A, typically the ramp would be re-entered with the body holding a use,
and therefore the ramp should not destroy the state.
B, both the body and ramp will have released their uses, and the ramp
should destroy the state.
C, we must arrange for the body to release its use, because we require
the ramp to cleanup in this circumstance.
D is an outlier, since the responsibility for destruction of the state
now rests with the user's code (via a handle.destroy() call).
NOTE: In the case that the body has never suspended before such an
exception occurs, the only reasonable way for the user code to obtain the
necessary handle is if unhandled_exception() throws the handle or some
object that contains the handle. That is outside of the designs here -
if the user code might need this corner-case, then such provision will
have to be made.
In the ramp, we implement destruction for the persistent frame state by
means of cleanups. These are run conditionally when the reference count
is 0 signalling that both the body and the ramp have completed.
In the body, once we pass the final suspend, then we test the use and
delete the state if the use is 0.
PR c++/115908
PR c++/118074
PR c++/95615
gcc/cp/ChangeLog:
* coroutines.cc (coro_frame_refcount_id): New.
(coro_init_identifiers): Initialise coro_frame_refcount_id.
(build_actor_fn): Set up initial_await_resume_called. Handle
decrementing of the frame reference count. Return directly to
the caller if that is non-zero.
(cp_coroutine_transform::wrap_original_function_body): Use a
conditional eh-only cleanup around the initial await expression
to release the body use on exception before initial await
resume.
(cp_coroutine_transform::build_ramp_function): Wrap the called
body in a cleanup that releases a use of the frame when we
return to the ramp. Implement frame, promise and argument copy
destruction via conditional cleanups when the frame use count
is zero.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/pr115908.C: Move to...
* g++.dg/coroutines/torture/pr115908.C: ...here.
* g++.dg/coroutines/torture/pr95615-02.C: Move to...
* g++.dg/coroutines/torture/pr95615-01-promise-ctor-throws.C: ...here.
* g++.dg/coroutines/torture/pr95615-03.C: Move to...
* g++.dg/coroutines/torture/pr95615-02-get-return-object-throws.C: ...here.
* g++.dg/coroutines/torture/pr95615-01.C: Move to...
* g++.dg/coroutines/torture/pr95615-03-initial-suspend-throws.C: ...here.
* g++.dg/coroutines/torture/pr95615-04.C: Move to...
* g++.dg/coroutines/torture/pr95615-04-initial-await-ready-throws.C: ...here.
* g++.dg/coroutines/torture/pr95615-05.C: Move to...
* g++.dg/coroutines/torture/pr95615-05-initial-await-suspend-throws.C: ...here.
* g++.dg/coroutines/torture/pr95615.inc: Add more cases and ensure that the
code completes properly when no exceptions are thrown.
* g++.dg/coroutines/torture/pr95615-00-nothing-throws.C: New test.
* g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C: New test.
* g++.dg/coroutines/torture/pr95615-07-body-throws.C: New test.
* g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C: New test.
* g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C: New test.
Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
|
|
|
|
We have been keeping a copy of coroutine_handle<promise> in the state
frame, as it was expected to be efficient to use this to initialize the
argument to await_suspend. This does not turn out to be the case and
intializing the value is obstructive to CGW2563 fixes. This removes
the use.
gcc/cp/ChangeLog:
* coroutines.cc (struct coroutine_info): Update comments.
(struct coro_aw_data): Remove self_handle and add in
information to create the handle in lowering.
(expand_one_await_expression): Build a temporary coroutine
handle.
(build_actor_fn): Remove reference to the frame copy of the
coroutine handle.
(cp_coroutine_transform::wrap_original_function_body): Remove
reference to the frame copy of the coroutine handle.
Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
|
|
Here we have an expression that is not evaluated but is still seen
as potentially-evaluated. We handle this by determining if the
operand has side-effects, producing a warning that the assume has
been ignored and eliding it.
gcc/cp/ChangeLog:
* coroutines.cc (analyze_expression_awaits): Elide assume
attributes containing await expressions, since these have
side effects. Emit a diagnostic that this has been done.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/assume.C: New test.
|
|
I missed adjusting the number of args when copying the
IS_TRIVIALLY_CONSTRUCTIBLE line to create IS_TRIVIALLY_DESTRUCTIBLE.
PR c++/120678
gcc/cp/ChangeLog:
* cp-trait.def (IS_TRIVIALLY_DESTRUCTIBLE): Fix nargs.
|
|
To respect the #pragma diagnostic lines in libstdc++ headers when compiling
with module std, we need to represent them in the module.
I think it's reasonable to give serializers direct access to the underlying
data, as here with get_classification_history. This is a different approach
from how Jakub made PCH streaming members of diagnostic_option_classifier,
but it seems to me that modules handling belongs in module.cc.
libcpp/ChangeLog:
* line-map.cc (linemap_location_from_module_p): Add.
* include/line-map.h: Declare it.
gcc/ChangeLog:
* diagnostic.h (diagnostic_option_classifier): Friend
diagnostic_context.
(diagnostic_context::get_classification_history): New.
gcc/cp/ChangeLog:
* module.cc (module_state::write_diagnostic_classification): New.
(module_state::write_begin): Call it.
(module_state::read_diagnostic_classification): New.
(module_state::read_initial): Call it.
(dk_string, dump_dc_change): New.
gcc/testsuite/ChangeLog:
* g++.dg/modules/warn-spec-3_a.C: New test.
* g++.dg/modules/warn-spec-3_b.C: New test.
* g++.dg/modules/warn-spec-3_c.C: New test.
|
|
From [expr.await]/2
We should not accept co_await, co_yield in unevaluated contexts.
Currently (see PR68604) we do not mark typeid expressions as unevaluated
since the standard rules mean that this depends on the value type.
gcc/cp/ChangeLog:
* coroutines.cc (finish_co_await_expr): Do not allow in an
unevaluated context.
(finish_co_yield_expr): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/unevaluated.C: New test.
Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
|
|
Some of the lookup code is expecting to find a valid (not UNKNOWN)
location, which triggers in the reported case. To avoid this, we are
reverting the change to use UNKNOWN_LOCATION for synthesizing the
wrapper, and instead using the start and end locations of the original
function.
PR c++/120273
gcc/cp/ChangeLog:
* coroutines.cc
(cp_coroutine_transform::wrap_original_function_body): Use
function start and end locations when synthesizing code.
(cp_coroutine_transform::cp_coroutine_transform): Set the
function end location.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/pr120273.C: New test.
Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
|
|
|
|
We already error about a type or function definition causing a concept check
to change value, but it would be useful to diagnose this for other SFINAE
contexts as well; the memoization problem also affects templates. So
-Wsfinae-incomplete remembers if we've failed a requirement for a complete
type/deduced return type in a non-tf_error context, and later warns if the
type/function becomes complete.
This warning is enabled by default; I think the signal-to-noise ratio is
high enough to warrant that, and it catches things that are likely to make
the program "ill-formed, no diagnostic required".
friend87.C is an interesting case; this could be considered a false positive
because it is using friend injection to define the auto function to
implement a compile-time counter. I think this is sufficiently pathological
that it's fine to expect people who want to play this sort of game to
suppress the warning.
The data for this warning uses GTY((cache)) to persist through GC, but allow
entries to be discarded if the key is not otherwise marked.
I don't think it's desirable to export/import this information in modules,
it makes sense for it to be local to a single TU.
-Wsfinae-incomplete=2 adds a warning at the point of failure, which is
primarily intended to help with debugging warnings from the default mode.
gcc/ChangeLog:
* doc/invoke.texi: Document -Wsfinae-incomplete.
gcc/c-family/ChangeLog:
* c.opt: Add -Wsfinae-incomplete.
* c.opt.urls: Regenerate.
gcc/cp/ChangeLog:
* constraint.cc (failed_completions_map): New.
(note_failed_type_completion): Rename from
note_failed_type_completion_for_satisfaction. Add
-Wsfinae-incomplete handling.
(failed_completion_location): New.
* class.cc (finish_struct_1): Add -Wsfinae-incomplete warning.
* decl.cc (require_deduced_type): Adjust.
(finish_function): Add -Wsfinae-incomplete warning.
* typeck.cc (complete_type_or_maybe_complain): Adjust.
(cxx_sizeof_or_alignof_type): Call note_failed_type_completion.
* pt.cc (dependent_template_arg_p): No longer static.
* cp-tree.h: Adjust.
libstdc++-v3/ChangeLog:
* testsuite/20_util/is_complete_or_unbounded/memoization.cc
* testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc:
Expect -Wsfinae-incomplete.
gcc/testsuite/ChangeLog:
* g++.dg/template/friend87.C
* g++.dg/cpp2a/concepts-complete1.C
* g++.dg/cpp2a/concepts-complete2.C
* g++.dg/cpp2a/concepts-complete3.C
* g++.dg/cpp2a/concepts-complete4.C: Expect -Wsfinae-incomplete.
|
|
Here an unexpanded parameter pack pass into asm_operand which doesn't
expect to see an operand without type. So use check_for_bare_parameter_packs
to remedy that.
gcc/cp/ChangeLog:
* parser.cc (cp_parser_asm_operand_list): Check for unexpanded
parameter packs.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/variadic-crash7.C: New test.
|