Age | Commit message (Collapse) | Author | Files | Lines |
|
C2x adds support for enums with a fixed underlying type specified
("enum e : long long;" and similar). Implement this in the C front
end. The same representation is used for these types as in C++, with
two macros moved from cp-tree.h to c-common.h.
Such enums can have bool as the underlying type, and various C
front-end code checking for boolean types is adjusted to use a new
C_BOOLEAN_TYPE_P to handle such enums the same way as bool. (Note
that for C++ we have bug 96496 that enums with underlying type bool
don't work correctly there.)
There are various issues with the wording for such enums in the
current C2x working draft (including but not limited to wording in the
accepted paper that failed to make it into the working draft), which I
intend to raise in NB comments. I think what I've implemented and
added tests for matches the intent.
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
PR c/61469
gcc/c-family/
* c-common.h (ENUM_UNDERLYING_TYPE, ENUM_FIXED_UNDERLYING_TYPE_P):
New. Moved from cp/cp-tree.h.
* c-warn.cc (warnings_for_convert_and_check): Do not consider
conversions to enum with underlying type bool to overflow.
gcc/c/
* c-convert.cc (c_convert): Handle enums with underlying boolean
type like bool.
* c-decl.cc (shadow_tag_warned): Allow shadowing declarations for
enums with enum type specifier, but give errors for storage class
specifiers, qualifiers or alignment specifiers in non-definition
declarations of such enums.
(grokdeclarator): Give error for non-definition use of type
specifier with an enum type specifier.
(parser_xref_tag): Add argument has_enum_type_specifier. Pass it
to lookup_tag and use it to set ENUM_FIXED_UNDERLYING_TYPE_P.
(xref_tag): Update call to parser_xref_tag.
(start_enum): Add argument fixed_underlying_type. Complete enum
type with a fixed underlying type given in the definition. Give
error for defining without a fixed underlying type in the
definition if one was given in a prior declaration. Do not mark
enums with fixed underlying type as packed for -fshort-enums.
Store the enum type in the_enum.
(finish_enum): Do not adjust types of values or check their range
for an enum with a fixed underlying type. Set underlying type of
enum and variants.
(build_enumerator): Check enumeration constants for enum with
fixed underlying type against that type and convert to that type.
Increment in the underlying integer type, with handling for bool.
(c_simulate_enum_decl): Update call to start_enum.
(declspecs_add_type): Set specs->enum_type_specifier_ref_p.
* c-objc-common.cc (c_get_alias_set): Use ENUM_UNDERLYING_TYPE
rather than recomputing an underlying type based on size.
* c-parser.cc (c_parser_declspecs)
(c_parser_struct_or_union_specifier, c_parser_typeof_specifier):
Set has_enum_type_specifier for type specifiers.
(c_parser_enum_specifier): Handle enum type specifiers.
(c_parser_struct_or_union_specifier): Update call to
parser_xref_tag.
(c_parser_omp_atomic): Check for boolean increment or decrement
using C_BOOLEAN_TYPE_P.
* c-tree.h (C_BOOLEAN_TYPE_P): New.
(struct c_typespec): Add has_enum_type_specifier.
(struct c_declspecs): Add enum_type_specifier_ref_p.
(struct c_enum_contents): Add enum_type.
(start_enum, parser_xref_tag): Update prototypes.
* c-typeck.cc (composite_type): Allow for enumerated types
compatible with bool.
(common_type, comptypes_internal, perform_integral_promotions):
Use ENUM_UNDERLYING_TYPE.
(parser_build_binary_op, build_unary_op, convert_for_assignment)
(c_finish_return, c_start_switch, build_binary_op): Check for
boolean types using C_BOOLEAN_TYPE_P.
gcc/cp/
* cp-tree.h (ENUM_FIXED_UNDERLYING_TYPE_P, ENUM_UNDERLYING_TYPE):
Remove. Moved to c-common.h.
gcc/testsuite/
* gcc.dg/c11-enum-4.c, gcc.dg/c11-enum-5.c, gcc.dg/c11-enum-6.c,
gcc.dg/c2x-enum-6.c, gcc.dg/c2x-enum-7.c, gcc.dg/c2x-enum-8.c,
gcc.dg/gnu2x-enum-1.c: New tests.
|
|
|
|
This patch implements a new experimental warning (enabled by -Wall) to
detect references bound to temporaries whose lifetime has ended. The
primary motivation is the Note in
<https://en.cppreference.com/w/cpp/algorithm/max>:
Capturing the result of std::max by reference produces a dangling reference
if one of the parameters is a temporary and that parameter is returned:
int n = 1;
const int& r = std::max(n-1, n+1); // r is dangling
That's because both temporaries for n-1 and n+1 are destroyed at the end
of the full expression. With this warning enabled, you'll get:
g.C:3:12: warning: possibly dangling reference to a temporary [-Wdangling-reference]
3 | const int& r = std::max(n-1, n+1);
| ^
g.C:3:24: note: the temporary was destroyed at the end of the full expression 'std::max<int>((n - 1), (n + 1))'
3 | const int& r = std::max(n-1, n+1);
| ~~~~~~~~^~~~~~~~~~
The warning works by checking if a reference is initialized with a function
that returns a reference, and at least one parameter of the function is
a reference that is bound to a temporary. It assumes that such a function
actually returns one of its arguments! (I added code to check_return_expr
to suppress the warning when we've seen the definition of the function
and we can say that it can return a variable with static storage
duration.)
It warns when the function in question is a member function, but only if
the function is invoked on a temporary object, otherwise the warning
would emit loads of warnings for valid code like obj.emplace<T>({0}, 0).
It does detect the dangling reference in:
struct S {
const S& self () { return *this; }
};
const S& s = S().self();
It warns in member initializer lists as well:
const int& f(const int& i) { return i; }
struct S {
const int &r;
S() : r(f(10)) { }
};
I've run the testsuite/bootstrap with the warning enabled by default.
There were just a few FAILs, all of which look like genuine bugs.
A bootstrap with the warning enabled by default passed as well.
When testing a previous version of the patch, there were many FAILs in
libstdc++'s 22_locale/; all of them because the warning triggered on
const test_type& obj = std::use_facet<test_type>(std::locale());
but this code looks valid -- std::use_facet doesn't return a reference
to its parameter. Therefore I added a #pragma and code to suppress the
warning.
PR c++/106393
gcc/c-family/ChangeLog:
* c.opt (Wdangling-reference): New.
gcc/cp/ChangeLog:
* call.cc (expr_represents_temporary_p): New, factored out of...
(conv_binds_ref_to_temporary): ...here. Don't return false just
because a ck_base is missing. Use expr_represents_temporary_p.
(do_warn_dangling_reference): New.
(maybe_warn_dangling_reference): New.
(extend_ref_init_temps): Call maybe_warn_dangling_reference.
* cp-tree.h: Adjust comment.
* typeck.cc (check_return_expr): Suppress -Wdangling-reference
warnings.
gcc/ChangeLog:
* doc/invoke.texi: Document -Wdangling-reference.
libstdc++-v3/ChangeLog:
* include/bits/locale_classes.tcc: Add #pragma to disable
-Wdangling-reference with std::use_facet.
gcc/testsuite/ChangeLog:
* g++.dg/cpp23/elision4.C: Use -Wdangling-reference, add dg-warning.
* g++.dg/cpp23/elision7.C: Likewise.
* g++.dg/warn/Wdangling-pointer-2.C: Use -Wno-dangling-reference.
* g++.dg/warn/Wdangling-reference1.C: New test.
* g++.dg/warn/Wdangling-reference2.C: New test.
* g++.dg/warn/Wdangling-reference3.C: New test.
|
|
|
|
C2x adds printf and scanf wN and wfN length modifiers (wN for
int_leastN_t / uint_leastN_t, also usable for intN_t and uintN_t which
are now required to be the same type as the "least" versions when both
are supported; wfN for int_fastN_t / uint_fastN_t). Add corresponding
format checking support for those length modifiers, for all the
standard integer conversion speciciers plus the recommended integer
specifier %B.
Note that, as with the %b support, this only deals with format
checking, not other format handling elsewhere in the compiler (in
particular, it doesn't add any -Wformat-overflow support; cf. Frolov
Daniil's patch
<https://gcc.gnu.org/pipermail/gcc-patches/2022-September/600790.html>
adding such support for %b and %B, which I think is still pending
review). And of course library support is a separate matter for each
library implementation (I hope to add corresponding glibc support in
due course).
None of the tables of format conversions for kinds of formats not
supporting the new length modifiers are updated; they don't need
updating because the entries not matching some length modifier listed
for that kind of format can never be accessed, and the tables
generally thus already only explicitly covered a sufficient initial
subsequence of the length modifiers, rather than listing a full 13
possibilities before this patch or 21 after it. %w (as used for
HOST_WIDE_INT in GCC-internal formats) comes after the new modifiers
in the FMT_LEN_* enumeration, but that's not a problem because the
tables don't actually use FMT_LEN_w entries; rather, such entries get
rewritten at runtime once GCC knows the value of HOST_WIDE_INT in the
GCC it's compiling.
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
gcc/c-family/
* c-format.h (enum format_lengths): Add FMT_LEN_w8, FMT_LEN_w16,
FMT_LEN_w32, FMT_LEN_w64, FMT_LEN_wf8, FMT_LEN_wf16, FMT_LEN_wf32
and FMT_LEN_wf64.
(NOARGUMENTS, NOLENGTHS): Update definitions.
(T_I8, T2X_I8, T_I16, T2X_I16, T_I32, T2X_I32, T_I64, T2X_I64)
(T_U8, T2X_U8, T_U16, T2X_U16, T_U32, T2X_U32, T_U64, T2X_U64)
(T_IF8, T2X_IF8, T_IF16, T2X_IF16, T_IF32, T2X_IF32, T_IF64)
(T2X_IF64, T_UF8, T2X_UF8, T_UF16, T2X_UF16, T_UF32, T2X_UF32)
(T_UF64, T2X_UF64): New macros.
* c-format.cc (printf_length_specs, scanf_length_specs): Add wN
and wfN length modifiers.
(print_char_table, scan_char_table): Add entries using wN and wfN
length modifiers.
gcc/testsuite/
* gcc.dg/format/format.h (int_least8_t, int_least16_t)
(int_least32_t, int_least64_t, uint_least8_t, uint_least16_t)
(uint_least32_t, uint_least64_t, int_fast8_t, int_fast16_t)
(int_fast32_t, int_fast64_t, uint_fast8_t, uint_fast16_t)
(uint_fast32_t, uint_fast64_t): New typedefs.
* gcc.dg/format/c11-printf-1.c, gcc.dg/format/c11-scanf-1.c,
gcc.dg/format/c2x-printf-1.c, gcc.dg/format/c2x-scanf-1.c,
gcc.dg/format/ext-9.c: Add tests using wN and wfN length
modifiers.
|
|
|
|
C2x has two enhancements to enumerations: allowing enumerations whose
values do not all fit in int (similar to an existing extension), and
allowing an underlying type to be specified (as in C++). This patch
implements the first of those enhancements.
Apart from adjusting diagnostics to reflect this being a standard
feature, there are some semantics differences from the previous
extension:
* The standard feature gives all the values of such an enum the
enumerated type (while keeping type int if that can represent all
values of the enumeration), where previously GCC only gave those
values outside the range of int the enumerated type. This change
was previously requested in PR 36113; it seems unlikely that people
are depending on the detail of the previous extension that some
enumerators had different types to others depending on whether their
values could be represented as int, and this patch makes the change
to types of enumerators unconditionally (if that causes problems in
practice we could always make it conditional on C2x mode instead).
* The types *while the enumeration is being defined*, for enumerators
that can't be represented as int, are now based more directly on the
types of the expressions used, rather than a possibly different type
with the right precision constructed using c_common_type_for_size.
Again, this change is made unconditionally.
* Where overflow (or wraparound to 0, in the case of an unsigned type)
when 1 is implicitly added to determine the value of the next
enumerator was previously an error, it now results in a wider type
with the same signedness (as the while-being-defined type of the
previous enumerator) being chosen, if available.
When a type is chosen in such an overflow case, or when a type is
chosen for the underlying integer type of the enumeration, it's
possible that (unsigned) __int128 is chosen. Although C2x allows for
such types wider than intmax_t to be considered extended integer
types, we don't have various features required to do so (integer
constant suffixes; sufficient library support would also be needed to
define the associated macros for printf/scanf conversions, and
<stdint.h> typedef names would need to be defined). Thus, there are
also pedwarns for exceeding the range of intmax_t / uintmax_t, as
while in principle exceeding that range is OK, it's only OK in a
context where the relevant types meet the requirements for extended
integer types, which does not currently apply here.
Bootstrapped with no regressions for x86_64-pc-linux-gnu. Also
manually checked diagnostics for c2x-enum-3.c with -m32 to confirm the
diagnostics in that { target { ! int128 } } test are as expected.
PR c/36113
gcc/c-family/
* c-common.cc (c_common_type_for_size): Add fallback to
widest_unsigned_literal_type_node or
widest_integer_literal_type_node for precision that may not
exactly match the precision of those types.
gcc/c/
* c-decl.cc (finish_enum): If any enumerators do not fit in int,
convert all to the type of the enumeration. pedwarn if no integer
type fits all enumerators and default to
widest_integer_literal_type_node in that case. Otherwise pedwarn
for type wider than intmax_t.
(build_enumerator): pedwarn for enumerators outside the range of
uintmax_t or intmax_t, and otherwise use pedwarn_c11 for
enumerators outside the range of int. On overflow, attempt to
find a wider type that can hold the value of the next enumerator.
Do not convert value to type determined with
c_common_type_for_size.
gcc/testsuite/
* gcc.dg/c11-enum-1.c, gcc.dg/c11-enum-2.c, gcc.dg/c11-enum-3.c,
gcc.dg/c2x-enum-1.c, gcc.dg/c2x-enum-2.c, gcc.dg/c2x-enum-3.c,
gcc.dg/c2x-enum-4.c, gcc.dg/c2x-enum-5.c: New tests.
* gcc.dg/pr30260.c: Explicitly use -std=gnu11. Update expected
diagnostics.
* gcc.dg/torture/pr25183.c: Update expected diagnostics.
|
|
|
|
Here is a complete patch to add std::bfloat16_t support on
x86 (AArch64 and ARM left for later). Almost no BFmode optabs
are added by the patch, so for binops/unops it extends to SFmode
first and then truncates back to BFmode.
For {HF,SF,DF,XF,TF}mode -> BFmode conversions libgcc has implementations
of all those conversions so that we avoid double rounding, for
BFmode -> {DF,XF,TF}mode conversions to avoid growing libgcc too much
it emits BFmode -> SFmode conversion first and then converts to the even
wider mode, neither step should be imprecise.
For BFmode -> HFmode, it first emits a precise BFmode -> SFmode conversion
and then SFmode -> HFmode, because neither format is subset or superset
of the other, while SFmode is superset of both.
expr.cc then contains a -ffast-math optimization of the BF -> SF and
SF -> BF conversions if we don't optimize for space (and for the latter
if -frounding-math isn't enabled either).
For x86, perhaps truncsfbf2 optab could be defined for TARGET_AVX512BF16
but IMNSHO should FAIL if !flag_finite_math || flag_rounding_math
|| !flag_unsafe_math_optimizations, because I think the insn doesn't
raise on sNaNs, hardcodes round to nearest and flushes denormals to zero.
By default (unless x86 -fexcess-precision=16) we use float excess
precision for BFmode, so truncate only on explicit casts and assignments.
The patch introduces a single __bf16 builtin - __builtin_nansf16b,
because (__bf16) __builtin_nansf ("") will drop the sNaN into qNaN,
and uses f16b suffix instead of bf16 because there would be ambiguity on
log vs. logb - __builtin_logbf16 could be either log with bf16 suffix
or logb with f16 suffix. In other cases libstdc++ should mostly use
__builtin_*f for std::bfloat16_t overloads (we have a problem with
std::nextafter though but that one we have also for std::float16_t).
2022-10-14 Jakub Jelinek <jakub@redhat.com>
gcc/
* tree-core.h (enum tree_index): Add TI_BFLOAT16_TYPE.
* tree.h (bfloat16_type_node): Define.
* tree.cc (excess_precision_type): Promote bfloat16_type_mode
like float16_type_mode.
(build_common_tree_nodes): Initialize bfloat16_type_node if
BFmode is supported.
* expmed.h (maybe_expand_shift): Declare.
* expmed.cc (maybe_expand_shift): No longer static.
* expr.cc (convert_mode_scalar): Don't ICE on BF -> HF or HF -> BF
conversions. If there is no optab, handle BF -> {DF,XF,TF,HF}
conversions as separate BF -> SF -> {DF,XF,TF,HF} conversions, add
-ffast-math generic implementation for BF -> SF and SF -> BF
conversions.
* builtin-types.def (BT_BFLOAT16, BT_FN_BFLOAT16_CONST_STRING): New.
* builtins.def (BUILT_IN_NANSF16B): New builtin.
* fold-const-call.cc (fold_const_call): Handle CFN_BUILT_IN_NANSF16B.
* config/i386/i386.cc (classify_argument): Handle E_BCmode.
(ix86_libgcc_floating_mode_supported_p): Also return true for BFmode
for -msse2.
(ix86_mangle_type): Mangle BFmode as DF16b.
(ix86_invalid_conversion, ix86_invalid_unary_op,
ix86_invalid_binary_op): Remove.
(TARGET_INVALID_CONVERSION, TARGET_INVALID_UNARY_OP,
TARGET_INVALID_BINARY_OP): Don't redefine.
* config/i386/i386-builtins.cc (ix86_bf16_type_node): Remove.
(ix86_register_bf16_builtin_type): Use bfloat16_type_node rather than
ix86_bf16_type_node, only create it if still NULL.
* config/i386/i386-builtin-types.def (BFLOAT16): Likewise.
* config/i386/i386.md (cbranchbf4, cstorebf4): New expanders.
gcc/c-family/
* c-cppbuiltin.cc (c_cpp_builtins): If bfloat16_type_node,
predefine __BFLT16_*__ macros and for C++23 also
__STDCPP_BFLOAT16_T__. Predefine bfloat16_type_node related
macros for -fbuilding-libgcc.
* c-lex.cc (interpret_float): Handle CPP_N_BFLOAT16.
gcc/c/
* c-typeck.cc (convert_arguments): Don't promote __bf16 to
double.
gcc/cp/
* cp-tree.h (extended_float_type_p): Return true for
bfloat16_type_node.
* typeck.cc (cp_compare_floating_point_conversion_ranks): Set
extended{1,2} if mv{1,2} is bfloat16_type_node. Adjust comment.
gcc/testsuite/
* lib/target-supports.exp (check_effective_target_bfloat16,
check_effective_target_bfloat16_runtime, add_options_for_bfloat16):
New.
* gcc.dg/torture/bfloat16-basic.c: New test.
* gcc.dg/torture/bfloat16-builtin.c: New test.
* gcc.dg/torture/bfloat16-builtin-issignaling-1.c: New test.
* gcc.dg/torture/bfloat16-complex.c: New test.
* gcc.dg/torture/builtin-issignaling-1.c: Allow to be includable
from bfloat16-builtin-issignaling-1.c.
* gcc.dg/torture/floatn-basic.h: Allow to be includable from
bfloat16-basic.c.
* gcc.target/i386/vect-bfloat16-typecheck_2.c: Adjust expected
diagnostics.
* gcc.target/i386/sse2-bfloat16-scalar-typecheck.c: Likewise.
* gcc.target/i386/vect-bfloat16-typecheck_1.c: Likewise.
* g++.target/i386/bfloat_cpp_typecheck.C: Likewise.
libcpp/
* include/cpplib.h (CPP_N_BFLOAT16): Define.
* expr.cc (interpret_float_suffix): Handle bf16 and BF16 suffixes for
C++.
libgcc/
* config/i386/t-softfp (softfp_extensions): Add bfsf.
(softfp_truncations): Add tfbf xfbf dfbf sfbf hfbf.
(CFLAGS-extendbfsf2.c, CFLAGS-truncsfbf2.c, CFLAGS-truncdfbf2.c,
CFLAGS-truncxfbf2.c, CFLAGS-trunctfbf2.c, CFLAGS-trunchfbf2.c): Add
-msse2.
* config/i386/libgcc-glibc.ver (GCC_13.0.0): Export
__extendbfsf2 and __trunc{s,d,x,t,h}fbf2.
* config/i386/sfp-machine.h (_FP_NANSIGN_B): Define.
* config/i386/64/sfp-machine.h (_FP_NANFRAC_B): Define.
* config/i386/32/sfp-machine.h (_FP_NANFRAC_B): Define.
* soft-fp/brain.h: New file.
* soft-fp/truncsfbf2.c: New file.
* soft-fp/truncdfbf2.c: New file.
* soft-fp/truncxfbf2.c: New file.
* soft-fp/trunctfbf2.c: New file.
* soft-fp/trunchfbf2.c: New file.
* soft-fp/truncbfhf2.c: New file.
* soft-fp/extendbfsf2.c: New file.
libiberty/
* cp-demangle.h (D_BUILTIN_TYPE_COUNT): Increment.
* cp-demangle.c (cplus_demangle_builtin_types): Add std::bfloat16_t
entry.
(cplus_demangle_type): Demangle DF16b.
* testsuite/demangle-expected (_Z3xxxDF16b): New test.
|
|
The following patch implements excess precision support for C++.
Like for C, it uses EXCESS_PRECISION_EXPR tree to say that its operand
is evaluated in excess precision and what the semantic type of the
expression is.
In most places I've followed what the C FE does in similar spots, so
e.g. for binary ops if one or both operands are already
EXCESS_PRECISION_EXPR, strip those away or for operations that might need
excess precision (+, -, *, /) check if the operands should use excess
precision and convert to that type and at the end wrap into
EXCESS_PRECISION_EXPR with the common semantic type.
This patch follows the C99 handling where it differs from C11 handling.
There are some cases which needed to be handled differently, the C FE can
just strip EXCESS_PRECISION_EXPR (replace it with its operand) when handling
explicit cast, but that IMHO isn't right for C++ - the discovery what exact
conversion should be used (e.g. if user conversion or standard or their
sequence) should be decided based on the semantic type (i.e. type of
EXCESS_PRECISION_EXPR), and that decision continues in convert_like* where
we pick the right user conversion, again, if say some class has ctor
from double and long double and we are on ia32 with standard excess
precision promoting float/double to long double, then we should pick the
ctor from double. Or when some other class has ctor from just double,
and EXCESS_PRECISION_EXPR semantic type is float, we should choose the
user ctor from double, but actually just convert the long double excess
precision to double and not to float first. We need to make sure
even identity conversion converts from excess precision to the semantic one
though, but if identity is chained with other conversions, we don't want
the identity next_conversion to drop to semantic precision only to widen
afterwards.
The existing testcases tweaks were for cases on i686-linux where excess
precision breaks those tests, e.g. if we have
double d = 4.2;
if (d == 4.2)
then it does the expected thing only with -fexcess-precision=fast,
because with -fexcess-precision=standard it is actually
double d = 4.2;
if ((long double) d == 4.2L)
where 4.2L is different from 4.2. I've added -fexcess-precision=fast
to some tests and changed other tests to use constants that are exactly
representable and don't suffer from these excess precision issues.
There is one exception, pr68180.C looks like a bug in the patch which is
also present in the C FE (so I'd like to get it resolved incrementally
in both). Reduced testcase:
typedef float __attribute__((vector_size (16))) float32x4_t;
float32x4_t foo(float32x4_t x, float y) { return x + y; }
with -m32 -std=c11 -Wno-psabi or -m32 -std=c++17 -Wno-psabi
it is rejected with:
pr68180.c:2:52: error: conversion of scalar ‘long double’ to vector ‘float32x4_t’ {aka ‘__vector(4) float’} involves truncation
but without excess precision (say just -std=c11 -Wno-psabi or -std=c++17 -Wno-psabi)
it is accepted. Perhaps we should pass down the semantic type to
scalar_to_vector and use the semantic type rather than excess precision type
in the diagnostics.
2022-10-14 Jakub Jelinek <jakub@redhat.com>
PR middle-end/323
PR c++/107097
gcc/
* doc/invoke.texi (-fexcess-precision=standard): Mention that the
option now also works in C++.
gcc/c-family/
* c-common.def (EXCESS_PRECISION_EXPR): Remove comment part about
the tree being specific to C/ObjC.
* c-opts.cc (c_common_post_options): Handle flag_excess_precision
in C++ the same as in C.
* c-lex.cc (interpret_float): Set const_type to excess_precision ()
even for C++.
gcc/cp/
* parser.cc (cp_parser_primary_expression): Handle
EXCESS_PRECISION_EXPR with REAL_CST operand the same as REAL_CST.
* cvt.cc (cp_ep_convert_and_check): New function.
* call.cc (build_conditional_expr): Add excess precision support.
When type_after_usual_arithmetic_conversions returns error_mark_node,
use gcc_checking_assert that it is because of uncomparable floating
point ranks instead of checking all those conditions and make it
work also with complex types.
(convert_like_internal): Likewise. Add NESTED_P argument, pass true
to recursive calls to convert_like.
(convert_like): Add NESTED_P argument, pass it through to
convert_like_internal. For other overload pass false to it.
(convert_like_with_context): Pass false to NESTED_P.
(convert_arg_to_ellipsis): Add excess precision support.
(magic_varargs_p): For __builtin_is{finite,inf,inf_sign,nan,normal}
and __builtin_fpclassify return 2 instead of 1, document what it
means.
(build_over_call): Don't handle former magic 2 which is no longer
used, instead for magic 1 remove EXCESS_PRECISION_EXPR.
(perform_direct_initialization_if_possible): Pass false to NESTED_P
convert_like argument.
* constexpr.cc (cxx_eval_constant_expression): Handle
EXCESS_PRECISION_EXPR.
(potential_constant_expression_1): Likewise.
* pt.cc (tsubst_copy, tsubst_copy_and_build): Likewise.
* cp-tree.h (cp_ep_convert_and_check): Declare.
* cp-gimplify.cc (cp_fold): Handle EXCESS_PRECISION_EXPR.
* typeck.cc (cp_common_type): For COMPLEX_TYPEs, return error_mark_node
if recursive call returned it.
(convert_arguments): For magic 1 remove EXCESS_PRECISION_EXPR.
(cp_build_binary_op): Add excess precision support. When
cp_common_type returns error_mark_node, use gcc_checking_assert that
it is because of uncomparable floating point ranks instead of checking
all those conditions and make it work also with complex types.
(cp_build_unary_op): Likewise.
(cp_build_compound_expr): Likewise.
(build_static_cast_1): Remove EXCESS_PRECISION_EXPR.
gcc/testsuite/
* gcc.target/i386/excess-precision-1.c: For C++ wrap abort and
exit declarations into extern "C" block.
* gcc.target/i386/excess-precision-2.c: Likewise.
* gcc.target/i386/excess-precision-3.c: Likewise. Remove
check_float_nonproto and check_double_nonproto tests for C++.
* gcc.target/i386/excess-precision-7.c: For C++ wrap abort and
exit declarations into extern "C" block.
* gcc.target/i386/excess-precision-9.c: Likewise.
* g++.target/i386/excess-precision-1.C: New test.
* g++.target/i386/excess-precision-2.C: New test.
* g++.target/i386/excess-precision-3.C: New test.
* g++.target/i386/excess-precision-4.C: New test.
* g++.target/i386/excess-precision-5.C: New test.
* g++.target/i386/excess-precision-6.C: New test.
* g++.target/i386/excess-precision-7.C: New test.
* g++.target/i386/excess-precision-9.C: New test.
* g++.target/i386/excess-precision-11.C: New test.
* c-c++-common/dfp/convert-bfp-10.c: Add -fexcess-precision=fast
as dg-additional-options.
* c-c++-common/dfp/compare-eq-const.c: Likewise.
* g++.dg/cpp1z/constexpr-96862.C: Likewise.
* g++.dg/cpp1z/decomp12.C (main): Use 2.25 instead of 2.3 to
avoid excess precision differences.
* g++.dg/other/thunk1.C: Add -fexcess-precision=fast
as dg-additional-options.
* g++.dg/vect/pr64410.cc: Likewise.
* g++.dg/cpp1y/pr68180.C: Likewise.
* g++.dg/vect/pr89653.cc: Likewise.
* g++.dg/cpp0x/variadic-tuple.C: Likewise.
* g++.dg/cpp0x/nsdmi-union1.C: Use 4.25 instead of 4.2 to
avoid excess precision differences.
* g++.old-deja/g++.brendan/copy9.C: Add -fexcess-precision=fast
as dg-additional-options.
* g++.old-deja/g++.brendan/overload7.C: Likewise.
|
|
|
|
A late change for C2x (addressing comments from the second round of
editorial review before the CD ballot, postdating the most recent
public working draft) removed the value 2 for *_IS_IEC_60559 (a new
<float.h> macro added in C2x). Adjust the implementation accordingly
not to use this value.
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
gcc/
* ginclude/float.h (FLT_IS_IEC_60559, DBL_IS_IEC_60559)
(LDBL_IS_IEC_60559): Update comment.
gcc/c-family/
* c-cppbuiltin.cc (builtin_define_float_constants): Do not use
value 2 for *_IS_IEC_60559.
gcc/testsuite/
* gcc.dg/c2x-float-10.c: Do not expect value 2 for *_IS_IEC_60559.
|
|
|
|
The token_streamer class (which implements gcc mode -E and
-save-temps/-no-integrated-cpp) needs to keep track whether the last tokens
output were in a system header, so that it can generate line marker
annotations as necessary for a downstream consumer to reconstruct the
state. The logic for tracking it, which was added by r5-1863 to resolve
PR60723, has some edge case issues as revealed by the three new test
cases. The first, coming from the original PR60014, was incidentally fixed by
r9-1926 for unrelated reasons. The other two were still failing on master
prior to this commit. Such code paths were not realizable prior to r13-1544,
which made it possible for the token streamer to see CPP_PRAGMA tokens in more
contexts.
The two main issues being corrected here are:
1) print.prev_was_system_token needs to indicate whether the previous token
output was in a system location. However, it was not being set on every token,
only on those that triggered the main code path; specifically it was not
triggered on a CPP_PRAGMA token. Testcase 2 covers this case.
2) The token_streamer uses a variable "line_marker_emitted" to remember
whether a line marker has been emitted while processing a given token, so that
it wouldn't be done more than once in case multiple conditions requiring a
line marker are true. There was no reason for this to be a member variable
that retains its value from token to token, since it is just needed for
tracking the state locally while processing a single given token. The fact
that it could retain its value for a subsequent token is rather difficult to
observe, but testcase 3 demonstrates incorrect behavior resulting from
that. Moving this to a local variable also simplifies understanding the
control flow going forward.
gcc/c-family/ChangeLog:
PR preprocessor/60014
PR preprocessor/60723
* c-ppoutput.cc (class token_streamer): Remove member
line_marker_emitted to...
(token_streamer::stream): ...a local variable here. Set
print.prev_was_system_token on all code paths.
gcc/testsuite/ChangeLog:
PR preprocessor/60014
PR preprocessor/60723
* gcc.dg/cpp/pr60014-1.c: New test.
* gcc.dg/cpp/pr60014-1.h: New test.
* gcc.dg/cpp/pr60014-2.c: New test.
* gcc.dg/cpp/pr60014-2.h: New test.
* gcc.dg/cpp/pr60014-3.c: New test.
* gcc.dg/cpp/pr60014-3.h: New test.
|
|
|
|
VAR and FIELD decls can become part of a lambda context, when the
lambda is 'attached' to that entity (It's a C++20 ODR thing that was
discovered with modules, but is actually separate.) We were not
marking those decls as substitution candidates, leading to demangling
failures and variance from other compilers.
This patch bumps the ABI, and adds the contexts them to the
substitution table. This is the intent of the ABI.
gcc/
* common.opt (-fabi-version=): Document 18.
* doc/invoke.texi (-fabi-version): Document 18.
gcc/c-family/
* c-opts.cc (c_common_post_options): Bump abi to 18.
gcc/cp/
* mangle.cc (write_prefix): Add VAR_DECL & FIELD_DECL to
substitution table under abi=18. Note possible mismatch.
gcc/testsuite/
* g++.dg/abi/lambda-ctx1-17.C: New.
* g++.dg/abi/lambda-ctx1-18.C: New.
* g++.dg/abi/lambda-ctx1-18vs17.C: New.
* g++.dg/abi/lambda-ctx1.h: New.
* g++.dg/abi/lambda-vis.C: Adjust expected mangles.
* g++.dg/abi/macro0.C: Adjust.
|
|
When getting the name of an attribute, we ought to use
get_attribute_name, which handles both [[]] and __attribute__(())
forms. Failure to do so may result in an ICE, like here.
pp_c_attributes_display wasn't able to print the [[]] form of
attributes, so this patch teaches it to.
When printing a pointer to function with a standard attribute, the attribute
should be printed after the parameter-list. With this patch we print:
aka 'void (*)(int) [[gnu::nocf_check]]'
or, in C++ with noexcept:
aka 'void (*)(int) noexcept [[gnu::nocf_check]]'
pp_c_attributes has been unused since its introduction in r56273 so
this patch removes it.
PR c++/106937
gcc/c-family/ChangeLog:
* c-pretty-print.cc (pp_c_specifier_qualifier_list): Print only GNU
attributes here.
(c_pretty_printer::direct_abstract_declarator): Print the standard [[]]
attributes here.
(pp_c_attributes): Remove.
(pp_c_attributes_display): Print the [[]] form if appropriate. Use
get_attribute_name. Don't print a trailing space when printing the
[[]] form.
* c-pretty-print.h (pp_c_attributes): Remove.
gcc/cp/ChangeLog:
* error.cc: Include "attribs.h".
(dump_type_prefix): Print only GNU attributes here.
(dump_type_suffix): Print standard attributes here.
gcc/testsuite/ChangeLog:
* c-c++-common/pointer-to-fn1.c: New test.
|
|
|
|
Add the following new option -fstrict-flex-arrays[=n] and a corresponding
attribute strict_flex_array to GCC:
'-fstrict-flex-arrays'
Control when to treat the trailing array of a structure as a flexible array
member for the purpose of accessing the elements of such an array.
The positive form is equivalent to '-fstrict-flex-arrays=3', which is the
strictest. A trailing array is treated as a flexible array member only when
it declared as a flexible array member per C99 standard onwards.
The negative form is equivalent to '-fstrict-flex-arrays=0', which is the
least strict. All trailing arrays of structures are treated as flexible
array members.
'-fstrict-flex-arrays=LEVEL'
Control when to treat the trailing array of a structure as a flexible array
member for the purpose of accessing the elements of such an array. The value
of LEVEL controls the level of strictness
The possible values of LEVEL are the same as for the
'strict_flex_array' attribute (*note Variable Attributes::).
You can control this behavior for a specific trailing array field
of a structure by using the variable attribute 'strict_flex_array'
attribute (*note Variable Attributes::).
'strict_flex_array (LEVEL)'
The 'strict_flex_array' attribute should be attached to the trailing
array field of a structure. It controls when to treat the trailing array
field of a structure as a flexible array member for the purposes of accessing
the elements of such an array. LEVEL must be an integer betwen 0 to 3.
LEVEL=0 is the least strict level, all trailing arrays of
structures are treated as flexible array members. LEVEL=3 is the
strictest level, only when the trailing array is declared as a
flexible array member per C99 standard onwards ('[]'), it is
treated as a flexible array member.
There are two more levels in between 0 and 3, which are provided to
support older codes that use GCC zero-length array extension
('[0]') or one-element array as flexible array members('[1]'): When
LEVEL is 1, the trailing array is treated as a flexible array member
when it is declared as either '[]', '[0]', or '[1]'; When
LEVEL is 2, the trailing array is treated as a flexible array member
when it is declared as either '[]', or '[0]'.
This attribute can be used with or without the
'-fstrict-flex-arrays'. When both the attribute and the option
present at the same time, the level of the strictness for the
specific trailing array field is determined by the attribute.
gcc/c-family/ChangeLog:
* c-attribs.cc (handle_strict_flex_array_attribute): New function.
(c_common_attribute_table): New item for strict_flex_array.
* c.opt: (fstrict-flex-arrays): New option.
(fstrict-flex-arrays=): New option.
gcc/c/ChangeLog:
* c-decl.cc (flexible_array_member_type_p): New function.
(one_element_array_type_p): Likewise.
(zero_length_array_type_p): Likewise.
(add_flexible_array_elts_to_size): Call new utility
routine flexible_array_member_type_p.
(is_flexible_array_member_p): New function.
(finish_struct): Set the new DECL_NOT_FLEXARRAY flag.
gcc/cp/ChangeLog:
* module.cc (trees_out::core_bools): Stream out new bit
decl_not_flexarray.
(trees_in::core_bools): Stream in new bit decl_not_flexarray.
gcc/ChangeLog:
* doc/extend.texi: Document strict_flex_array attribute.
* doc/invoke.texi: Document -fstrict-flex-arrays[=n] option.
* print-tree.cc (print_node): Print new bit decl_not_flexarray.
* tree-core.h (struct tree_decl_common): New bit field
decl_not_flexarray.
* tree-streamer-in.cc (unpack_ts_decl_common_value_fields): Stream
in new bit decl_not_flexarray.
* tree-streamer-out.cc (pack_ts_decl_common_value_fields): Stream
out new bit decl_not_flexarray.
* tree.cc (array_at_struct_end_p): Update it with the new bit field
decl_not_flexarray.
* tree.h (DECL_NOT_FLEXARRAY): New flag.
gcc/testsuite/ChangeLog:
* g++.dg/strict-flex-array-1.C: New test.
* gcc.dg/strict-flex-array-1.c: New test.
|
|
Fixes:
gcc/c-family/name-hint.h:109:66: warning: unqualified call to 'std::move' [-Wunqualified-std-cast-call]
gcc/config/i386/i386-expand.cc:1351:9: warning: argument 'operands' of type 'rtx[3]' (aka 'rtx_def *[3]') with mismatched bound [-Warray-parameter]
gcc/config/i386/i386.cc:15635:8: warning: argument 'operands' of type 'rtx[2]' (aka 'rtx_def *[2]') with mismatched bound [-Warray-parameter]
gcc/cp/module.cc:17482:51: warning: argument 'counts' of type 'unsigned int[8]' with mismatched bound [-Warray-parameter]
gcc/cp/module.cc:17508:37: warning: argument 'counts' of type 'unsigned int[8]' with mismatched bound [-Warray-parameter]
gcc/cp/name-lookup.cc:6385:16: warning: unqualified call to 'std::move' [-Wunqualified-std-cast-call]
gcc/c-family/ChangeLog:
* name-hint.h: Use std::move.
gcc/ChangeLog:
* config/i386/i386-protos.h (ix86_binary_operator_ok): Add array
size to function parameter.
(ix86_unary_operator_ok): Likewise.
gcc/cp/ChangeLog:
* module.cc (enum module_state_counts): Use array size.
* name-lookup.cc (class namespace_limit_reached): Likewise.
(class module_state): Move up in the file.
|
|
In some cases we want to look up or remove both standard
attributes and attributes from gnu namespace but not others.
This patch arranges for ATTR_NS of "" to stand for ATTR_NS
NULL or "gnu", so that we don't need 2 separate calls, and
introduces is_attribute_namespace_p function which allows
testing the namespace of an attribute similar way.
The patch also uses the new lookup_attribute overload and extra
tests to avoid emitting weird warnings on foreign namespace attributes
which we should just ignore (perhaps with a warning), but shouldn't
imply any meaning to them just because they have a name matching some
standard or gnu attribute name.
2022-10-07 Jakub Jelinek <jakub@redhat.com>
gcc/
* attribs.h (is_attribute_namespace_p): New inline function.
(lookup_attribute): Document meaning of ATTR_NS equal to "".
* attribs.cc (remove_attribute): Use is_attribute_namespace_p.
(private_lookup_attribute): For ATTR_NS "" match either standard
attribute or "gnu" namespace one.
gcc/c-family/
* c-common.cc (attribute_fallthrough_p): Lookup fallthrough attribute
only in gnu namespace or as standard attribute, treat fallthrough
attributes in other namespaces like any other unknown attribute.
gcc/cp/
* parser.cc (cp_parser_check_std_attribute): Only do checks if
attribute is a standard attribute or in gnu namespace and only
lookup other attributes in those namespaces.
* cp-gimplify.cc (lookup_hotness_attribute): Adjust function comment.
Only return true for standard attribute or gnu namespace attribute.
(remove_hotness_attribute): Only remove hotness attributes when
they are standard or in gnu namespace, implement it in a single
loop rather than former 4 now 8 remove_attribute calls.
gcc/testsuite/
* g++.dg/cpp1z/fallthrough2.C: New test.
* g++.dg/cpp2a/attr-likely7.C: New test.
|
|
|
|
C2x adds typeof as a standard feature. In general this follows
existing GNU C semantics very closely, but there are various ways in
which the implementation involves more than simply enabling the
keyword for C2x:
* As well as typeof, there is a typeof_unqual variant, which removes
all qualifiers and _Atomic from the resulting type (whereas typeof
preserves qualifiers and _Atomic on qualified or atomic (lvalue or
type name) operands).
* The typeof keyword is disabled by -fno-asm, so enabling it for C2x
needs to be implemented in a way that preserves the disabling by
-fno-asm for older standard versions (which having -fno-asm having
no effect on it in C2x mode). This is done via adding a new D_EXT11
mask (which is also where the C++ front-end change comes from, to
handle D_EXT11 appropriately there for -fno-asm and
-fno-gnu-keywords).
* GNU typeof treats the noreturn property of a function (as specified
in standard C with _Noreturn or [[noreturn]]) as being part of the
type of a pointer to function, but it is not part of the type in
standard terms. Thus a special case is needed in the typeof
implementation, just like in the _Generic implementation, to avoid
treating it as a type for standard typeof. It seems plausible this
is being used when copying the type of one object to another using
typeof, so the existing semantics are preserved for __typeof__, and
for typeof in pre-C2x modes, while typeof for C2x or later has the
standard semantics.
* It turns out that, even after Martin Uecker's changes in this area,
there were still cases where rvalues could wrongly have a qualified
or atomic type in GCC. This applied to ++ and -- increment and
decrement expressions, and also to calls to functions returning an
atomic type. (For the latter, the working draft doesn't actually
explicitly exclude the function call expression having an atomic
type, but given all the changes that have gone into C17 and C2x to
avoid rvalues ever having qualified types, and given that
lvalue-to-rvalue conversion removes both qualifiers and _Atomic, it
seems unlikely that this (or casts, where GCC already removes
_Atomic) is actually intended as a route to allow an
_Atomic-qualified rvalue; I've noted this to raise as an NB comment
on the CD ballot.)
Bootstrapped with no regressions for x86_64-pc-linux-gnu. OK to
commit (C+
gcc/
* doc/invoke.texi (-fno-asm): Update description of effects on
typeof keyword.
gcc/c-family/
* c-common.cc (c_common_reswords): Mark typeof as D_EXT11. Add
typeof_unqual.
* c-common.h (enum rid): Add RID_TYPEOF_UNQUAL.
(D_EXT11): New macro. Values of subsequent macros updated.
gcc/c/
* c-parser.cc (c_parse_init): Add D_EXT11 to mask if flag_no_asm
and not C2x.
(c_keyword_starts_typename, c_token_starts_declspecs)
(c_parser_declspecs, c_parser_objc_selector): Handle
RID_TYPEOF_UNQUAL.
(c_parser_typeof_specifier): Handle RID_TYPEOF_UNQUAL.
Distinguish typeof for C2x from __typeof__ for all standard
versions and typeof before C2x.
* c-typeck.cc (build_function_call_vec): Use unqualified version
of non-void return type.
(build_unary_op): Use unqualified type for increment and
decrement.
gcc/cp/
* lex.cc (init_reswords): Handle D_EXT11.
gcc/testsuite/
* gcc.dg/c11-typeof-1.c, gcc.dg/c2x-typeof-1.c,
gcc.dg/c2x-typeof-2.c, gcc.dg/c2x-typeof-3.c,
gcc.dg/gnu11-typeof-1.c, gcc.dg/gnu11-typeof-2.c,
gcc.dg/gnu2x-typeof-1.c: New tests.
|
|
The following patch implements C++23 P1774R8 - Portable assumptions
paper, by introducing support for [[assume (cond)]]; attribute for C++.
In addition to that the patch adds [[gnu::assume (cond)]]; and
__attribute__((assume (cond))); support to both C and C++.
As described in C++23, the attribute argument is conditional-expression
rather than the usual assignment-expression for attribute arguments,
the condition is contextually converted to bool (for C truthvalue conversion
is done on it) and is never evaluated at runtime.
For C++ constant expression evaluation, I only check the simplest conditions
for undefined behavior, because otherwise I'd need to undo changes to
*ctx->global which happened during the evaluation (but I believe the spec
allows that and we can further improve later).
The patch uses a new internal function, .ASSUME, to hold the condition
in the FEs. At gimplification time, if the condition is simple/without
side-effects, it is gimplified as if (cond) ; else __builtin_unreachable ();
and otherwise for now dropped on the floor. The intent is to incrementally
outline the conditions into separate artificial functions and use
.ASSUME further to tell the ranger and perhaps other optimization passes
about the assumptions, as detailed in the PR.
When implementing it, I found that assume entry hasn't been added to
https://eel.is/c++draft/cpp.cond#6
Jonathan said he'll file a NB comment about it, this patch assumes it
has been added into the table as 202207L when the paper has been voted in.
With the attributes for both C/C++, I'd say we don't need to add
__builtin_assume with similar purpose, especially when __builtin_assume
in LLVM is just weird. It is strange for side-effects in function call's
argument not to be evaluated, and LLVM in that case (annoyingly) warns
and ignores the side-effects (but doesn't do then anything with it),
if there are no side-effects, it will work like our
if (!cond) __builtin_unreachable ();
2022-10-06 Jakub Jelinek <jakub@redhat.com>
PR c++/106654
gcc/
* internal-fn.def (ASSUME): New internal function.
* internal-fn.h (expand_ASSUME): Declare.
* internal-fn.cc (expand_ASSUME): Define.
* gimplify.cc (gimplify_call_expr): Gimplify IFN_ASSUME.
* fold-const.h (simple_condition_p): Declare.
* fold-const.cc (simple_operand_p_2): Rename to ...
(simple_condition_p): ... this. Remove forward declaration.
No longer static. Adjust function comment and fix a typo in it.
Adjust recursive call.
(simple_operand_p): Adjust function comment.
(fold_truth_andor): Adjust simple_operand_p_2 callers to call
simple_condition_p.
* doc/extend.texi: Document assume attribute. Move fallthrough
attribute example to its section.
gcc/c-family/
* c-attribs.cc (handle_assume_attribute): New function.
(c_common_attribute_table): Add entry for assume attribute.
* c-lex.cc (c_common_has_attribute): Handle
__have_cpp_attribute (assume).
gcc/c/
* c-parser.cc (handle_assume_attribute): New function.
(c_parser_declaration_or_fndef): Handle assume attribute.
(c_parser_attribute_arguments): Add assume_attr argument,
if true, parse first argument as conditional expression.
(c_parser_gnu_attribute, c_parser_std_attribute): Adjust
c_parser_attribute_arguments callers.
(c_parser_statement_after_labels) <case RID_ATTRIBUTE>: Handle
assume attribute.
gcc/cp/
* cp-tree.h (process_stmt_assume_attribute): Implement C++23
P1774R8 - Portable assumptions. Declare.
(diagnose_failing_condition): Declare.
(find_failing_clause): Likewise.
* parser.cc (assume_attr): New enumerator.
(cp_parser_parenthesized_expression_list): Handle assume_attr.
Remove identifier variable, for id_attr push the identifier into
expression_list right away instead of inserting it before all the
others at the end.
(cp_parser_conditional_expression): New function.
(cp_parser_constant_expression): Use it.
(cp_parser_statement): Handle assume attribute.
(cp_parser_expression_statement): Likewise.
(cp_parser_gnu_attribute_list): Use assume_attr for assume
attribute.
(cp_parser_std_attribute): Likewise. Handle standard assume
attribute like gnu::assume.
* cp-gimplify.cc (process_stmt_assume_attribute): New function.
* constexpr.cc: Include fold-const.h.
(find_failing_clause_r, find_failing_clause): New functions,
moved from semantics.cc with ctx argument added and if non-NULL,
call cxx_eval_constant_expression rather than fold_non_dependent_expr.
(cxx_eval_internal_function): Handle IFN_ASSUME.
(potential_constant_expression_1): Likewise.
* pt.cc (tsubst_copy_and_build): Likewise.
* semantics.cc (diagnose_failing_condition): New function.
(find_failing_clause_r, find_failing_clause): Moved to constexpr.cc.
(finish_static_assert): Use it. Add auto_diagnostic_group.
gcc/testsuite/
* gcc.dg/attr-assume-1.c: New test.
* gcc.dg/attr-assume-2.c: New test.
* gcc.dg/attr-assume-3.c: New test.
* g++.dg/cpp2a/feat-cxx2a.C: Add colon to C++20 features
comment, add C++20 attributes comment and move C++20
new features after the attributes before them.
* g++.dg/cpp23/feat-cxx2b.C: Likewise. Test
__has_cpp_attribute(assume).
* g++.dg/cpp23/attr-assume1.C: New test.
* g++.dg/cpp23/attr-assume2.C: New test.
* g++.dg/cpp23/attr-assume3.C: New test.
* g++.dg/cpp23/attr-assume4.C: New test.
|
|
|
|
The following patch adds support for the begin declare target construct,
which is another spelling for declare target construct without clauses
(where it needs paired end declare target), but unlike that one accepts
clauses.
This is an OpenMP 5.1 feature, implemented with 5.2 clarification because
in 5.1 we had a restriction in the declare target chapter shared by
declare target and begin declare target that if there are any clauses
specified at least one of them needs to be to or link. But that
was of course meant just for declare target and not begin declare target,
because begin declare target doesn't even allow to/link/enter clauses.
In addition to that, the patch also makes device_type clause duplication
an error (as stated in 5.1) and similarly makes declare target with
just device_type clause an error rather than warning.
What this patch doesn't do is:
1) OpenMP 5.1 also added an indirect clause, we don't support that
neither on declare target nor begin declare target
and I couldn't find it in our features pages (neither libgomp.texi
nor web)
2) I think device_type(nohost)/device_type(host) support can't work for
variables (in 5.0 it only talked about procedures so this could be
also thought as 5.1 feature that we should just add to the list
and implement)
3) I don't see any use of the "omp declare target nohost" attribute, so
I'm not sure if device_type(nohost) works at all
2022-10-04 Jakub Jelinek <jakub@redhat.com>
gcc/c-family/
* c-omp.cc (c_omp_directives): Uncomment begin declare target
entry.
gcc/c/
* c-lang.h (struct c_omp_declare_target_attr): New type.
(current_omp_declare_target_attribute): Change type from
int to vec<c_omp_declare_target_attr, va_gc> *.
* c-parser.cc (c_parser_translation_unit): Adjust for that change.
If last pushed directive was begin declare target, use different
wording and simplify format strings for easier translations.
(c_parser_omp_clause_device_type): Uncomment
check_no_duplicate_clause call.
(c_parser_omp_declare_target): Adjust for the
current_omp_declare_target_attribute type change, push { -1 }.
Use error_at rather than warning_at for declare target with
only device_type clauses.
(OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK): Define.
(c_parser_omp_begin): Add begin declare target support.
(c_parser_omp_end): Adjust for the
current_omp_declare_target_attribute type change, adjust
diagnostics wording and simplify format strings for easier
translations.
* c-decl.cc (current_omp_declare_target_attribute): Change type from
int to vec<c_omp_declare_target_attr, va_gc> *.
(c_decl_attributes): Adjust for the
current_omp_declare_target_attribute type change. If device_type
was present on begin declare target, add "omp declare target host"
and/or "omp declare target nohost" attributes.
gcc/cp/
* cp-tree.h (struct omp_declare_target_attr): Rename to ...
(cp_omp_declare_target_attr): ... this. Add device_type member.
(omp_begin_assumes_data): Rename to ...
(cp_omp_begin_assumes_data): ... this.
(struct saved_scope): Change types of omp_declare_target_attribute
and omp_begin_assumes.
* parser.cc (cp_parser_omp_clause_device_type): Uncomment
check_no_duplicate_clause call.
(cp_parser_omp_all_clauses): Fix up pasto, c_name for OMP_CLAUSE_LINK
should be "link" rather than "to".
(cp_parser_omp_declare_target): Adjust for omp_declare_target_attr
to cp_omp_declare_target_attr changes, push -1 as device_type. Use
error_at rather than warning_at for declare target with only
device_type clauses.
(OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK): Define.
(cp_parser_omp_begin): Add begin declare target support. Adjust
for omp_begin_assumes_data to cp_omp_begin_assumes_data change.
(cp_parser_omp_end): Adjust for the
omp_declare_target_attr to cp_omp_declare_target_attr and
omp_begin_assumes_data to cp_omp_begin_assumes_data type changes,
adjust diagnostics wording and simplify format strings for easier
translations.
* semantics.cc (finish_translation_unit): Likewise.
* decl2.cc (cplus_decl_attributes): If device_type was present on
begin declare target, add "omp declare target host" and/or
"omp declare target nohost" attributes.
gcc/testsuite/
* c-c++-common/gomp/declare-target-4.c: Move tests that are now
rejected into declare-target-7.c.
* c-c++-common/gomp/declare-target-6.c: Adjust expected diagnostics.
* c-c++-common/gomp/declare-target-7.c: New test.
* c-c++-common/gomp/begin-declare-target-1.c: New test.
* c-c++-common/gomp/begin-declare-target-2.c: New test.
* c-c++-common/gomp/begin-declare-target-3.c: New test.
* c-c++-common/gomp/begin-declare-target-4.c: New test.
* g++.dg/gomp/attrs-9.C: Add begin declare target tests.
* g++.dg/gomp/attrs-18.C: New test.
libgomp/
* libgomp.texi (Support begin/end declare target syntax in C/C++):
Mark as implemented.
|
|
|
|
... to match the trait's canonical spelling __is_same instead
of its alternative spelling __is_same_as.
gcc/c-family/ChangeLog:
* c-common.cc (c_common_reswords): Use RID_IS_SAME instead of
RID_IS_SAME_AS.
gcc/cp/ChangeLog:
* constraint.cc (diagnose_trait_expr): Use CPTK_IS_SAME instead
of CPTK_IS_SAME_AS.
* cp-trait.def (IS_SAME_AS): Rename to ...
(IS_SAME): ... this.
* pt.cc (alias_ctad_tweaks): Use CPTK_IS_SAME instead of
CPTK_IS_SAME_AS.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
|
|
C2x changes the <float.h> definition of *_EPSILON to apply only to
normalized numbers. The effect is that LDBL_EPSILON for IBM long
double becomes 0x1p-105L instead of 0x1p-1074L.
There is a reasonable case for considering this a defect fix - it
originated from the issue reporting process (DR#467), though it ended
up being resolved by a paper (N2326) for C2x rather than through the
issue process, and code using *_EPSILON often needs to override the
pre-C2x value of LDBL_EPSILON and use something on the order of
magnitude of the C2x value instead. However, I've followed the
conservative approach of only making the change for C2x and not for
previous standard versions (and not for C++, which doesn't have the
C2x changes in this area).
The testcases added are intended to be valid for all long double
formats. The C11 one is based on
gcc.target/powerpc/rs6000-ldouble-2.c (and when we move to a C2x
default, gcc.target/powerpc/rs6000-ldouble-2.c will need an
appropriate option added to keep using an older language version).
Tested with no regressions for cross to powerpc-linux-gnu.
gcc/c-family/
* c-cppbuiltin.cc (builtin_define_float_constants): Do not
special-case __*_EPSILON__ setting for IBM long double for C2x.
gcc/testsuite/
* gcc.dg/c11-float-7.c, gcc.dg/c2x-float-12.c: New tests.
|
|
|
|
Adding a new built-in trait currently involves manual boilerplate
consisting of defining an rid enumerator for the identifier as well as a
corresponding cp_trait_kind enumerator and handling them in various switch
statements, the exact set of which depends on whether the proposed trait
yields (and thus is recognized as) a type or an expression.
To streamline the process, this patch adds a central cp-trait.def file
that tabulates the essential details about each built-in trait (whether
it yields a type or an expression, its code, its spelling and its arity)
and uses this file to automate away the manual boilerplate. It also
migrates all the existing C++-specific built-in traits to use this
approach.
After this change, adding a new built-in trait just entails declaring
it in cp-trait.def and defining its behavior in finish_trait_expr/type
(and handling it in diagnose_trait_expr, if it's an expression-yielding
trait).
gcc/c-family/ChangeLog:
* c-common.cc (c_common_reswords): Use cp/cp-trait.def to handle
C++ traits.
* c-common.h (enum rid): Likewise.
gcc/cp/ChangeLog:
* constraint.cc (diagnose_trait_expr): Likewise.
* cp-objcp-common.cc (names_builtin_p): Likewise.
* cp-tree.h (enum cp_trait_kind): Likewise.
* cxx-pretty-print.cc (pp_cxx_trait): Likewise.
* parser.cc (cp_keyword_starts_decl_specifier_p): Likewise.
(cp_parser_primary_expression): Likewise.
(cp_parser_trait): Likewise.
(cp_parser_simple_type_specifier): Likewise.
* cp-trait.def: New file.
|
|
|
|
C2x adds a standard [[noreturn]] attribute (which can also be spelt
[[_Noreturn]] for use with <stdnoreturn.h>), so allowing non-returning
functions to be declared in a manner compatible with C++; the
_Noreturn function specifier remains available but is marked
obsolescent.
Implement this attribute. It's more restricted than GNU
__attribute__ ((noreturn)) - that allows function pointers but using
the standard attribute on a function pointer is a constraint
violation. Thus, the attribute gets its own handler that checks for a
FUNCTION_DECL before calling the handler for the GNU attribute. Tests
for the attribute are based on those for C11 _Noreturn and for other
C2x attributes.
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
gcc/c-family/
* c-lex.cc (c_common_has_attribute): Handle noreturn attribute for
C.
gcc/c/
* c-decl.cc (handle_std_noreturn_attribute): New function.
(std_attribute_table): Add _Noreturn and noreturn.
gcc/testsuite/
* gcc.dg/c2x-attr-noreturn-1.c, gcc.dg/c2x-attr-noreturn-2.c,
gcc.dg/c2x-attr-noreturn-3.c: New tests.
* gcc.dg/c2x-has-c-attribute-2.c: Also test __has_c_attribute for
noreturn attribute.
|
|
This implements builtins for std::remove_cv, std::remove_reference and
std::remove_cvref using TRAIT_TYPE from the previous patch.
gcc/c-family/ChangeLog:
* c-common.cc (c_common_reswords): Add __remove_cv,
__remove_reference and __remove_cvref.
* c-common.h (enum rid): Add RID_REMOVE_CV, RID_REMOVE_REFERENCE
and RID_REMOVE_CVREF.
gcc/cp/ChangeLog:
* constraint.cc (diagnose_trait_expr): Handle CPTK_REMOVE_CV,
CPTK_REMOVE_REFERENCE and CPTK_REMOVE_CVREF.
* cp-objcp-common.cc (names_builtin_p): Likewise.
* cp-tree.h (enum cp_trait_kind): Add CPTK_REMOVE_CV,
CPTK_REMOVE_REFERENCE and CPTK_REMOVE_CVREF.
* cxx-pretty-print.cc (pp_cxx_trait): Handle CPTK_REMOVE_CV,
CPTK_REMOVE_REFERENCE and CPTK_REMOVE_CVREF.
* parser.cc (cp_keyword_starts_decl_specifier_p): Return true
for RID_REMOVE_CV, RID_REMOVE_REFERENCE and RID_REMOVE_CVREF.
(cp_parser_trait): Handle RID_REMOVE_CV, RID_REMOVE_REFERENCE
and RID_REMOVE_CVREF.
(cp_parser_simple_type_specifier): Likewise.
* semantics.cc (finish_trait_type): Likewise.
libstdc++-v3/ChangeLog:
* include/bits/unique_ptr.h (unique_ptr<_Tp[], _Dp>): Remove
__remove_cv and use __remove_cv_t instead.
gcc/testsuite/ChangeLog:
* g++.dg/ext/has-builtin-1.C: Test existence of __remove_cv,
__remove_reference and __remove_cvref.
* g++.dg/ext/remove_cv.C: New test.
* g++.dg/ext/remove_reference.C: New test.
* g++.dg/ext/remove_cvref.C: New test.
|
|
|
|
This patch implements https://wg21.link/p2266, which, once again,
changes the implicit move rules. Here's a brief summary of various
changes in this area:
r125211: Introduced moving from certain lvalues when returning them
r171071: CWG 1148, enable move from value parameter on return
r212099: CWG 1579, it's OK to call a converting ctor taking an rvalue
r251035: CWG 1579, do maybe-rvalue overload resolution twice
r11-2411: Avoid calling const copy ctor on implicit move
r11-2412: C++20 implicit move changes, remove the fallback overload
resolution, allow move on throw of parameters and implicit
move of rvalue references
P2266 enables the implicit move even for functions that return references.
That is, we will now perform a move in
X&& foo (X&& x) {
return x;
}
P2266 also removes the fallback overload resolution, but this was
resolved by r11-2412: we only do convert_for_initialization with
LOOKUP_PREFER_RVALUE in C++17 and older.
P2266 also says that a returned move-eligible id-expression is always an
xvalue. This required some further short, but nontrivial changes,
especially when it comes to deduction, because we have to pay attention
to whether we have auto, auto&& (which is like T&&), or decltype(auto)
with (un)parenthesized argument. In C++23,
decltype(auto) f(int&& x) { return (x); }
auto&& f(int x) { return x; }
both should deduce to 'int&&' but
decltype(auto) f(int x) { return x; }
should deduce to 'int'. A cornucopia of tests attached. I've also
verified that we behave like clang++.
xvalue_p seemed to be broken: since the introduction of clk_implicit_rval,
it cannot use '==' when checking for clk_rvalueref.
Since this change breaks code, it's only enabled in C++23. In
particular, this code will not compile in C++23:
int& g(int&& x) { return x; }
because x is now treated as an rvalue, and you can't bind a non-const lvalue
reference to an rvalue.
This patch also fixes PR106882 (the check_return_expr changes).
PR c++/101165
PR c++/106882
gcc/c-family/ChangeLog:
* c-cppbuiltin.cc (c_cpp_builtins): Define __cpp_implicit_move.
gcc/cp/ChangeLog:
* call.cc (reference_binding): Check clk_implicit_rval in C++20 only.
* cp-tree.h (unparenthesized_id_or_class_member_access_p): Declare.
* pt.cc (unparenthesized_id_or_class_member_access_p): New function,
broken out of...
(do_auto_deduction): ...here. Use it. In C++23, maybe call
treat_lvalue_as_rvalue_p.
* tree.cc (xvalue_p): Check & clk_rvalueref, not == clk_rvalueref.
* typeck.cc (check_return_expr): Allow implicit move for functions
returning a reference as well, or when the return value type is not
a scalar type.
gcc/testsuite/ChangeLog:
* g++.dg/conversion/pr41426.C: Add dg-error for C++23.
* g++.dg/cpp0x/elision_weak.C: Likewise.
* g++.dg/cpp0x/move-return3.C: Only link in c++20_down.
* g++.dg/cpp1y/decltype-auto2.C: Add dg-error for C++23.
* g++.dg/cpp1y/lambda-generic-89419.C: Likewise.
* g++.dg/cpp23/feat-cxx2b.C: Test __cpp_implicit_move.
* g++.dg/gomp/pr56217.C: Only compile in c++20_down.
* g++.dg/warn/Wno-return-local-addr.C: Add dg-error for C++23.
* g++.dg/warn/Wreturn-local-addr.C: Adjust dg-error.
* g++.old-deja/g++.brendan/crash55.C: Add dg-error for C++23.
* g++.old-deja/g++.jason/temporary2.C: Likewise.
* g++.old-deja/g++.mike/p2846b.C: Adjust.
* g++.dg/cpp1y/decltype-auto6.C: New test.
* g++.dg/cpp23/decltype1.C: New test.
* g++.dg/cpp23/decltype2.C: New test.
* g++.dg/cpp23/elision1.C: New test.
* g++.dg/cpp23/elision2.C: New test.
* g++.dg/cpp23/elision3.C: New test.
* g++.dg/cpp23/elision4.C: New test.
* g++.dg/cpp23/elision5.C: New test.
* g++.dg/cpp23/elision6.C: New test.
* g++.dg/cpp23/elision7.C: New test.
|
|
In <https://gcc.gnu.org/pipermail/gcc-patches/2022-September/602057.html>
Jason noticed that we quote "nothrow" in diagnostics even though it's
not a keyword in C++. This patch removes the quotes and also drops
"nothrow" from c_keywords.
gcc/c-family/ChangeLog:
* c-format.cc (c_keywords): Drop nothrow.
gcc/cp/ChangeLog:
* constraint.cc (diagnose_trait_expr): Say "nothrow" without quotes
rather than in quotes.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-traits3.C: Adjust expected diagnostics.
|
|
The following patch attempts to implement C++23 P1169R4 - static operator()
paper's compiler side (there is some small library side too not implemented
yet). This allows static members as user operator() declarations and
static specifier on lambdas without lambda capture.
The synthetized conversion operator changes for static lambdas as it can just
return the operator() static method address, doesn't need to create a thunk
for it.
The change in call.cc (joust) is to avoid ICEs because we assumed that len
could be different only if both candidates are direct calls but it can be
one direct and one indirect call, and to implement the
[over.match.best.general]/1 and [over.best.ics.general] changes from
the paper (implemented always as Jason is sure it doesn't make a difference
in C++20 and earlier unless static member function operator() or
static lambda which we accept with pedwarn in earlier standards too appears
and my testing confirmed that).
2022-09-27 Jakub Jelinek <jakub@redhat.com>
PR c++/106651
gcc/c-family/
* c-cppbuiltin.cc (c_cpp_builtins): Predefine
__cpp_static_call_operator=202207L for C++23.
gcc/cp/
* cp-tree.h (LAMBDA_EXPR_STATIC_P): Implement C++23
P1169R4 - static operator(). Define.
* parser.cc (CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR): Document
that it also allows static.
(cp_parser_lambda_declarator_opt): Handle static lambda specifier.
(cp_parser_decl_specifier_seq): Allow RID_STATIC for
CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR.
* decl.cc (grok_op_properties): If operator() isn't a method,
use a different error wording, if it is static member function,
allow it (for C++20 and older with a pedwarn unless it is
a lambda function or template instantiation).
* call.cc (joust): Don't ICE if one candidate is static member
function and the other is an indirect call. If the parameter
conversion on the other candidate is user defined conversion,
ellipsis or bad conversion, make static member function candidate
a winner for that parameter.
* lambda.cc (maybe_add_lambda_conv_op): Handle static lambdas.
* error.cc (dump_lambda_function): Print static for static lambdas.
gcc/testsuite/
* g++.dg/template/error30.C: Adjust expected diagnostics.
* g++.dg/cpp1z/constexpr-lambda13.C: Likewise.
* g++.dg/cpp23/feat-cxx2b.C: Test __cpp_static_call_operator.
* g++.dg/cpp23/static-operator-call1.C: New test.
* g++.dg/cpp23/static-operator-call2.C: New test.
* g++.old-deja/g++.jason/operator.C: Adjust expected diagnostics.
|
|
The following patch implements OpenMP 5.1
#pragma omp assume
#pragma omp assumes
and
#pragma omp begin assumes
#pragma omp end assumes
directive support for C and C++. Currently it doesn't remember
anything from the assumption clauses for later, so is mainly
to support the directives and diagnose errors in their use.
If the recently posted C++23 [[assume (cond)]]; support makes it
in, the intent is that this can be easily adjusted at least for
the #pragma omp assume directive with holds clause(s) to use
the same infrastructure. Now, C++23 portable assumptions are slightly
different from OpenMP 5.1 assumptions' holds clause in that C++23
assumption holds just where it appears, while OpenMP 5.1 assumptions
hold everywhere in the scope of the directive. For assumes
directive which can appear at file or namespace scope it is the whole
TU and everything that functions from there call at runtime, for
begin assumes/end assumes pair all the functions in between those
directives and everything they call and for assume directive the
associated (currently structured) block. I have no idea how to
represents such holds to be usable for optimizers, except to
make
#pragma omp assume holds (cond)
block;
expand essentially to
[[assume (cond)]];
block;
or
[[assume (cond)]];
block;
[[assume (cond)]];
for now. Except for holds clause, the other assumptions are
OpenMP related, I'd say we should brainstorm where it would be
useful to optimize based on such information (I guess e.g. in target
regions it easily could) and only when we come up with something
like that think about how to propagate the assumptions to the optimizers.
2022-09-27 Jakub Jelinek <jakub@redhat.com>
gcc/c-family/
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_ASSUME,
PRAGMA_OMP_ASSUMES and PRAGMA_OMP_BEGIN. Rename
PRAGMA_OMP_END_DECLARE_TARGET to PRAGMA_OMP_END.
* c-pragma.cc (omp_pragmas): Add assumes and begin.
For end rename PRAGMA_OMP_END_DECLARE_TARGET to PRAGMA_OMP_END.
(omp_pragmas_simd): Add assume.
* c-common.h (c_omp_directives): Declare.
* c-omp.cc (omp_directives): Rename to ...
(c_omp_directives): ... this. No longer static. Uncomment
assume, assumes, begin assumes and end assumes entries.
In end declare target entry rename PRAGMA_OMP_END_DECLARE_TARGET
to PRAGMA_OMP_END.
(c_omp_categorize_directive): Adjust for omp_directives to
c_omp_directives renaming.
gcc/c/
* c-lang.h (current_omp_begin_assumes): Declare.
* c-parser.cc: Include bitmap.h.
(c_parser_omp_end_declare_target): Rename to ...
(c_parser_omp_end): ... this. Handle also end assumes.
(c_parser_omp_begin, c_parser_omp_assumption_clauses,
c_parser_omp_assumes, c_parser_omp_assume): New functions.
(c_parser_translation_unit): Also diagnose #pragma omp begin assumes
without corresponding #pragma omp end assumes.
(c_parser_pragma): Use %s in may only be used at file scope
diagnostics to decrease number of translatable messages. Handle
PRAGMA_OMP_BEGIN and PRAGMA_OMP_ASSUMES. Handle PRAGMA_OMP_END
rather than PRAGMA_OMP_END_DECLARE_TARGET and call c_parser_omp_end
for it rather than c_parser_omp_end_declare_target.
(c_parser_omp_construct): Handle PRAGMA_OMP_ASSUME.
* c-decl.cc (current_omp_begin_assumes): Define.
gcc/cp/
* cp-tree.h (struct omp_begin_assumes_data): New type.
(struct saved_scope): Add omp_begin_assumes member.
* parser.cc: Include bitmap.h.
(cp_parser_omp_assumption_clauses, cp_parser_omp_assume,
cp_parser_omp_assumes, cp_parser_omp_begin): New functions.
(cp_parser_omp_end_declare_target): Rename to ...
(cp_parser_omp_end): ... this. Handle also end assumes.
(cp_parser_omp_construct): Handle PRAGMA_OMP_ASSUME.
(cp_parser_pragma): Handle PRAGMA_OMP_ASSUME, PRAGMA_OMP_ASSUMES
and PRAGMA_OMP_BEGIN. Handle PRAGMA_OMP_END rather than
PRAGMA_OMP_END_DECLARE_TARGET and call cp_parser_omp_end
for it rather than cp_parser_omp_end_declare_target.
* pt.cc (apply_late_template_attributes): Also temporarily clear
omp_begin_assumes.
* semantics.cc (finish_translation_unit): Also diagnose
#pragma omp begin assumes without corresponding
#pragma omp end assumes.
gcc/testsuite/
* c-c++-common/gomp/assume-1.c: New test.
* c-c++-common/gomp/assume-2.c: New test.
* c-c++-common/gomp/assume-3.c: New test.
* c-c++-common/gomp/assumes-1.c: New test.
* c-c++-common/gomp/assumes-2.c: New test.
* c-c++-common/gomp/assumes-3.c: New test.
* c-c++-common/gomp/assumes-4.c: New test.
* c-c++-common/gomp/begin-assumes-1.c: New test.
* c-c++-common/gomp/begin-assumes-2.c: New test.
* c-c++-common/gomp/begin-assumes-3.c: New test.
* c-c++-common/gomp/begin-assumes-4.c: New test.
* c-c++-common/gomp/declare-target-6.c: New test.
* g++.dg/gomp/attrs-1.C (bar): Add n1 and n2 arguments, add
tests for assume directive.
* g++.dg/gomp/attrs-2.C (bar): Likewise.
* g++.dg/gomp/attrs-9.C: Add n1 and n2 variables, add tests for
begin assumes directive.
* g++.dg/gomp/attrs-15.C: New test.
* g++.dg/gomp/attrs-16.C: New test.
* g++.dg/gomp/attrs-17.C: New test.
|
|
compiler part except for bfloat16 [PR106652]
The following patch implements the compiler part of C++23
P1467R9 - Extended floating-point types and standard names compiler part
by introducing _Float{16,32,64,128} as keywords and builtin types
like they are implemented for C already since GCC 7, with DF{16,32,64,128}_
mangling.
It also introduces _Float{32,64,128}x for C++ with the
https://github.com/itanium-cxx-abi/cxx-abi/pull/147
proposed mangling of DF{32,64,128}x.
The patch doesn't add anything for bfloat16_t support, as right now
__bf16 type refuses all conversions and arithmetic operations.
The patch wants to keep backwards compatibility with how __float128 has
been handled in C++ before, both for mangling and behavior in binary
operations, overload resolution etc. So, there are some backend changes
where for C __float128 and _Float128 are the same type (float128_type_node
and float128t_type_node are the same pointer), but for C++ they are distinct
types which mangle differently and _Float128 is treated as extended
floating-point type while __float128 is treated as non-standard floating
point type. The various C++23 changes about how floating-point types
are changed are actually implemented as written in the spec only if at least
one of the types involved is _Float{16,32,64,128,32x,64x,128x} (_FloatNx are
also treated as extended floating-point types) and kept previous behavior
otherwise. For float/double/long double the rules are actually written that
they behave the same as before.
There is some backwards incompatibility at least on x86 regarding _Float16,
because that type was already used by that name and with the DF16_ mangling
(but only since GCC 12 and I think it isn't that widely used in the wild
yet). E.g. config/i386/avx512fp16intrin.h shows the issues, where
in C or in GCC 12 in C++ one could pass 0.0f to a builtin taking _Float16
argument, but with the changes that is not possible anymore, one needs
to either use 0.0f16 or (_Float16) 0.0f.
We have also a problem with glibc headers, where since glibc 2.27
math.h and complex.h aren't compilable with these changes. One gets
errors like:
In file included from /usr/include/math.h:43,
from abc.c:1:
/usr/include/bits/floatn.h:86:9: error: multiple types in one declaration
86 | typedef __float128 _Float128;
| ^~~~~~~~~~
/usr/include/bits/floatn.h:86:20: error: declaration does not declare anything [-fpermissive]
86 | typedef __float128 _Float128;
| ^~~~~~~~~
In file included from /usr/include/bits/floatn.h:119:
/usr/include/bits/floatn-common.h:214:9: error: multiple types in one declaration
214 | typedef float _Float32;
| ^~~~~
/usr/include/bits/floatn-common.h:214:15: error: declaration does not declare anything [-fpermissive]
214 | typedef float _Float32;
| ^~~~~~~~
/usr/include/bits/floatn-common.h:251:9: error: multiple types in one declaration
251 | typedef double _Float64;
| ^~~~~~
/usr/include/bits/floatn-common.h:251:16: error: declaration does not declare anything [-fpermissive]
251 | typedef double _Float64;
| ^~~~~~~~
This is from snippets like:
/* The remaining of this file provides support for older compilers. */
# if __HAVE_FLOAT128
/* The type _Float128 exists only since GCC 7.0. */
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef __float128 _Float128;
# endif
where it hardcodes that C++ doesn't have _Float{16,32,64,128,32x,64x,128x} support nor
{f,F}{16,32,64,128}{,x} literal suffixes nor _Complex _Float{16,32,64,128,32x,64x,128x}.
The patch fixincludes this for now and hopefully if this is committed, then
glibc can change those. The patch changes those
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
conditions to
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
Another thing is mangling, as said above, Itanium C++ ABI specifies
DF <number> _ as _Float{16,32,64,128} mangling, but GCC was implementing
a mangling incompatible with that starting with DF for fixed point types.
Fixed point was never supported in C++ though, I believe the reason why
the mangling has been added was that due to a bug it would leak into the
C++ FE through decltype (0.0r) etc. But that has been shortly after the
mangling was added fixed (I think in the same GCC release cycle), so we
now reject 0.0r etc. in C++. If we ever need the fixed point mangling,
I think it can be readded but better with a different prefix so that it
doesn't conflict with the published standard manglings. So, this patch
also kills the fixed point mangling and implements the DF <number> _
demangling.
The patch predefines __STDCPP_FLOAT{16,32,64,128}_T__ macros when
those types are available, but only for C++23, while the underlying types
are available in C++98 and later including the {f,F}{16,32,64,128} literal
suffixes (but those with a pedwarn for C++20 and earlier). My understanding
is that it needs to be predefined by the compiler, on the other side
predefining even for older modes when <stdfloat> is a new C++23 header
would be weird. One can find out if _Float{16,32,64,128,32x,64x,128x} is
supported in C++ by
__GNUC__ >= 13 && defined(__FLT{16,32,64,128,32X,64X,128X}_MANT_DIG__)
(but that doesn't work well with older G++ 13 snapshots).
As for std::bfloat16_t, three targets (aarch64, arm and x86) apparently
"support" __bf16 type which has the bfloat16 format, but isn't really
usable, e.g. {aarch64,arm,ix86}_invalid_conversion disallow any conversions
from or to type with BFmode, {aarch64,arm,ix86}_invalid_unary_op disallows
any unary operations on those except for ADDR_EXPR and
{aarch64,arm,ix86}_invalid_binary_op disallows any binary operation on
those. So, I think we satisfy:
"If the implementation supports an extended floating-point type with the
properties, as specified by ISO/IEC/IEEE 60559, of radix (b) of 2, storage
width in bits (k) of 16, precision in bits (p) of 8, maximum exponent (emax)
of 127, and exponent field width in bits (w) of 8, then the typedef-name
std::bfloat16_t is defined in the header <stdfloat> and names such a type,
the macro __STDCPP_BFLOAT16_T__ is defined, and the floating-point literal
suffixes bf16 and BF16 are supported."
because we don't really support those right now.
2022-09-27 Jakub Jelinek <jakub@redhat.com>
PR c++/106652
PR c++/85518
gcc/
* tree-core.h (enum tree_index): Add TI_FLOAT128T_TYPE
enumerator.
* tree.h (float128t_type_node): Define.
* tree.cc (build_common_tree_nodes): Initialize float128t_type_node.
* builtins.def (DEF_FLOATN_BUILTIN): Adjust comment now that
_Float<N> is supported in C++ too.
* config/i386/i386.cc (ix86_mangle_type): Only mangle as "g"
float128t_type_node.
* config/i386/i386-builtins.cc (ix86_init_builtin_types): Use
float128t_type_node for __float128 instead of float128_type_node
and create it if NULL.
* config/i386/avx512fp16intrin.h (_mm_setzero_ph, _mm256_setzero_ph,
_mm512_setzero_ph, _mm_set_sh, _mm_load_sh): Use 0.0f16 instead of
0.0f.
* config/ia64/ia64.cc (ia64_init_builtins): Use
float128t_type_node for __float128 instead of float128_type_node
and create it if NULL.
* config/rs6000/rs6000-c.cc (is_float128_p): Also return true
for float128t_type_node if non-NULL.
* config/rs6000/rs6000.cc (rs6000_mangle_type): Don't mangle
float128_type_node as "u9__ieee128".
* config/rs6000/rs6000-builtin.cc (rs6000_init_builtins): Use
float128t_type_node for __float128 instead of float128_type_node
and create it if NULL.
gcc/c-family/
* c-common.cc (c_common_reswords): Change _Float{16,32,64,128} and
_Float{32,64,128}x flags from D_CONLY to 0.
(shorten_binary_op): Punt if common_type returns error_mark_node.
(shorten_compare): Likewise.
(c_common_nodes_and_builtins): For C++ record _Float{16,32,64,128}
and _Float{32,64,128}x builtin types if available. For C++
clear float128t_type_node.
* c-cppbuiltin.cc (c_cpp_builtins): Predefine
__STDCPP_FLOAT{16,32,64,128}_T__ for C++23 if supported.
* c-lex.cc (interpret_float): For q/Q suffixes prefer
float128t_type_node over float128_type_node. Allow
{f,F}{16,32,64,128} suffixes for C++ if supported with pedwarn
for C++20 and older. Allow {f,F}{32,64,128}x suffixes for C++
with pedwarn. Don't call excess_precision_type for C++.
gcc/cp/
* cp-tree.h (cp_compare_floating_point_conversion_ranks): Implement
P1467R9 - Extended floating-point types and standard names except
for std::bfloat16_t for now. Declare.
(extended_float_type_p): New inline function.
* mangle.cc (write_builtin_type): Mangle float{16,32,64,128}_type_node
as DF{16,32,64,128}_. Mangle float{32,64,128}x_type_node as
DF{32,64,128}x. Remove FIXED_POINT_TYPE mangling that conflicts
with that.
* typeck2.cc (check_narrowing): If one of ftype or type is extended
floating-point type, compare floating-point conversion ranks.
* parser.cc (cp_keyword_starts_decl_specifier_p): Handle
CASE_RID_FLOATN_NX.
(cp_parser_simple_type_specifier): Likewise and diagnose missing
_Float<N> or _Float<N>x support if not supported by target.
* typeck.cc (cp_compare_floating_point_conversion_ranks): New function.
(cp_common_type): If both types are REAL_TYPE and one or both are
extended floating-point types, select common type based on comparison
of floating-point conversion ranks and subranks.
(cp_build_binary_op): Diagnose operation with floating point arguments
with unordered conversion ranks.
* call.cc (standard_conversion): For floating-point conversion, if
either from or to are extended floating-point types, set conv->bad_p
for implicit conversion from larger to smaller conversion rank or
with unordered conversion ranks.
(convert_like_internal): Emit a pedwarn on such conversions.
(build_conditional_expr): Diagnose operation with floating point
arguments with unordered conversion ranks.
(convert_arg_to_ellipsis): Don't promote extended floating-point types
narrower than double to double.
(compare_ics): Implement P1467R9 [over.ics.rank]/4 changes.
gcc/testsuite/
* g++.dg/cpp23/ext-floating1.C: New test.
* g++.dg/cpp23/ext-floating2.C: New test.
* g++.dg/cpp23/ext-floating3.C: New test.
* g++.dg/cpp23/ext-floating4.C: New test.
* g++.dg/cpp23/ext-floating5.C: New test.
* g++.dg/cpp23/ext-floating6.C: New test.
* g++.dg/cpp23/ext-floating7.C: New test.
* g++.dg/cpp23/ext-floating8.C: New test.
* g++.dg/cpp23/ext-floating9.C: New test.
* g++.dg/cpp23/ext-floating10.C: New test.
* g++.dg/cpp23/ext-floating.h: New file.
* g++.target/i386/float16-1.C: Adjust expected diagnostics.
libcpp/
* expr.cc (interpret_float_suffix): Allow {f,F}{16,32,64,128} and
{f,F}{32,64,128}x suffixes for C++.
include/
* demangle.h (enum demangle_component_type): Add
DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE.
(struct demangle_component): Add u.s_extended_builtin member.
libiberty/
* cp-demangle.c (d_dump): Handle
DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE. Don't handle
DEMANGLE_COMPONENT_FIXED_TYPE.
(d_make_extended_builtin_type): New function.
(cplus_demangle_builtin_types): Add _Float entry.
(cplus_demangle_type): For DF demangle it as _Float<N> or
_Float<N>x rather than fixed point which conflicts with it.
(d_count_templates_scopes): Handle
DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE. Just break; for
DEMANGLE_COMPONENT_FIXED_TYPE.
(d_find_pack): Handle DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE.
Don't handle DEMANGLE_COMPONENT_FIXED_TYPE.
(d_print_comp_inner): Likewise.
* cp-demangle.h (D_BUILTIN_TYPE_COUNT): Bump.
* testsuite/demangle-expected: Replace _Z3xxxDFyuVb test
with _Z3xxxDF16_DF32_DF64_DF128_CDF16_Vb. Add
_Z3xxxDF32xDF64xDF128xCDF32xVb test.
fixincludes/
* inclhack.def (glibc_cxx_floatn_1, glibc_cxx_floatn_2,
glibc_cxx_floatn_3): New fixes.
* tests/base/bits/floatn.h: New file.
* fixincl.x: Regenerated.
|
|
|
|
P0482R6, which added char8_t, didn't allow
const char arr[] = u8"howdy";
because it said "Declarations of arrays of char may currently be initialized
with UTF-8 string literals. Under this proposal, such initializations would
become ill-formed." This caused too many issues, so P2513R4 alleviates some
of those compatibility problems. In particular, "Arrays of char or unsigned
char may now be initialized with a UTF-8 string literal." This restriction
has been lifted for initialization only, not implicit conversions. Also,
my reading is that 'signed char' was excluded from the allowable conversions.
This is supposed to be treated as a DR in C++20.
PR c++/106656
gcc/c-family/ChangeLog:
* c-cppbuiltin.cc (c_cpp_builtins): Update value of __cpp_char8_t
for C++20.
gcc/cp/ChangeLog:
* typeck2.cc (array_string_literal_compatible_p): Allow
initializing arrays of char or unsigned char by a UTF-8 string literal.
gcc/testsuite/ChangeLog:
* g++.dg/cpp23/feat-cxx2b.C: Adjust.
* g++.dg/cpp2a/feat-cxx2a.C: Likewise.
* g++.dg/ext/char8_t-feature-test-macro-2.C: Likewise.
* g++.dg/ext/char8_t-init-2.C: Likewise.
* g++.dg/cpp2a/char8_t3.C: New test.
* g++.dg/cpp2a/char8_t4.C: New test.
|
|
|
|
To improve compile times, the C++ library could use compiler built-ins
rather than implementing std::is_convertible (and _nothrow) as class
templates. This patch adds the built-ins. We already have
__is_constructible and __is_assignable, and the nothrow forms of those.
Microsoft (and clang, for compatibility) also provide an alias called
__is_convertible_to. I did not add it, but it would be trivial to do
so.
I noticed that our __is_assignable doesn't implement the "Access checks
are performed as if from a context unrelated to either type" requirement,
therefore std::is_assignable / __is_assignable give two different results
here:
class S {
operator int();
friend void g(); // #1
};
void
g ()
{
// #1 doesn't matter
static_assert(std::is_assignable<int&, S>::value, "");
static_assert(__is_assignable(int&, S), "");
}
This is not a problem if __is_assignable is not meant to be used by
the users.
This patch doesn't make libstdc++ use the new built-ins, but I had to
rename a class otherwise its name would clash with the new built-in.
PR c++/106784
gcc/c-family/ChangeLog:
* c-common.cc (c_common_reswords): Add __is_convertible and
__is_nothrow_convertible.
* c-common.h (enum rid): Add RID_IS_CONVERTIBLE and
RID_IS_NOTHROW_CONVERTIBLE.
gcc/cp/ChangeLog:
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_CONVERTIBLE
and CPTK_IS_NOTHROW_CONVERTIBLE.
* cp-objcp-common.cc (names_builtin_p): Handle RID_IS_CONVERTIBLE
RID_IS_NOTHROW_CONVERTIBLE.
* cp-tree.h (enum cp_trait_kind): Add CPTK_IS_CONVERTIBLE and
CPTK_IS_NOTHROW_CONVERTIBLE.
(is_convertible): Declare.
(is_nothrow_convertible): Likewise.
* cxx-pretty-print.cc (pp_cxx_trait_expression): Handle
CPTK_IS_CONVERTIBLE and CPTK_IS_NOTHROW_CONVERTIBLE.
* method.cc (is_convertible): New.
(is_nothrow_convertible): Likewise.
* parser.cc (cp_parser_primary_expression): Handle RID_IS_CONVERTIBLE
and RID_IS_NOTHROW_CONVERTIBLE.
(cp_parser_trait_expr): Likewise.
* semantics.cc (trait_expr_value): Handle CPTK_IS_CONVERTIBLE and
CPTK_IS_NOTHROW_CONVERTIBLE.
(finish_trait_expr): Likewise.
libstdc++-v3/ChangeLog:
* include/std/type_traits: Rename __is_nothrow_convertible to
__is_nothrow_convertible_lib.
* testsuite/20_util/is_nothrow_convertible/value_ext.cc: Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/ext/has-builtin-1.C: Enhance to test __is_convertible and
__is_nothrow_convertible.
* g++.dg/ext/is_convertible1.C: New test.
* g++.dg/ext/is_convertible2.C: New test.
* g++.dg/ext/is_nothrow_convertible1.C: New test.
* g++.dg/ext/is_nothrow_convertible2.C: New test.
|
|
|
|
I added c_expr::m_decimal in r13-2386-gbedfca647a9e9c1a as part of the
implementation of -Wxor-used-as-pow, but I missed various places where
the field needed to be initialized.
Fixed thusly.
gcc/c-family/ChangeLog:
PR c/106830
* c-warn.cc (check_for_xor_used_as_pow): Don't try checking
values that don't fit in uhwi.
gcc/c/ChangeLog:
PR c/106830
* c-parser.cc (c_parser_initelt): Initialize m_decimal.
(c_parser_cast_expression): Likewise.
(c_parser_alignof_expression): Likewise.
(c_parser_postfix_expression_after_paren_type): Likewise.
(c_parser_postfix_expression_after_primary): Likewise.
(c_parser_expression): Likewise.
(c_parser_omp_variable_list): Likewise.
(c_parser_transaction_expression): Likewise.
* c-tree.h (c_expr::set_error): Likewise.
* c-typeck.cc (c_expr_sizeof_expr): Likewise.
(parser_build_unary_op): Likewise.
(parser_build_binary_op): Likewise.
(digest_init): Likewise.
(pop_init_level): Likewise.
* gimple-parser.cc (c_parser_gimple_call_internal): Likewise.
gcc/testsuite/ChangeLog:
PR c/106830
* gcc.dg/Wxor-used-as-pow-pr106830.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
|
|
All frontends replicate this, so move it.
gcc/
* tree.cc (build_common_tree_nodes): Initialize void_list_node
here.
gcc/ada/
* gcc-interface/trans.cc (gigi): Do not initialize void_list_node.
gcc/c-family/
* c-common.h (build_void_list_node): Remove.
* c-common.cc (c_common_nodes_and_builtins): Do not initialize
void_list_node.
gcc/c/
* c-decl.cc (build_void_list_node): Remove.
gcc/cp/
* decl.cc (cxx_init_decl_processing): Inline last
build_void_list_node call.
(build_void_list_node): Remove.
gcc/d/
* d-builtins.cc (d_build_c_type_nodes): Do not initialize
void_list_node.
gcc/fortran/
* f95-lang.cc (gfc_init_decl_processing): Do not initialize
void_list_node.
gcc/go/
* go-lang.cc (go_langhook_init): Do not initialize
void_list_node.
gcc/jit/
* dummy-frontend.cc (jit_langhook_init): Do not initialize
void_list_node.
gcc/lto/
* lto-lang.cc (lto_build_c_type_nodes): Do not initialize
void_list_node.
|
|
|
|
The mingw32 port is the only port to have TARGET_OVERRIDES_FORMAT_ATTRIBUTES
defined. When this macro is defined, it will never evaluate to NULL and produce
a warning: "error: the address of 'mingw_format_attribute_overrides' will never
be NULL [-Werror=address]"
Also, when TARGET_OVERRIDES_FORMAT_ATTRIBUTES is defined,
TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT must be defined as well. Add that
requirement to the docs.
2022-09-07 Jan-Benedict Glaw <jbglaw@lug-owl.de>
gcc/c-family/ChangeLog:
* c-format.cc (convert_format_name_to_system_name): Fix warning.
gcc/ChangeLog:
* doc/tm.texi.in (TARGET_OVERRIDES_FORMAT_ATTRIBUTES): Document requirement
of TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT being defined as well.
* doc/tm.texi: Regenerate.
|